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