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