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