dolibarr 23.0.3
sellsjournal.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
4 * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
5 * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
6 * Copyright (C) 2013 Christophe Battarel <christophe.battarel@altairis.fr>
7 * Copyright (C) 2013-2025 Alexandre Spangaro <alexandre@inovea-conseil.com>
8 * Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
9 * Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
10 * Copyright (C) 2014 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
11 * Copyright (C) 2018-2025 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
13 * Copyright (C) 2025 Vincent de Grandporé <vincent@de-grandpre.quebec>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 */
28
35// Load Dolibarr environment
36require '../../main.inc.php';
37require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
38require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
39require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
40require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
41require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
42require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
43require_once DOL_DOCUMENT_ROOT.'/societe/class/client.class.php';
44require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
45
55// Load translation files required by the page
56$langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "errors"));
57
58$id_journal = GETPOSTINT('id_journal');
59$action = GETPOST('action', 'aZ09');
60
61$date_startmonth = GETPOSTINT('date_startmonth');
62$date_startday = GETPOSTINT('date_startday');
63$date_startyear = GETPOSTINT('date_startyear');
64$date_endmonth = GETPOSTINT('date_endmonth');
65$date_endday = GETPOSTINT('date_endday');
66$date_endyear = GETPOSTINT('date_endyear');
67$in_bookkeeping = GETPOST('in_bookkeeping');
68if ($in_bookkeeping == '') {
69 $in_bookkeeping = 'notyet';
70}
71
72$now = dol_now();
73
74$hookmanager->initHooks(array('sellsjournal'));
75$parameters = array();
76
77// Security check
78if (!isModEnabled('accounting')) {
80}
81if ($user->socid > 0) {
83}
84if (!$user->hasRight('accounting', 'bind', 'write')) {
86}
87
88$error = 0;
89
90$tabfac = array();
91$tabht = array();
92$tabtva = array();
93$tabwarranty = array();
94$tabttc = array();
95$tablocaltax1 = array();
96$tablocaltax2 = array();
97
98$cptcli = 'NotDefined';
99
100/*
101 * Actions
102 */
103
104$reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
105
106$accountingaccount = new AccountingAccount($db);
107
108// Get information of a journal
109$accountingjournalstatic = new AccountingJournal($db);
110$accountingjournalstatic->fetch($id_journal);
111$journal = $accountingjournalstatic->code;
112$journal_label = $accountingjournalstatic->label;
113
114$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
115$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
116
117$pastmonth = null; // Initialise, could be unset
118$pastmonthyear = null; // Initialise, could be unset
119
120if (empty($date_startmonth)) {
121 // Period by default on transfer
123 $date_start = $dates['date_start'];
124 $pastmonthyear = $dates['pastmonthyear'];
125 $pastmonth = $dates['pastmonth'];
126}
127if (empty($date_endmonth)) {
128 // Period by default on transfer
130 $date_end = $dates['date_end'];
131 $pastmonthyear = $dates['pastmonthyear'];
132 $pastmonth = $dates['pastmonth'];
133}
134if (getDolGlobalString('ACCOUNTANCY_JOURNAL_USE_CURRENT_MONTH')) {
135 $pastmonth += 1;
136}
137
138if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
139 $date_start = dol_get_first_day((int) $pastmonthyear, (int) $pastmonth, false);
140 $date_end = dol_get_last_day((int) $pastmonthyear, (int) $pastmonth, false);
141}
142
143$sql = "SELECT f.rowid, f.ref, f.type, f.situation_cycle_ref, f.datef as df, f.ref_client, f.date_lim_reglement as dlr, f.close_code, f.retained_warranty, f.revenuestamp, f.situation_final,";
144$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.localtax1_tx, fd.localtax2_tx, fd.total_ttc, fd.situation_percent, fd.vat_src_code, fd.info_bits,";
145$sql .= " s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.fk_pays,";
146if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
147 $sql .= " spe.accountancy_code_customer_general,";
148 $sql .= " spe.accountancy_code_customer as code_compta_client,";
149 $sql .= " spe.accountancy_code_supplier_general,";
150 $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
151} else {
152 $sql .= " s.accountancy_code_customer_general,";
153 $sql .= " s.code_compta as code_compta_client,";
154 $sql .= " s.accountancy_code_supplier_general,";
155 $sql .= " s.code_compta_fournisseur,";
156}
157$sql .= " p.rowid as pid, p.ref as pref, aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte,";
158if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
159 $sql .= " ppe.accountancy_code_sell";
160} else {
161 $sql .= " p.accountancy_code_sell";
162}
163$parameters = array();
164$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
165$sql .= $hookmanager->resPrint;
166$sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
167$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = fd.fk_product";
168if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
169 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
170}
171$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd.fk_code_ventilation";
172$sql .= " JOIN ".MAIN_DB_PREFIX."facture as f ON f.rowid = fd.fk_facture";
173$sql .= " JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
174if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
175 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
176}
177$parameters = array();
178$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
179$sql .= $hookmanager->resPrint;
180$sql .= " WHERE fd.fk_code_ventilation > 0";
181$sql .= " AND f.entity IN (".getEntity('invoice', 0).')'; // We don't share object for accountancy, we use source object sharing
182$sql .= " AND f.fk_statut > 0";
183if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) { // Non common setup
184 $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_SITUATION.")";
185} else {
186 $sql .= " AND f.type IN (".Facture::TYPE_STANDARD.",".Facture::TYPE_REPLACEMENT.",".Facture::TYPE_CREDIT_NOTE.",".Facture::TYPE_DEPOSIT.",".Facture::TYPE_SITUATION.")";
187}
188$sql .= " AND fd.product_type IN (0,1)";
189if ($date_start && $date_end) {
190 $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
191}
192// Define begin binding date
193if (getDolGlobalInt('ACCOUNTING_DATE_START_BINDING')) {
194 $sql .= " AND f.datef >= '".$db->idate(getDolGlobalInt('ACCOUNTING_DATE_START_BINDING'))."'";
195}
196// Already in bookkeeping or not
197if ($in_bookkeeping == 'already') {
198 $sql .= " AND f.rowid IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";
199 // $sql .= " AND fd.rowid IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; // Useless, we save one line for all products with same account
200}
201if ($in_bookkeeping == 'notyet') {
202 $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')";
203 // $sql .= " AND fd.rowid NOT IN (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; // Useless, we save one line for all products with same account
204}
205$parameters = array();
206$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
207$sql .= $hookmanager->resPrint;
208$sql .= " ORDER BY f.datef, f.ref";
209//print $sql;
210
211dol_syslog('accountancy/journal/sellsjournal.php', LOG_DEBUG);
212$tabfac = array();
213$tabht = array();
214$tabtva = array();
215$def_tva = array();
216$tabwarranty = array();
217$tabrevenuestamp = array();
218$tabttc = array();
219$tablocaltax1 = array();
220$tablocaltax2 = array();
221$tabcompany = array();
222$vatdata_cache = array();
223
224// Variables
225$cptcli = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER', 'NotDefined');
226$cpttva = getDolGlobalString('ACCOUNTING_VAT_SOLD_ACCOUNT', 'NotDefined');
227$cptlocaltax1 = getDolGlobalString('ACCOUNTING_LT1_SOLD_ACCOUNT', 'NotDefined');
228$cptlocaltax2 = getDolGlobalString('ACCOUNTING_LT2_SOLD_ACCOUNT', 'NotDefined');
229
230$result = $db->query($sql);
231if ($result) {
232 $num = $db->num_rows($result);
233
234 $i = 0;
235 while ($i < $num) {
236 $obj = $db->fetch_object($result);
237
238 // Controls
239 $accountancy_code_customer_general = (!empty($obj->accountancy_code_customer_general) && $obj->accountancy_code_customer_general != '-1') ? $obj->accountancy_code_customer_general : $cptcli;
240 $compta_soc = (!empty($obj->code_compta_client)) ? $obj->code_compta_client : $cptcli;
241
242 $compta_prod = $obj->compte;
243 if (empty($compta_prod)) {
244 if ($obj->product_type == 0) {
245 $compta_prod = getDolGlobalString('ACCOUNTING_PRODUCT_SOLD_ACCOUNT', 'NotDefined');
246 } else {
247 $compta_prod = getDolGlobalString('ACCOUNTING_SERVICE_SOLD_ACCOUNT', 'NotDefined');
248 }
249 }
250
251 // $compta_revenuestamp = getDolGlobalString('ACCOUNTING_REVENUESTAMP_SOLD_ACCOUNT', 'NotDefined');
252
253 $tax_id = $obj->tva_tx . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '');
254 // SERVICE_ARE_ECOMMERCE_200238EC makes the chosen accountancy code depend on the buyer country,
255 // so the cache key must include the buyer country to avoid serving a previous buyer's result.
256 if (getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')) {
257 $vatdata_cache_key = $tax_id.'_'.(int) $obj->fk_pays;
258 } else {
259 $vatdata_cache_key = $tax_id;
260 }
261 if (array_key_exists($vatdata_cache_key, $vatdata_cache)) {
262 $vatdata = $vatdata_cache[$vatdata_cache_key];
263 } else {
264 if (getDolGlobalString('SERVICE_ARE_ECOMMERCE_200238EC')) {
265 $buyer = new Societe($db);
266 $buyer->fetch($obj->socid);
267 } else {
268 $buyer = null; // We don't need the buyer in this case
269 }
270 $seller = $mysoc;
271 $vatdata = getTaxesFromId($tax_id, $buyer, $seller, 0);
272 $vatdata_cache[$vatdata_cache_key] = $vatdata;
273 }
274 $compta_tva = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cpttva);
275 $compta_localtax1 = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cptlocaltax1);
276 $compta_localtax2 = (!empty($vatdata['accountancy_code_sell']) ? $vatdata['accountancy_code_sell'] : $cptlocaltax2);
277
278 // Define the array to store the detail of each vat rate and code for lines
279 if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
280 $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : '')] = (vatrate($obj->tva_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''));
281 if ($obj->localtax1_tx > 0.0) {
282 $def_tva[$obj->rowid][$compta_localtax1][vatrate($obj->localtax1_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : '').' LT1'] = (vatrate($obj->localtax1_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''));
283 }
284 if ($obj->localtax2_tx > 0.0) {
285 $def_tva[$obj->rowid][$compta_localtax2][vatrate($obj->localtax2_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : '').' LT2'] = (vatrate($obj->localtax2_tx).($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''));
286 }
287 }
288
289 // Create a compensation rate for situation invoice.
290 $situation_ratio = 1;
291 if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
292 if ($obj->situation_cycle_ref) {
293 // Avoid divide by 0
294 if ($obj->situation_percent == 0) {
295 $situation_ratio = 0;
296 } else {
297 $line = new FactureLigne($db);
298 $line->fetch($obj->fdid);
299
300 // Situation invoices handling
301 $prev_progress = $line->get_prev_progress($obj->rowid);
302
303 $situation_ratio = ($obj->situation_percent - $prev_progress) / $obj->situation_percent;
304 }
305 }
306 }
307
308 $revenuestamp = (float) price2num($obj->revenuestamp, 'MT');
309
310 // Invoice lines
311 $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df);
312 $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr);
313 $tabfac[$obj->rowid]["ref"] = $obj->ref;
314 $tabfac[$obj->rowid]["type"] = $obj->type;
315 $tabfac[$obj->rowid]["description"] = $obj->label_compte;
316 $tabfac[$obj->rowid]["close_code"] = $obj->close_code; // close_code = 'replaced' for replacement invoices (not used in most european countries)
317 $tabfac[$obj->rowid]["revenuestamp"] = $revenuestamp;
318 //$tabfac[$obj->rowid]["fk_facturedet"] = $obj->fdid;
319
320 // Avoid warnings
321 if (!isset($tabttc[$obj->rowid][$compta_soc])) {
322 $tabttc[$obj->rowid][$compta_soc] = 0;
323 }
324 if (!isset($tabht[$obj->rowid][$compta_prod])) {
325 $tabht[$obj->rowid][$compta_prod] = 0;
326 }
327 if (!isset($tabtva[$obj->rowid][$compta_tva])) {
328 $tabtva[$obj->rowid][$compta_tva] = 0;
329 }
330 if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
331 $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
332 }
333 if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
334 $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
335 }
336
337 // Compensation of data for invoice situation by using $situation_ratio. This works (nearly) for invoice that was not correctly recorded
338 // but it may introduces an error for situation invoices that were correctly saved. There is still rounding problem that differs between
339 // real data we should have stored and result obtained with a compensation.
340 // It also seems that credit notes on situation invoices are correctly saved (but it depends on the version used in fact).
341 // For credit notes, we hope to have situation_ratio = 1 so the compensation has no effect to avoid introducing troubles with credit notes.
342 if (getDolGlobalInt('INVOICE_USE_SITUATION') == 1) {
343 $total_ttc = $obj->total_ttc * $situation_ratio;
344 } else {
345 $total_ttc = $obj->total_ttc;
346 }
347
348 // Move a part of the retained warrenty into the account of warranty
349 if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && $obj->retained_warranty > 0 && (!getDolGlobalString('INVOICE_RETAINED_WARRANTY_LIMITED_TO_FINAL_SITUATION') || !empty($obj->situation_final))) {
350 $retained_warranty = (float) price2num($total_ttc * $obj->retained_warranty / 100, 'MT'); // Calculate the amount of warrenty for this line (using the percent value)
351 $tabwarranty[$obj->rowid][$compta_soc] += $retained_warranty;
352 $total_ttc -= $retained_warranty;
353 }
354
355 $tabttc[$obj->rowid][$compta_soc] += $total_ttc;
356 $tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio;
357 $tva_npr = ((($obj->info_bits & 1) == 1) ? 1 : 0);
358 if (!$tva_npr) { // We ignore line if VAT is a NPR
359 if (getDolGlobalInt('INVOICE_USE_SITUATION') == 2) {
360 $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
361 $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
362 $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
363 } else {
364 $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio;
365 $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1 * $situation_ratio;
366 $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2 * $situation_ratio;
367 }
368 }
369
370 $compta_revenuestamp = 'NotDefined';
371 if (!empty($revenuestamp)) {
372 $sqlrevenuestamp = "SELECT accountancy_code_sell FROM ".MAIN_DB_PREFIX."c_revenuestamp";
373 $sqlrevenuestamp .= " WHERE fk_pays = ".((int) $mysoc->country_id);
374 $sqlrevenuestamp .= " AND taux = ".((float) $revenuestamp);
375 $sqlrevenuestamp .= " AND active = 1";
376 $resqlrevenuestamp = $db->query($sqlrevenuestamp);
377
378 if ($resqlrevenuestamp) {
379 $num_rows_revenuestamp = $db->num_rows($resqlrevenuestamp);
380 if ($num_rows_revenuestamp > 1) {
381 dol_print_error($db, 'Failed 2 or more lines for the revenue stamp of your country. Check the dictionary of revenue stamp.');
382 } else {
383 $objrevenuestamp = $db->fetch_object($resqlrevenuestamp);
384 if ($objrevenuestamp) {
385 $compta_revenuestamp = $objrevenuestamp->accountancy_code_sell;
386 }
387 }
388 }
389 }
390
391 if (empty($tabrevenuestamp[$obj->rowid][$compta_revenuestamp]) && !empty($revenuestamp)) {
392 // The revenue stamp was never seen for this invoice id=$obj->rowid
393 $tabttc[$obj->rowid][$compta_soc] += $obj->revenuestamp;
394 $tabrevenuestamp[$obj->rowid][$compta_revenuestamp] = $obj->revenuestamp;
395 }
396
397 $tabcompany[$obj->rowid] = array(
398 'id' => $obj->socid,
399 'name' => $obj->name,
400 'code_client' => $obj->code_client,
401 'accountancy_code_customer_general' => $accountancy_code_customer_general,
402 'code_compta' => $compta_soc
403 );
404
405 // After the line is processed
406 $parameters = array(
407 'obj' => $obj,
408 'tabfac' => &$tabfac,
409 'tabht' => &$tabht,
410 'tabtva' => &$tabtva,
411 'def_tva' => &$def_tva,
412 'tabwarranty' => &$tabwarranty,
413 'tabrevenuestamp' => &$tabrevenuestamp,
414 'tabttc' => &$tabttc,
415 'tablocaltax1' => &$tablocaltax1,
416 'tablocaltax2' => &$tablocaltax2,
417 'tabcompany' => &$tabcompany,
418 'vatdata_cache' => &$vatdata_cache,
419 );
420 $reshook = $hookmanager->executeHooks('processingJournalData', $parameters); // Note that $action and $object may have been modified by hook
421
422 $i++;
423
424 // Check for too many lines.
425 if ($i > getDolGlobalInt('ACCOUNTANCY_MAX_TOO_MANY_LINES_TO_PROCESS', 10000)) {
426 $error++;
427 setEventMessages("ErrorTooManyLinesToProcessPleaseUseAMoreSelectiveFilter", null, 'errors');
428 break;
429 }
430 }
431
432 // After the loop on each line
433 $parameters = array(
434 'tabfac' => &$tabfac,
435 'tabht' => &$tabht,
436 'tabtva' => &$tabtva,
437 'def_tva' => &$def_tva,
438 'tabwarranty' => &$tabwarranty,
439 'tabrevenuestamp' => &$tabrevenuestamp,
440 'tabttc' => &$tabttc,
441 'tablocaltax1' => &$tablocaltax1,
442 'tablocaltax2' => &$tablocaltax2,
443 'tabcompany' => &$tabcompany,
444 'vatdata_cache' => &$vatdata_cache,
445 );
446 $reshook = $hookmanager->executeHooks('processedJournalData', $parameters); // Note that $action and $object may have been modified by hook
447} else {
448 dol_print_error($db);
449}
450
451
452$errorforinvoice = array();
453
454/*
455// Old way, 1 query for each invoice
456// Loop on all invoices to detect lines without binded code (fk_code_ventilation <= 0)
457foreach ($tabfac as $key => $val) { // Loop on each invoice
458 $sql = "SELECT COUNT(fd.rowid) as nb";
459 $sql .= " FROM ".MAIN_DB_PREFIX."facturedet as fd";
460 $sql .= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0";
461 $sql .= " AND fd.total_ttc <> 0 AND fk_facture = ".((int) $key);
462 $resql = $db->query($sql);
463 if ($resql) {
464 $obj = $db->fetch_object($resql);
465 if ($obj->nb > 0) {
466 $errorforinvoice[$key] = 'somelinesarenotbound';
467 }
468 } else {
469 dol_print_error($db);
470 }
471}
472*/
473// New way, single query, load all unbound lines
474if (!empty($tabfac)) {
475 $sql = "
476 SELECT
477 fk_facture,
478 COUNT(fd.rowid) as nb
479 FROM
480 ".MAIN_DB_PREFIX."facturedet as fd
481 WHERE
482 fd.product_type <= 2
483 AND fd.fk_code_ventilation <= 0
484 AND fd.total_ttc <> 0
485 AND fk_facture IN (".$db->sanitize(implode(",", array_keys($tabfac))).")
486 GROUP BY fk_facture
487 ";
488 $resql = $db->query($sql);
489 if ($resql) {
490 $num = $db->num_rows($resql);
491 $i = 0;
492 while ($i < $num) {
493 $obj = $db->fetch_object($resql);
494 if ($obj->nb > 0) {
495 $errorforinvoice[$obj->fk_facture] = 'somelinesarenotbound';
496 }
497 $i++;
498 }
499 }
500}
501//var_dump($errorforinvoice);exit;
502
503// Bookkeeping Write
504if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'bind', 'write')) {
505 $now = dol_now();
506 $error = 0;
507
508 $companystatic = new Societe($db);
509 $invoicestatic = new Facture($db);
510 $bookkeepingstatic = new BookKeeping($db);
511
512 $accountingaccountcustomer = new AccountingAccount($db);
513 $accountingaccountcustomer->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), true);
514
515 $accountingaccountcustomerwarranty = new AccountingAccount($db);
516 $accountingaccountcustomerwarranty->fetch(0, getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'), true);
517
518 foreach ($tabfac as $key => $val) { // Loop on each invoice
519 $errorforline = 0;
520
521 $totalcredit = 0;
522 $totaldebit = 0;
523
524 $db->begin(); // We accept transaction into loop, so if we hang, we can continue transfer from the last error
525
526 $companystatic->id = $tabcompany[$key]['id'];
527 $companystatic->name = $tabcompany[$key]['name'];
528 $companystatic->accountancy_code_customer_general = $tabcompany[$key]['accountancy_code_customer_general'];
529 $companystatic->code_compta = $tabcompany[$key]['code_compta'];
530 $companystatic->code_compta_client = $tabcompany[$key]['code_compta'];
531 $companystatic->code_client = $tabcompany[$key]['code_client'];
532 $companystatic->client = 3;
533
534 $invoicestatic->id = $key;
535 $invoicestatic->ref = (string) $val["ref"];
536 $invoicestatic->type = $val["type"];
537 $invoicestatic->close_code = $val["close_code"];
538
539 $date = dol_print_date($val["date"], 'day');
540
541 // Is it a replaced invoice? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
542 $replacedinvoice = 0;
543 if ($invoicestatic->close_code == Facture::CLOSECODE_REPLACED) {
544 $replacedinvoice = 1;
545 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
546 if ($alreadydispatched) {
547 $replacedinvoice = 2;
548 }
549 }
550
551 // If not already into bookkeeping, we won't add it. If yes, do nothing (should not happen because creating a replacement is not possible if invoice is accounted)
552 if ($replacedinvoice == 1) {
553 $db->rollback();
554 continue;
555 }
556
557 // Error if some lines are not binded/ready to be journalized
558 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
559 $error++;
560 $errorforline++;
561 setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
562 }
563
564 // Warranty
565 if (!$errorforline && getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY')) {
566 if (isset($tabwarranty[$key]) && is_array($tabwarranty[$key])) {
567 foreach ($tabwarranty[$key] as $k => $mt) {
568 $bookkeeping = new BookKeeping($db);
569 $bookkeeping->doc_date = $val["date"];
570 $bookkeeping->date_lim_reglement = $val["datereg"];
571 $bookkeeping->doc_ref = $val["ref"];
572 $bookkeeping->date_creation = $now;
573 $bookkeeping->doc_type = 'customer_invoice';
574 $bookkeeping->fk_doc = $key;
575 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are the source of this record to add
576 $bookkeeping->thirdparty_code = $companystatic->code_client;
577
578 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
579 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
580
581 $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY');
582 $bookkeeping->label_compte = $accountingaccountcustomerwarranty->label;
583
584 $bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("RetainedWarranty"));
585 $bookkeeping->montant = $mt;
586 $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
587 $bookkeeping->debit = ($mt >= 0) ? $mt : 0;
588 $bookkeeping->credit = ($mt < 0) ? -$mt : 0;
589 $bookkeeping->code_journal = $journal;
590 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
591 $bookkeeping->fk_user_author = $user->id;
592 $bookkeeping->entity = $conf->entity;
593
594 $totaldebit += $bookkeeping->debit;
595 $totalcredit += $bookkeeping->credit;
596
597 $result = $bookkeeping->create($user);
598 if ($result < 0) {
599 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
600 $error++;
601 $errorforline++;
602 $errorforinvoice[$key] = 'alreadyjournalized';
603 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
604 } else {
605 $error++;
606 $errorforline++;
607 $errorforinvoice[$key] = 'other';
608 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
609 }
610 }
611 }
612 }
613 }
614
615 // Thirdparty
616 if (!$errorforline) {
617 foreach ($tabttc[$key] as $k => $mt) {
618 $bookkeeping = new BookKeeping($db);
619 $bookkeeping->doc_date = $val["date"];
620 $bookkeeping->date_lim_reglement = $val["datereg"];
621 $bookkeeping->doc_ref = $val["ref"];
622 $bookkeeping->date_creation = $now;
623 $bookkeeping->doc_type = 'customer_invoice';
624 $bookkeeping->fk_doc = $key;
625 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
626 $bookkeeping->thirdparty_code = $companystatic->code_client;
627
628 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
629 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
630
631 $bookkeeping->numero_compte = (!empty($tabcompany[$key]['accountancy_code_customer_general']) && $tabcompany[$key]['accountancy_code_customer_general'] != '-1') ? $tabcompany[$key]['accountancy_code_customer_general'] : $cptcli;
632 $bookkeeping->label_compte = $accountingaccountcustomer->label;
633
634 $bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("SubledgerAccount"));
635 $bookkeeping->montant = $mt;
636 $bookkeeping->sens = ($mt >= 0) ? 'D' : 'C';
637 $bookkeeping->debit = ($mt >= 0) ? $mt : 0;
638 $bookkeeping->credit = ($mt < 0) ? -$mt : 0;
639 $bookkeeping->code_journal = $journal;
640 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
641 $bookkeeping->fk_user_author = $user->id;
642 $bookkeeping->entity = $conf->entity;
643
644 $totaldebit += $bookkeeping->debit;
645 $totalcredit += $bookkeeping->credit;
646
647 $result = $bookkeeping->create($user);
648 if ($result < 0) {
649 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
650 $error++;
651 $errorforline++;
652 $errorforinvoice[$key] = 'alreadyjournalized';
653 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
654 } else {
655 $error++;
656 $errorforline++;
657 $errorforinvoice[$key] = 'other';
658 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
659 }
660 } else {
661 if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
662 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
663 $lettering_static = new Lettering($db);
664
665 $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
666 }
667 }
668 }
669 }
670
671 // Product / Service
672 if (!$errorforline) {
673 foreach ($tabht[$key] as $k => $mt) {
674 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
675 $accountingaccount = new AccountingAccount($db);
676 $accountingaccount->fetch(0, $k, true);
677 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
678 } else {
679 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
680 }
681
682 $label_account = $accountingaccount->label;
683
684 // get compte id and label
685 if ($accountingaccount->id > 0) {
686 $bookkeeping = new BookKeeping($db);
687 $bookkeeping->doc_date = $val["date"];
688 $bookkeeping->date_lim_reglement = $val["datereg"];
689 $bookkeeping->doc_ref = $val["ref"];
690 $bookkeeping->date_creation = $now;
691 $bookkeeping->doc_type = 'customer_invoice';
692 $bookkeeping->fk_doc = $key;
693 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
694 $bookkeeping->thirdparty_code = $companystatic->code_client;
695
696 if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) {
697 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
698 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
699 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
700 } else {
701 $bookkeeping->subledger_account = '';
702 $bookkeeping->subledger_label = '';
703 }
704 } else {
705 $bookkeeping->subledger_account = '';
706 $bookkeeping->subledger_label = '';
707 }
708
709 $bookkeeping->numero_compte = $k;
710 $bookkeeping->label_compte = $label_account;
711
712 $bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $label_account);
713 $bookkeeping->montant = $mt;
714 $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
715 $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
716 $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
717 $bookkeeping->code_journal = $journal;
718 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
719 $bookkeeping->fk_user_author = $user->id;
720 $bookkeeping->entity = $conf->entity;
721
722 $totaldebit += $bookkeeping->debit;
723 $totalcredit += $bookkeeping->credit;
724
725 $result = $bookkeeping->create($user);
726 if ($result < 0) {
727 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
728 $error++;
729 $errorforline++;
730 $errorforinvoice[$key] = 'alreadyjournalized';
731 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
732 } else {
733 $error++;
734 $errorforline++;
735 $errorforinvoice[$key] = 'other';
736 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
737 }
738 }
739 }
740 }
741 }
742
743 // VAT
744 if (!$errorforline) {
745 $listoftax = array(0, 1, 2);
746 foreach ($listoftax as $numtax) {
747 $arrayofvat = $tabtva;
748 if ($numtax == 1) {
749 $arrayofvat = $tablocaltax1;
750 }
751 if ($numtax == 2) {
752 $arrayofvat = $tablocaltax2;
753 }
754
755 foreach ($arrayofvat[$key] as $k => $mt) {
756 if ($mt) {
757 if (empty($conf->cache['accountingaccountincurrententity_vat'][$k])) {
758 $accountingaccount = new AccountingAccount($db);
759 $accountingaccount->fetch(0, $k, true);
760 $conf->cache['accountingaccountincurrententity_vat'][$k] = $accountingaccount;
761 } else {
762 $accountingaccount = $conf->cache['accountingaccountincurrententity_vat'][$k];
763 }
764
765 $label_account = $accountingaccount->label;
766
767 $bookkeeping = new BookKeeping($db);
768 $bookkeeping->doc_date = $val["date"];
769 $bookkeeping->date_lim_reglement = $val["datereg"];
770 $bookkeeping->doc_ref = $val["ref"];
771 $bookkeeping->date_creation = $now;
772 $bookkeeping->doc_type = 'customer_invoice';
773 $bookkeeping->fk_doc = $key;
774 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
775 $bookkeeping->thirdparty_code = $companystatic->code_client;
776
777 $bookkeeping->subledger_account = '';
778 $bookkeeping->subledger_label = '';
779
780 $bookkeeping->numero_compte = $k;
781 $bookkeeping->label_compte = $label_account;
782
783
784 $tmpvatrate = (empty($def_tva[$key][$k]) ? (empty($arrayofvat[$key][$k]) ? '' : $arrayofvat[$key][$k]) : implode(', ', $def_tva[$key][$k]));
785 $labelvataccount = $langs->trans("Taxes").' '.$tmpvatrate.' %';
786 $labelvataccount .= ($numtax ? ' - Localtax '.$numtax : '');
787 $bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $labelvataccount);
788
789 $bookkeeping->montant = $mt;
790 $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
791 $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
792 $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
793 $bookkeeping->code_journal = $journal;
794 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
795 $bookkeeping->fk_user_author = $user->id;
796 $bookkeeping->entity = $conf->entity;
797
798 $totaldebit += $bookkeeping->debit;
799 $totalcredit += $bookkeeping->credit;
800
801 $result = $bookkeeping->create($user);
802 if ($result < 0) {
803 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
804 $error++;
805 $errorforline++;
806 $errorforinvoice[$key] = 'alreadyjournalized';
807 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
808 } else {
809 $error++;
810 $errorforline++;
811 $errorforinvoice[$key] = 'other';
812 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
813 }
814 }
815 }
816 }
817 }
818 }
819
820 // Revenue stamp
821 if (!$errorforline) {
822 if (isset($tabrevenuestamp[$key]) && is_array($tabrevenuestamp[$key])) {
823 foreach ($tabrevenuestamp[$key] as $k => $mt) {
824 if ($mt) {
825 if (empty($conf->cache['accountingaccountincurrententity_rs'][$k])) {
826 $accountingaccount = new AccountingAccount($db);
827 $accountingaccount->fetch(0, $k, true);
828 $conf->cache['accountingaccountincurrententity_rs'][$k] = $accountingaccount;
829 } else {
830 $accountingaccount = $conf->cache['accountingaccountincurrententity_rs'][$k];
831 }
832
833 $label_account = $accountingaccount->label;
834
835 $bookkeeping = new BookKeeping($db);
836 $bookkeeping->doc_date = $val["date"];
837 $bookkeeping->date_lim_reglement = $val["datereg"];
838 $bookkeeping->doc_ref = $val["ref"];
839 $bookkeeping->date_creation = $now;
840 $bookkeeping->doc_type = 'customer_invoice';
841 $bookkeeping->fk_doc = $key;
842 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
843 $bookkeeping->thirdparty_code = $companystatic->code_client;
844
845 $bookkeeping->subledger_account = '';
846 $bookkeeping->subledger_label = '';
847
848 $bookkeeping->numero_compte = $k;
849 $bookkeeping->label_compte = $label_account;
850
851 $bookkeeping->label_operation = $bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("RevenueStamp"));
852 $bookkeeping->montant = $mt;
853 $bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
854 $bookkeeping->debit = ($mt < 0) ? -$mt : 0;
855 $bookkeeping->credit = ($mt >= 0) ? $mt : 0;
856 $bookkeeping->code_journal = $journal;
857 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
858 $bookkeeping->fk_user_author = $user->id;
859 $bookkeeping->entity = $conf->entity;
860
861 $totaldebit += $bookkeeping->debit;
862 $totalcredit += $bookkeeping->credit;
863
864 $result = $bookkeeping->create($user);
865 if ($result < 0) {
866 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
867 $error++;
868 $errorforline++;
869 $errorforinvoice[$key] = 'alreadyjournalized';
870 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
871 } else {
872 $error++;
873 $errorforline++;
874 $errorforinvoice[$key] = 'other';
875 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
876 }
877 }
878 }
879 }
880 }
881 }
882
883 // Protection against a bug on lines before
884 if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
885 $error++;
886 $errorforline++;
887 $errorforinvoice[$key] = 'amountsnotbalanced';
888 setEventMessages('We Tried to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors');
889 }
890
891 if (!$errorforline) {
892 $db->commit();
893 } else {
894 $db->rollback();
895
896 if ($error >= 10) {
897 setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
898 break; // Break in the foreach
899 }
900 }
901 }
902
903 $tabpay = $tabfac;
904
905 if (empty($error) && count($tabpay) > 0) {
906 setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
907 } elseif (count($tabpay) == $error) {
908 setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
909 } else {
910 setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
911 }
912
913 $action = '';
914
915 // Must reload data, so we make a redirect
916 if (count($tabpay) != $error) {
917 $param = 'id_journal='.$id_journal;
918 $param .= '&date_startday='.$date_startday;
919 $param .= '&date_startmonth='.$date_startmonth;
920 $param .= '&date_startyear='.$date_startyear;
921 $param .= '&date_endday='.$date_endday;
922 $param .= '&date_endmonth='.$date_endmonth;
923 $param .= '&date_endyear='.$date_endyear;
924 $param .= '&in_bookkeeping='.$in_bookkeeping;
925 header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
926 exit;
927 }
928}
929
930
931
932/*
933 * View
934 */
935
936$form = new Form($db);
937
938// Export
939if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
940 // Note that to have the button to get this feature enabled, you must enable ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL
941 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
942
943 $filename = 'journal';
944 $type_export = 'journal';
945 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
946
947 $companystatic = new Client($db);
948 $invoicestatic = new Facture($db);
949 $bookkeepingstatic = new BookKeeping($db);
950
951 foreach ($tabfac as $key => $val) {
952 $companystatic->id = $tabcompany[$key]['id'];
953 $companystatic->name = $tabcompany[$key]['name'];
954 $companystatic->accountancy_code_customer_general = (!empty($tabcompany[$key]['accountancy_code_customer_general']) && $tabcompany[$key]['accountancy_code_customer_general'] != '-1') ? $tabcompany[$key]['accountancy_code_customer_general'] : $cptcli;
955 $companystatic->code_compta = $tabcompany[$key]['code_compta']; // deprecated
956 $companystatic->code_compta_client = $tabcompany[$key]['code_compta'];
957 $companystatic->code_client = $tabcompany[$key]['code_client'];
958 $companystatic->client = 3;
959
960 $invoicestatic->id = $key;
961 $invoicestatic->ref = (string) $val["ref"];
962 $invoicestatic->type = $val["type"];
963 $invoicestatic->close_code = $val["close_code"];
964
965 $date = dol_print_date($val["date"], 'day');
966
967 // Is it a replaced invoice? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
968 $replacedinvoice = 0;
969 if ($invoicestatic->close_code == Facture::CLOSECODE_REPLACED) {
970 $replacedinvoice = 1;
971 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
972 if ($alreadydispatched) {
973 $replacedinvoice = 2;
974 }
975 }
976
977 // If not already into bookkeeping, we won't add it. If yes, do nothing (should not happen because creating replacement not possible if invoice is accounted)
978 if ($replacedinvoice == 1) {
979 continue;
980 }
981
982 // Warranty
983 if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && isset($tabwarranty[$key])) {
984 foreach ($tabwarranty[$key] as $k => $mt) {
985 //if ($mt) {
986 print '"'.$key.'"'.$sep;
987 print '"'.$date.'"'.$sep;
988 print '"'.$val["ref"].'"'.$sep;
989 print '"'.csvClean(dol_trunc($companystatic->name, 32)).'"'.$sep;
990 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
991 print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY')).'"'.$sep;
992 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
993 print '"'.$langs->trans("ThirdParty").'"'.$sep;
994 print '"'.csvClean($bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("RetainedWarranty"))).'"'.$sep;
995 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
996 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
997 print '"'.$journal.'"';
998 print "\n";
999 //}
1000 }
1001 }
1002
1003 // Third party
1004 foreach ($tabttc[$key] as $k => $mt) {
1005 //if ($mt) {
1006 print '"'.$key.'"'.$sep;
1007 print '"'.$date.'"'.$sep;
1008 print '"'.$val["ref"].'"'.$sep;
1009 print '"'.csvClean(dol_trunc($companystatic->name, 32)).'"'.$sep;
1010 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
1011 print '"'.length_accountg($companystatic->accountancy_code_customer_general).'"'.$sep;
1012 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
1013 print '"'.$langs->trans("ThirdParty").'"'.$sep;
1014 print '"'.csvClean($bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("ThirdParty"))).'"'.$sep;
1015 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1016 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1017 print '"'.$journal.'"';
1018 print "\n";
1019 //}
1020 }
1021
1022 // Product / Service
1023 foreach ($tabht[$key] as $k => $mt) {
1024 $accountingaccount = new AccountingAccount($db);
1025 $accountingaccount->fetch(0, $k, true);
1026 //if ($mt) {
1027 print '"'.$key.'"'.$sep;
1028 print '"'.$date.'"'.$sep;
1029 print '"'.$val["ref"].'"'.$sep;
1030 print '"'.csvClean(dol_trunc($companystatic->name, 32)).'"'.$sep;
1031 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1032 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1033 print '""'.$sep;
1034 print '"'.csvClean(dol_trunc($accountingaccount->label, 32)).'"'.$sep;
1035 print '"'.csvClean($bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $accountingaccount->label)).'"'.$sep;
1036 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1037 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1038 print '"'.$journal.'"';
1039 print "\n";
1040 //}
1041 }
1042
1043 // VAT
1044 $listoftax = array(0, 1, 2);
1045 foreach ($listoftax as $numtax) {
1046 $arrayofvat = $tabtva;
1047 if ($numtax == 1) {
1048 $arrayofvat = $tablocaltax1;
1049 }
1050 if ($numtax == 2) {
1051 $arrayofvat = $tablocaltax2;
1052 }
1053
1054 foreach ($arrayofvat[$key] as $k => $mt) {
1055 if ($mt) {
1056 print '"'.$key.'"'.$sep;
1057 print '"'.$date.'"'.$sep;
1058 print '"'.$val["ref"].'"'.$sep;
1059 print '"'.csvClean(dol_trunc($companystatic->name, 32)).'"'.$sep;
1060 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1061 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1062 print '""'.$sep;
1063 print '"'.$langs->trans("VAT").' - '.implode(', ', $def_tva[$key][$k]).' %"'.$sep;
1064 print '"'.csvClean($bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("VAT").implode($def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : ''))).'"'.$sep;
1065 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1066 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1067 print '"'.$journal.'"';
1068 print "\n";
1069 }
1070 }
1071 }
1072
1073 // Revenue stamp
1074 if (isset($tabrevenuestamp[$key])) {
1075 foreach ($tabrevenuestamp[$key] as $k => $mt) {
1076 //if ($mt) {
1077 print '"'.$key.'"'.$sep;
1078 print '"'.$date.'"'.$sep;
1079 print '"'.$val["ref"].'"'.$sep;
1080 print '"'.csvClean(dol_trunc($companystatic->name, 32)).'"'.$sep;
1081 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1082 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
1083 print '""'.$sep;
1084 print '"'.$langs->trans("RevenueStamp").'"'.$sep;
1085 print '"'.csvClean($bookkeepingstatic->accountingLabelForOperation($companystatic->name, $invoicestatic->ref, $langs->trans("RevenueStamp"))).'"'.$sep;
1086 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
1087 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
1088 print '"'.$journal.'"';
1089 print "\n";
1090 //}
1091 }
1092 }
1093 }
1094}
1095
1096
1097
1098if (empty($action) || $action == 'view') {
1099 $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
1100 $help_url = 'EN:Module_Double_Entry_Accounting|FR:Module_Comptabilit&eacute;_en_Partie_Double#G&eacute;n&eacute;ration_des_&eacute;critures_en_comptabilit&eacute;';
1101 llxHeader('', dol_string_nohtmltag($title), $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-generation page-sellsjournal');
1102
1103 $nom = $title;
1104 $nomlink = '';
1105 $periodlink = '';
1106 $exportlink = '';
1107 $builddate = dol_now();
1108 $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
1109 if (getDolGlobalString('FACTURE_DEPOSITS_ARE_JUST_PAYMENTS')) {
1110 $description .= $langs->trans("DepositsAreNotIncluded");
1111 } else {
1112 $description .= $langs->trans("DepositsAreIncluded");
1113 }
1114
1115 $listofchoices = array('notyet' => $langs->trans("NotYetInGeneralLedger"), 'already' => $langs->trans("AlreadyInGeneralLedger"));
1116 $period = $form->selectDate($date_start ? $date_start : -1, 'date_start', 0, 0, 0, '', 1, 0).' - '.$form->selectDate($date_end ? $date_end : -1, 'date_end', 0, 0, 0, '', 1, 0);
1117 $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
1118
1119 $varlink = 'id_journal='.$id_journal;
1120
1121 journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
1122
1123 if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
1124 // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
1125 // Fiscal period test
1126 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
1127 $resql = $db->query($sql);
1128 if ($resql) {
1129 $obj = $db->fetch_object($resql);
1130 if ($obj->nb == 0) {
1131 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
1132 $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
1133 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
1134 print $desc;
1135 print '</div>';
1136 }
1137 } else {
1138 dol_print_error($db);
1139 }
1140 }
1141
1142 // Button to write into Ledger
1143 $acctCustomerNotConfigured = in_array(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER'), ['','-1']);
1144 if ($acctCustomerNotConfigured) {
1145 print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
1146 $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
1147 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
1148 print $desc;
1149 print '</div>';
1150 }
1151 print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
1152 if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
1153 print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
1154 }
1155 if ($acctCustomerNotConfigured) {
1156 print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
1157 } else {
1158 if ($in_bookkeeping == 'notyet') {
1159 print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
1160 } else {
1161 print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
1162 }
1163 }
1164 print '</div>';
1165
1166 // TODO Avoid using js. We can use a direct link with $param
1167 print '
1168 <script type="text/javascript">
1169 function launch_export() {
1170 $("div.fiche form input[name=\"action\"]").val("exportcsv");
1171 $("div.fiche form input[type=\"submit\"]").click();
1172 $("div.fiche form input[name=\"action\"]").val("");
1173 }
1174 function writebookkeeping() {
1175 console.log("click on writebookkeeping");
1176 $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
1177 $("div.fiche form input[type=\"submit\"]").click();
1178 $("div.fiche form input[name=\"action\"]").val("");
1179 }
1180 </script>';
1181
1182 /*
1183 * Show result array
1184 */
1185 print '<br>';
1186
1187 print '<div class="div-table-responsive">';
1188 print "<table class=\"noborder\" width=\"100%\">";
1189 print "<tr class=\"liste_titre\">";
1190 print "<td>".$langs->trans("Date")."</td>";
1191 print "<td>".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")</td>";
1192 print "<td>".$langs->trans("AccountAccounting")."</td>";
1193 print "<td>".$langs->trans("SubledgerAccount")."</td>";
1194 print "<td>".$langs->trans("LabelOperation")."</td>";
1195 print '<td class="center">'.$langs->trans("AccountingDebit")."</td>";
1196 print '<td class="center">'.$langs->trans("AccountingCredit")."</td>";
1197 print "</tr>\n";
1198
1199 $i = 0;
1200
1201 $companystatic = new Client($db);
1202 $invoicestatic = new Facture($db);
1203 $bookkeepingstatic = new BookKeeping($db);
1204
1205 foreach ($tabfac as $key => $val) {
1206 $companystatic->id = $tabcompany[$key]['id'];
1207 $companystatic->name = $tabcompany[$key]['name'];
1208 $companystatic->accountancy_code_customer_general = (!empty($tabcompany[$key]['accountancy_code_customer_general']) && $tabcompany[$key]['accountancy_code_customer_general'] != '-1') ? $tabcompany[$key]['accountancy_code_customer_general'] : $cptcli;
1209 $companystatic->code_compta = $tabcompany[$key]['code_compta'];
1210 $companystatic->code_compta_client = $tabcompany[$key]['code_compta'];
1211 $companystatic->code_client = $tabcompany[$key]['code_client'];
1212 $companystatic->client = 3;
1213
1214 $invoicestatic->id = $key;
1215 $invoicestatic->ref = (string) $val["ref"];
1216 $invoicestatic->type = $val["type"];
1217 $invoicestatic->close_code = $val["close_code"];
1218
1219 $date = dol_print_date($val["date"], 'day');
1220
1221 // Is it a replaced invoice? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
1222 $replacedinvoice = 0;
1223 if ($invoicestatic->close_code == Facture::CLOSECODE_REPLACED) {
1224 $replacedinvoice = 1;
1225 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
1226 if ($alreadydispatched) {
1227 $replacedinvoice = 2;
1228 }
1229 }
1230
1231 // If not already into bookkeeping, we won't add it, if yes, add the counterpart ???.
1232 if ($replacedinvoice == 1) {
1233 print '<tr class="oddeven">';
1234 print "<!-- Replaced invoice -->";
1235 print "<td>".$date."</td>";
1236 print "<td><strike>".$invoicestatic->getNomUrl(1)."</strike></td>";
1237 // Account
1238 print "<td>";
1239 print $langs->trans("Replaced");
1240 print '</td>';
1241 // Subledger account
1242 print "<td>";
1243 print '</td>';
1244 print "<td>";
1245 print "</td>";
1246 print '<td class="right"></td>';
1247 print '<td class="right"></td>';
1248 print "</tr>";
1249
1250 $i++;
1251 continue;
1252 }
1253 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
1254 print '<tr class="oddeven">';
1255 print "<!-- Some lines are not bound -->";
1256 print "<td>".$date."</td>";
1257 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1258 // Account
1259 print "<td>";
1260 print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
1261 print '</td>';
1262 // Subledger account
1263 print "<td>";
1264 print '</td>';
1265 print "<td>";
1266 print "</td>";
1267 print '<td class="right"></td>';
1268 print '<td class="right"></td>';
1269 print "</tr>";
1270
1271 $i++;
1272 }
1273
1274 // Warranty
1275 if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && isset($tabwarranty[$key]) && is_array($tabwarranty[$key])) {
1276 foreach ($tabwarranty[$key] as $k => $mt) {
1277 print '<tr class="oddeven">';
1278 print "<!-- Thirdparty warranty -->";
1279 print "<td>" . $date . "</td>";
1280 print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
1281 // Account
1282 print "<td>";
1283 $accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'));
1284 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1285 print '<span class="error">' . $langs->trans("MainAccountForRetainedWarrantyNotDefined") . '</span>';
1286 } else {
1287 print $accountoshow;
1288 }
1289 print '</td>';
1290 // Subledger account
1291 print "<td>";
1292 $accountoshow = length_accounta($k);
1293 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1294 print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
1295 } else {
1296 print $accountoshow;
1297 }
1298 print '</td>';
1299 print "<td>" . $bookkeepingstatic->accountingLabelForOperation($companystatic->getNomUrl(0), $invoicestatic->ref, $langs->trans("RetainedWarranty"), 1) . "</td>";
1300 print '<td class="right nowraponall amount">' . ($mt >= 0 ? price($mt) : '') . "</td>";
1301 print '<td class="right nowraponall amount">' . ($mt < 0 ? price(-$mt) : '') . "</td>";
1302 print "</tr>";
1303 }
1304 }
1305
1306 // Third party
1307 foreach ($tabttc[$key] as $k => $mt) {
1308 print '<tr class="oddeven">';
1309 print "<!-- Thirdparty -->";
1310 print "<td>".$date."</td>";
1311 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1312 // Account
1313 print "<td>";
1314 $accountoshow = length_accountg($companystatic->accountancy_code_customer_general);
1315 if (($accountoshow == "") || $accountoshow == "-1" || $accountoshow == 'NotDefined') {
1316 print '<span class="error">'.$langs->trans("MainAccountForCustomersNotDefined").'</span>';
1317 } else {
1318 print $accountoshow;
1319 }
1320 print '</td>';
1321 // Subledger account
1322 print "<td>";
1323 $accountoshow = length_accounta($k);
1324 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1325 print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
1326 } else {
1327 print $accountoshow;
1328 }
1329 print '</td>';
1330 print "<td>" . $bookkeepingstatic->accountingLabelForOperation($companystatic->getNomUrl(0, 'customer'), $invoicestatic->ref, $langs->trans("SubledgerAccount"), 1) . "</td>";
1331 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1332 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1333 print "</tr>";
1334
1335 $i++;
1336 }
1337
1338 // Product / Service
1339 foreach ($tabht[$key] as $k => $mt) {
1340 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
1341 $accountingaccount = new AccountingAccount($db);
1342 $accountingaccount->fetch(0, $k, true);
1343 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
1344 } else {
1345 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
1346 }
1347
1348 print '<tr class="oddeven">';
1349 print "<!-- Product -->";
1350 print "<td>".$date."</td>";
1351 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1352 // Account
1353 print "<td>";
1354 $accountoshow = length_accountg($k);
1355 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1356 print '<span class="error">'.$langs->trans("ProductNotDefined").'</span>';
1357 } else {
1358 print $accountoshow;
1359 }
1360 print "</td>";
1361 // Subledger account
1362 print "<td>";
1363 if (getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_USE_AUXILIARY_ON_DEPOSIT')) {
1364 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_DEPOSIT')) {
1365 print length_accounta($tabcompany[$key]['code_compta']);
1366 }
1367 } elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
1368 print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
1369 }
1370 print '</td>';
1371 $companystatic->id = $tabcompany[$key]['id'];
1372 $companystatic->name = $tabcompany[$key]['name'];
1373 print "<td>" . $bookkeepingstatic->accountingLabelForOperation($companystatic->getNomUrl(0, 'customer'), $invoicestatic->ref, $accountingaccount->label, 1) . "</td>";
1374 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1375 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1376 print "</tr>";
1377
1378 $i++;
1379 }
1380
1381 // VAT
1382 $listoftax = array(0, 1, 2);
1383 foreach ($listoftax as $numtax) {
1384 $arrayofvat = $tabtva;
1385 if ($numtax == 1) {
1386 $arrayofvat = $tablocaltax1;
1387 }
1388 if ($numtax == 2) {
1389 $arrayofvat = $tablocaltax2;
1390 }
1391
1392 // $key is id of invoice
1393 foreach ($arrayofvat[$key] as $k => $mt) {
1394 if ($mt) {
1395 print '<tr class="oddeven">';
1396 print "<!-- VAT -->";
1397 print "<td>".$date."</td>";
1398 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1399 // Account
1400 print "<td>";
1401 $accountoshow = length_accountg($k);
1402 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1403 print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("AccountingJournalType2").')</span>';
1404 } else {
1405 print $accountoshow;
1406 }
1407 print "</td>";
1408 // Subledger account
1409 print "<td>";
1410 print '</td>';
1411 // $def_tva is array[invoiceid][accountancy_code_sell_of_vat_rate_found][vatrate]=vatrate
1412 //var_dump($arrayofvat[$key]); //var_dump($key); //var_dump($k);
1413 $tmpvatrate = (empty($def_tva[$key][$k]) ? (empty($arrayofvat[$key][$k]) ? '' : $arrayofvat[$key][$k]) : implode(', ', $def_tva[$key][$k]));
1414 $labelvatrate = $langs->trans("Taxes").' '.$tmpvatrate.' %';
1415 $labelvatrate .= ($numtax ? ' - Localtax '.$numtax : '');
1416 print "<td>" . $bookkeepingstatic->accountingLabelForOperation($companystatic->getNomUrl(0, 'customer'), $invoicestatic->ref, $labelvatrate, 1) . "</td>";
1417 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1418 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1419 print "</tr>";
1420
1421 $i++;
1422 }
1423 }
1424 }
1425
1426 // Revenue stamp
1427 if (isset($tabrevenuestamp[$key]) && is_array($tabrevenuestamp[$key])) {
1428 foreach ($tabrevenuestamp[$key] as $k => $mt) {
1429 print '<tr class="oddeven">';
1430 print "<!-- Thirdparty revenuestamp -->";
1431 print "<td>" . $date . "</td>";
1432 print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
1433 // Account
1434 print "<td>";
1435 $accountoshow = length_accountg($k);
1436 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1437 print '<span class="error">' . $langs->trans("MainAccountForRevenueStampSaleNotDefined") . '</span>';
1438 } else {
1439 print $accountoshow;
1440 }
1441 print '</td>';
1442 // Subledger account
1443 print "<td>";
1444 print '</td>';
1445 print "<td>" . $bookkeepingstatic->accountingLabelForOperation($companystatic->getNomUrl(0, 'customer'), $invoicestatic->ref, $langs->trans("RevenueStamp"), 1) . "</td>";
1446 print '<td class="right nowraponall amount">' . ($mt < 0 ? price(-$mt) : '') . "</td>";
1447 print '<td class="right nowraponall amount">' . ($mt >= 0 ? price($mt) : '') . "</td>";
1448 print "</tr>";
1449 }
1450 }
1451 }
1452
1453 if (!$i) {
1454 print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1455 }
1456
1457 print "</table>";
1458 print '</div>';
1459
1460 // End of page
1461 llxFooter();
1462}
1463
1464$db->close();
length_accountg($account)
Return General accounting account with defined length (used for product and miscellaneous)
journalHead($nom, $variant, $period, $periodlink, $description, $builddate, $exportlink='', $moreparam=array(), $calcmode='', $varlink='', $moreoptions=array())
Show header of a page used to transfer/dispatch data in accounting.
getDefaultDatesForTransfer()
Return Default dates for transfer based on periodicity option in accountancy setup.
length_accounta($accounta)
Return Auxiliary accounting account of thirdparties with defined length.
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage accounting accounts.
Class to manage accounting journals.
Class to manage Ledger (General Ledger and Subledger)
Class to manage customers or prospects.
Class to manage invoices.
const TYPE_REPLACEMENT
Replacement invoice.
const TYPE_SITUATION
Situation invoice.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
Class to manage invoice lines.
Class to manage generation of HTML components Only common components must be here.
Class Lettering.
Class to manage third parties objects (customers, suppliers, prospects...)
global $mysoc
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:603
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:622
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0, $html=0)
Return a string with VAT rate label formatted for view output Used into pdf and HTML pages.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
getTaxesFromId($vatrate, $buyer=null, $seller=null, $firstparamisid=1)
Get tax (VAT) main information from Id.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.