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