dolibarr 20.0.5
purchasesjournal.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-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
7 * Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
8 * Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
9 * Copyright (C) 2018-2024 Frédéric France <frederic.france@free.fr>
10 * Copyright (C) 2018 Eric Seigne <eric.seigne@cap-rel.fr>
11 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
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
32require '../../main.inc.php';
33require_once DOL_DOCUMENT_ROOT.'/core/lib/report.lib.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingjournal.class.php';
38require_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountingaccount.class.php';
39require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
40require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.class.php';
41require_once DOL_DOCUMENT_ROOT.'/accountancy/class/bookkeeping.class.php';
42
43// Load translation files required by the page
44$langs->loadLangs(array("commercial", "compta", "bills", "other", "accountancy", "errors"));
45
46$id_journal = GETPOSTINT('id_journal');
47$action = GETPOST('action', 'aZ09');
48
49$date_startmonth = GETPOST('date_startmonth');
50$date_startday = GETPOST('date_startday');
51$date_startyear = GETPOST('date_startyear');
52$date_endmonth = GETPOST('date_endmonth');
53$date_endday = GETPOST('date_endday');
54$date_endyear = GETPOST('date_endyear');
55$in_bookkeeping = GETPOST('in_bookkeeping');
56if ($in_bookkeeping == '') {
57 $in_bookkeeping = 'notyet';
58}
59
60$now = dol_now();
61
62$hookmanager->initHooks(array('purchasesjournal'));
63$parameters = array();
64
65// Security check
66if (!isModEnabled('accounting')) {
68}
69if ($user->socid > 0) {
71}
72if (!$user->hasRight('accounting', 'bind', 'write')) {
74}
75
76$error = 0;
77
78
79/*
80 * Actions
81 */
82
83$reshook = $hookmanager->executeHooks('doActions', $parameters, $user, $action); // Note that $action and $object may have been modified by some hooks
84
85$accountingaccount = new AccountingAccount($db);
86
87// Get information of journal
88$accountingjournalstatic = new AccountingJournal($db);
89$accountingjournalstatic->fetch($id_journal);
90$journal = $accountingjournalstatic->code;
91$journal_label = $accountingjournalstatic->label;
92
93$date_start = dol_mktime(0, 0, 0, $date_startmonth, $date_startday, $date_startyear);
94$date_end = dol_mktime(23, 59, 59, $date_endmonth, $date_endday, $date_endyear);
95
96if (empty($date_startmonth)) {
97 // Period by default on transfer
99 $date_start = $dates['date_start'];
100 $pastmonthyear = $dates['pastmonthyear'];
101 $pastmonth = $dates['pastmonth'];
102}
103if (empty($date_endmonth)) {
104 // Period by default on transfer
106 $date_end = $dates['date_end'];
107 $pastmonthyear = $dates['pastmonthyear'];
108 $pastmonth = $dates['pastmonth'];
109}
110
111if (!GETPOSTISSET('date_startmonth') && (empty($date_start) || empty($date_end))) { // We define date_start and date_end, only if we did not submit the form
112 $date_start = dol_get_first_day($pastmonthyear, $pastmonth, false);
113 $date_end = dol_get_last_day($pastmonthyear, $pastmonth, false);
114}
115
116$sql = "SELECT f.rowid, f.ref as ref, f.type, f.datef as df, f.libelle as label, f.ref_supplier, f.date_lim_reglement as dlr, f.close_code, f.vat_reverse_charge,";
117$sql .= " fd.rowid as fdid, fd.description, fd.product_type, fd.total_ht, fd.tva as total_tva, fd.total_localtax1, fd.total_localtax2, fd.tva_tx, fd.total_ttc, fd.vat_src_code, fd.info_bits,";
118$sql .= " p.default_vat_code AS product_buy_default_vat_code, p.tva_tx as product_buy_vat, p.localtax1_tx as product_buy_localvat1, p.localtax2_tx as product_buy_localvat2,";
119$sql .= " co.code as country_code, co.label as country_label,";
120$sql .= " s.rowid as socid, s.nom as name, s.fournisseur, s.code_client, s.code_fournisseur, s.fk_pays,";
121if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
122 $sql .= " spe.accountancy_code_customer as code_compta,";
123 $sql .= " spe.accountancy_code_supplier as code_compta_fournisseur,";
124} else {
125 $sql .= " s.code_compta as code_compta,";
126 $sql .= " s.code_compta_fournisseur,";
127}
128if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
129 $sql .= " ppe.accountancy_code_buy,";
130} else {
131 $sql .= " p.accountancy_code_buy,";
132}
133$sql .= " aa.rowid as fk_compte, aa.account_number as compte, aa.label as label_compte";
134$parameters = array();
135$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
136$sql .= $hookmanager->resPrint;
137$sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn_det as fd";
138$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = fd.fk_product";
139if (getDolGlobalString('MAIN_PRODUCT_PERENTITY_SHARED')) {
140 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product_perentity as ppe ON ppe.fk_product = p.rowid AND ppe.entity = " . ((int) $conf->entity);
141}
142$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."accounting_account as aa ON aa.rowid = fd.fk_code_ventilation";
143$sql .= " JOIN ".MAIN_DB_PREFIX."facture_fourn as f ON f.rowid = fd.fk_facture_fourn";
144$sql .= " JOIN ".MAIN_DB_PREFIX."societe as s ON s.rowid = f.fk_soc";
145$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as co ON co.rowid = s.fk_pays ";
146if (getDolGlobalString('MAIN_COMPANY_PERENTITY_SHARED')) {
147 $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "societe_perentity as spe ON spe.fk_soc = s.rowid AND spe.entity = " . ((int) $conf->entity);
148}
149$parameters = array();
150$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters); // Note that $action and $object may have been modified by hook
151$sql .= $hookmanager->resPrint;
152$sql .= " WHERE f.fk_statut > 0";
153$sql .= " AND fd.fk_code_ventilation > 0";
154$sql .= " AND f.entity IN (".getEntity('facture_fourn', 0).")"; // We don't share object for accountancy
155if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
156 $sql .= " AND f.type IN (".FactureFournisseur::TYPE_STANDARD.",".FactureFournisseur::TYPE_REPLACEMENT.",".FactureFournisseur::TYPE_CREDIT_NOTE.",".FactureFournisseur::TYPE_SITUATION.")";
157} else {
159}
160if ($date_start && $date_end) {
161 $sql .= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
162}
163// Define begin binding date
164if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
165 $sql .= " AND f.datef >= '".$db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING'))."'";
166}
167// Already in bookkeeping or not
168if ($in_bookkeeping == 'already') {
169 $sql .= " AND f.rowid IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')";
170}
171if ($in_bookkeeping == 'notyet') {
172 $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM ".MAIN_DB_PREFIX."accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')";
173}
174$parameters = array();
175$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
176$sql .= $hookmanager->resPrint;
177$sql .= " ORDER BY f.datef";
178
179dol_syslog('accountancy/journal/purchasesjournal.php', LOG_DEBUG);
180$result = $db->query($sql);
181if ($result) {
182 $tabfac = array();
183 $tabht = array();
184 $tabtva = array();
185 $def_tva = array();
186 $tabttc = array();
187 $tablocaltax1 = array();
188 $tablocaltax2 = array();
189 $tabcompany = array();
190 $tabother = array();
191 $tabrctva = array();
192 $tabrclocaltax1 = array();
193 $tabrclocaltax2 = array();
194 $vatdata_cache = array();
195
196 $num = $db->num_rows($result);
197
198 // Variables
199 $cptfour = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER', 'NotDefined');
200 $cpttva = getDolGlobalString('ACCOUNTING_VAT_BUY_ACCOUNT', 'NotDefined');
201 $rcctva = getDolGlobalString('ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT', 'NotDefined');
202 $rcdtva = getDolGlobalString('ACCOUNTING_VAT_BUY_REVERSE_CHARGES_DEBIT', 'NotDefined');
203 $country_code_in_EEC = getCountriesInEEC(); // This make a database call but there is a cache done into $conf->cache['country_code_in_EEC']
204
205 $i = 0;
206 while ($i < $num) {
207 $obj = $db->fetch_object($result);
208
209 // Controls
210 $compta_soc = ($obj->code_compta_fournisseur != "") ? $obj->code_compta_fournisseur : $cptfour;
211
212 $compta_prod = $obj->compte;
213 if (empty($compta_prod)) {
214 if ($obj->product_type == 0) {
215 $compta_prod = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', 'NotDefined');
216 } else {
217 $compta_prod = getDolGlobalString('ACCOUNTING_SERVICE_BUY_ACCOUNT', 'NotDefined');
218 }
219 }
220
221 $tax_id = $obj->tva_tx . ($obj->vat_src_code ? ' (' . $obj->vat_src_code . ')' : '');
222 if (array_key_exists($tax_id, $vatdata_cache)) {
223 $vatdata = $vatdata_cache[$tax_id];
224 } else {
225 $vatdata = getTaxesFromId($tax_id, $mysoc, $mysoc, 0);
226 $vatdata_cache[$tax_id] = $vatdata;
227 }
228 $compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
229 $compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
230 $compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
231 $compta_counterpart_tva_npr = getDolGlobalString('ACCOUNTING_COUNTERPART_VAT_NPR', 'NotDefined');
232
233 // Define array to display all VAT rates that use this accounting account $compta_tva
234 if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
235 $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.')' : ''));
236 }
237
238 //$line = new SupplierInvoiceLine($db);
239 //$line->fetch($obj->fdid);
240
241 $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df);
242 $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr);
243 $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier.' ('.$obj->ref.')';
244 $tabfac[$obj->rowid]["refsologest"] = $obj->ref;
245 $tabfac[$obj->rowid]["refsuppliersologest"] = $obj->ref_supplier;
246 $tabfac[$obj->rowid]["type"] = $obj->type;
247 $tabfac[$obj->rowid]["description"] = $obj->description;
248 $tabfac[$obj->rowid]["close_code"] = $obj->close_code; // close_code = 'replaced' for replacement invoices (not used in most european countries)
249 //$tabfac[$obj->rowid]["fk_facturefourndet"] = $obj->fdid;
250
251 // Avoid warnings
252 if (!isset($tabttc[$obj->rowid][$compta_soc])) {
253 $tabttc[$obj->rowid][$compta_soc] = 0;
254 }
255 if (!isset($tabht[$obj->rowid][$compta_prod])) {
256 $tabht[$obj->rowid][$compta_prod] = 0;
257 }
258 if (!isset($tabtva[$obj->rowid][$compta_tva])) {
259 $tabtva[$obj->rowid][$compta_tva] = 0;
260 }
261 if (!isset($tablocaltax1[$obj->rowid][$compta_localtax1])) {
262 $tablocaltax1[$obj->rowid][$compta_localtax1] = 0;
263 }
264 if (!isset($tablocaltax2[$obj->rowid][$compta_localtax2])) {
265 $tablocaltax2[$obj->rowid][$compta_localtax2] = 0;
266 }
267
268 // VAT Reverse charge
269 if (($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) && $obj->vat_reverse_charge == 1 && in_array($obj->country_code, $country_code_in_EEC)) {
270 $rcvatdata = getTaxesFromId($obj->product_buy_vat . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : ''), $mysoc, $mysoc, 0);
271 $rcc_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
272 $rcd_compta_tva = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
273 $rcc_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
274 $rcd_compta_localtax1 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
275 $rcc_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_credit']) ? $vatdata['accountancy_code_vat_reverse_charge_credit'] : $rcctva);
276 $rcd_compta_localtax2 = (!empty($vatdata['accountancy_code_vat_reverse_charge_debit']) ? $vatdata['accountancy_code_vat_reverse_charge_debit'] : $rcdtva);
277 if (price2num($obj->product_buy_vat) || !empty($obj->product_buy_default_vat_code)) {
278 $vat_key = vatrate($obj->product_buy_vat) . ($obj->product_buy_default_vat_code ? ' (' . $obj->product_buy_default_vat_code . ')' : '');
279 $val_value = $vat_key;
280 $def_tva[$obj->rowid][$rcc_compta_tva][$vat_key] = $val_value;
281 $def_tva[$obj->rowid][$rcd_compta_tva][$vat_key] = $val_value;
282 }
283
284 if (!isset($tabrctva[$obj->rowid][$rcc_compta_tva])) {
285 $tabrctva[$obj->rowid][$rcc_compta_tva] = 0;
286 }
287 if (!isset($tabrctva[$obj->rowid][$rcd_compta_tva])) {
288 $tabrctva[$obj->rowid][$rcd_compta_tva] = 0;
289 }
290 if (!isset($tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1])) {
291 $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] = 0;
292 }
293 if (!isset($tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1])) {
294 $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] = 0;
295 }
296 if (!isset($tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2])) {
297 $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] = 0;
298 }
299 if (!isset($tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2])) {
300 $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] = 0;
301 }
302
303 $rcvat = (float) price2num($obj->total_ttc * $obj->product_buy_vat / 100, 'MT');
304 $rclocalvat1 = (float) price2num($obj->total_ttc * $obj->product_buy_localvat1 / 100, 'MT');
305 $rclocalvat2 = (float) price2num($obj->total_ttc * $obj->product_buy_localvat2 / 100, 'MT');
306
307 $tabrctva[$obj->rowid][$rcd_compta_tva] += $rcvat;
308 $tabrctva[$obj->rowid][$rcc_compta_tva] -= $rcvat;
309 $tabrclocaltax1[$obj->rowid][$rcd_compta_localtax1] += $rclocalvat1;
310 $tabrclocaltax1[$obj->rowid][$rcc_compta_localtax1] -= $rclocalvat1;
311 $tabrclocaltax2[$obj->rowid][$rcd_compta_localtax2] += $rclocalvat2;
312 $tabrclocaltax2[$obj->rowid][$rcc_compta_localtax2] -= $rclocalvat2;
313 }
314
315 $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc;
316 $tabht[$obj->rowid][$compta_prod] += $obj->total_ht;
317 $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva;
318 $tva_npr = ((($obj->info_bits & 1) == 1) ? 1 : 0);
319 if ($tva_npr) { // If NPR, we add an entry for counterpartWe into tabother
320 $tabother[$obj->rowid][$compta_counterpart_tva_npr] += $obj->total_tva;
321 }
322 $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1;
323 $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2;
324 $tabcompany[$obj->rowid] = array(
325 'id' => $obj->socid,
326 'name' => $obj->name,
327 'code_fournisseur' => $obj->code_fournisseur,
328 'code_compta_fournisseur' => $compta_soc
329 );
330
331 $i++;
332
333 // Check for too many lines.
334 if ($i > getDolGlobalInt('ACCOUNTANCY_MAX_TOO_MANY_LINES_TO_PROCESS', 10000)) {
335 $error++;
336 setEventMessages("ErrorTooManyLinesToProcessPleaseUseAMoreSelectiveFilter", null, 'errors');
337 break;
338 }
339 }
340} else {
341 dol_print_error($db);
342}
343
344$errorforinvoice = array();
345
346/*
347// Old way, 1 query for each invoice
348// Loop in invoices to detect lines with not binding lines
349foreach ($tabfac as $key => $val) { // Loop on each invoice
350 $sql = "SELECT COUNT(fd.rowid) as nb";
351 $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn_det as fd";
352 $sql .= " WHERE fd.product_type <= 2 AND fd.fk_code_ventilation <= 0";
353 $sql .= " AND fd.total_ttc <> 0 AND fk_facture_fourn = ".((int) $key);
354 $resql = $db->query($sql);
355 if ($resql) {
356 $obj = $db->fetch_object($resql);
357 if ($obj->nb > 0) {
358 $errorforinvoice[$key] = 'somelinesarenotbound';
359 }
360 } else {
361 dol_print_error($db);
362 }
363}
364*/
365// New way, single query, load all unbound lines
366if (!empty($tabfac)) {
367 $sql = "
368 SELECT
369 fk_facture_fourn,
370 COUNT(fd.rowid) as nb
371 FROM
372 " . MAIN_DB_PREFIX . "facture_fourn_det as fd
373 WHERE
374 fd.product_type <= 2
375 AND fd.fk_code_ventilation <= 0
376 AND fd.total_ttc <> 0
377 AND fk_facture_fourn IN (".$db->sanitize(implode(",", array_keys($tabfac))).")
378 GROUP BY fk_facture_fourn
379 ";
380 $resql = $db->query($sql);
381
382 $num = $db->num_rows($resql);
383 $i = 0;
384 while ($i < $num) {
385 $obj = $db->fetch_object($resql);
386 if ($obj->nb > 0) {
387 $errorforinvoice[$obj->fk_facture_fourn] = 'somelinesarenotbound';
388 }
389 $i++;
390 }
391}
392//var_dump($errorforinvoice);exit;
393
394
395
396// Bookkeeping Write
397if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'bind', 'write')) {
398 $now = dol_now();
399 $error = 0;
400
401 $companystatic = new Societe($db);
402 $invoicestatic = new FactureFournisseur($db);
403 $accountingaccountsupplier = new AccountingAccount($db);
404
405 $accountingaccountsupplier->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), true);
406
407 foreach ($tabfac as $key => $val) { // Loop on each invoice
408 $errorforline = 0;
409
410 $totalcredit = 0;
411 $totaldebit = 0;
412
413 $db->begin(); // We accept transaction into loop so if we hang, we can continue transfer from last error
414
415 $companystatic->id = $tabcompany[$key]['id'];
416 $companystatic->name = $tabcompany[$key]['name'];
417 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
418 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
419 $companystatic->fournisseur = 1;
420
421 $invoicestatic->id = $key;
422 $invoicestatic->ref = (string) $val["refsologest"];
423 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
424 $invoicestatic->type = $val["type"];
425 $invoicestatic->description = html_entity_decode(dol_trunc($val["description"], 32));
426 $invoicestatic->close_code = $val["close_code"];
427
428 $date = dol_print_date($val["date"], 'day');
429
430 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
431 $replacedinvoice = 0;
432 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
433 $replacedinvoice = 1;
434 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
435 if ($alreadydispatched) {
436 $replacedinvoice = 2;
437 }
438 }
439
440 // 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)
441 if ($replacedinvoice == 1) {
442 $db->rollback();
443 continue;
444 }
445
446 // Error if some lines are not binded/ready to be journalized
447 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
448 $error++;
449 $errorforline++;
450 setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
451 }
452
453 // Thirdparty
454 if (!$errorforline) {
455 foreach ($tabttc[$key] as $k => $mt) {
456 $bookkeeping = new BookKeeping($db);
457 $bookkeeping->doc_date = $val["date"];
458 $bookkeeping->date_lim_reglement = $val["datereg"];
459 $bookkeeping->doc_ref = $val["refsologest"];
460 $bookkeeping->date_creation = $now;
461 $bookkeeping->doc_type = 'supplier_invoice';
462 $bookkeeping->fk_doc = $key;
463 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
464 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
465
466 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
467 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
468
469 $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER');
470 $bookkeeping->label_compte = $accountingaccountsupplier->label;
471
472 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("SubledgerAccount");
473 $bookkeeping->montant = $mt;
474 $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
475 $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
476 $bookkeeping->credit = ($mt > 0) ? $mt : 0;
477 $bookkeeping->code_journal = $journal;
478 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
479 $bookkeeping->fk_user_author = $user->id;
480 $bookkeeping->entity = $conf->entity;
481
482 $totaldebit += $bookkeeping->debit;
483 $totalcredit += $bookkeeping->credit;
484
485 $result = $bookkeeping->create($user);
486 if ($result < 0) {
487 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
488 $error++;
489 $errorforline++;
490 $errorforinvoice[$key] = 'alreadyjournalized';
491 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
492 } else {
493 $error++;
494 $errorforline++;
495 $errorforinvoice[$key] = 'other';
496 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
497 }
498 } else {
499 if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
500 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
501 $lettering_static = new Lettering($db);
502
503 $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
504 }
505 }
506 }
507 }
508
509 // Product / Service
510 if (!$errorforline) {
511 foreach ($tabht[$key] as $k => $mt) {
512 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
513 $accountingaccount = new AccountingAccount($db);
514 $accountingaccount->fetch(0, $k, true);
515 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
516 } else {
517 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
518 }
519
520 $label_account = $accountingaccount->label;
521
522 // get compte id and label
523 if ($accountingaccount->id > 0) {
524 $bookkeeping = new BookKeeping($db);
525 $bookkeeping->doc_date = $val["date"];
526 $bookkeeping->date_lim_reglement = $val["datereg"];
527 $bookkeeping->doc_ref = $val["refsologest"];
528 $bookkeeping->date_creation = $now;
529 $bookkeeping->doc_type = 'supplier_invoice';
530 $bookkeeping->fk_doc = $key;
531 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
532 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
533
534 if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
535 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
536 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
537 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
538 } else {
539 $bookkeeping->subledger_account = '';
540 $bookkeeping->subledger_label = '';
541 }
542 } else {
543 $bookkeeping->subledger_account = '';
544 $bookkeeping->subledger_label = '';
545 }
546
547 $bookkeeping->numero_compte = $k;
548 $bookkeeping->label_compte = $label_account;
549
550 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$label_account;
551 $bookkeeping->montant = $mt;
552 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
553 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
554 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
555 $bookkeeping->code_journal = $journal;
556 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
557 $bookkeeping->fk_user_author = $user->id;
558 $bookkeeping->entity = $conf->entity;
559
560 $totaldebit += $bookkeeping->debit;
561 $totalcredit += $bookkeeping->credit;
562
563 $result = $bookkeeping->create($user);
564 if ($result < 0) {
565 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
566 $error++;
567 $errorforline++;
568 $errorforinvoice[$key] = 'alreadyjournalized';
569 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
570 } else {
571 $error++;
572 $errorforline++;
573 $errorforinvoice[$key] = 'other';
574 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
575 }
576 }
577 }
578 }
579 }
580
581 // VAT
582 // var_dump($tabtva);
583 if (!$errorforline) {
584 $listoftax = array(0, 1, 2);
585 foreach ($listoftax as $numtax) {
586 $arrayofvat = $tabtva;
587 if ($numtax == 1) {
588 $arrayofvat = $tablocaltax1;
589 }
590 if ($numtax == 2) {
591 $arrayofvat = $tablocaltax2;
592 }
593
594 // VAT Reverse charge
595 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
596 $has_vat = false;
597 foreach ($arrayofvat[$key] as $k => $mt) {
598 if ($mt) {
599 $has_vat = true;
600 }
601 }
602
603 if (!$has_vat) {
604 $arrayofvat = $tabrctva;
605 if ($numtax == 1) {
606 $arrayofvat = $tabrclocaltax1;
607 }
608 if ($numtax == 2) {
609 $arrayofvat = $tabrclocaltax2;
610 }
611 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
612 $arrayofvat[$key] = array();
613 }
614 }
615 }
616
617 foreach ($arrayofvat[$key] as $k => $mt) {
618 if ($mt) {
619 $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
620 $label_account = $accountingaccount->label;
621
622 $bookkeeping = new BookKeeping($db);
623 $bookkeeping->doc_date = $val["date"];
624 $bookkeeping->date_lim_reglement = $val["datereg"];
625 $bookkeeping->doc_ref = $val["refsologest"];
626 $bookkeeping->date_creation = $now;
627 $bookkeeping->doc_type = 'supplier_invoice';
628 $bookkeeping->fk_doc = $key;
629 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
630 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
631
632 $bookkeeping->subledger_account = '';
633 $bookkeeping->subledger_label = '';
634
635 $bookkeeping->numero_compte = $k;
636 $bookkeeping->label_compte = $label_account;
637
638 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
639 $bookkeeping->montant = $mt;
640 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
641 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
642 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
643 $bookkeeping->code_journal = $journal;
644 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
645 $bookkeeping->fk_user_author = $user->id;
646 $bookkeeping->entity = $conf->entity;
647
648 $totaldebit += $bookkeeping->debit;
649 $totalcredit += $bookkeeping->credit;
650
651 $result = $bookkeeping->create($user);
652 if ($result < 0) {
653 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
654 $error++;
655 $errorforline++;
656 $errorforinvoice[$key] = 'alreadyjournalized';
657 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
658 } else {
659 $error++;
660 $errorforline++;
661 $errorforinvoice[$key] = 'other';
662 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
663 }
664 }
665 }
666 }
667 }
668 }
669
670 // Counterpart of VAT for VAT NPR
671 // var_dump($tabother);
672 if (!$errorforline && isset($tabother[$key]) && is_array($tabother[$key])) {
673 foreach ($tabother[$key] as $k => $mt) {
674 if ($mt) {
675 $bookkeeping = new BookKeeping($db);
676 $bookkeeping->doc_date = $val["date"];
677 $bookkeeping->date_lim_reglement = $val["datereg"];
678 $bookkeeping->doc_ref = $val["refsologest"];
679 $bookkeeping->date_creation = $now;
680 $bookkeeping->doc_type = 'supplier_invoice';
681 $bookkeeping->fk_doc = $key;
682 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
683 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
684
685 $bookkeeping->subledger_account = '';
686 $bookkeeping->subledger_label = '';
687
688 $bookkeeping->numero_compte = $k;
689
690 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' NPR';
691 $bookkeeping->montant = $mt;
692 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
693 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
694 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
695 $bookkeeping->code_journal = $journal;
696 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
697 $bookkeeping->fk_user_author = $user->id;
698 $bookkeeping->entity = $conf->entity;
699
700 $totaldebit += $bookkeeping->debit;
701 $totalcredit += $bookkeeping->credit;
702
703 $result = $bookkeeping->create($user);
704 if ($result < 0) {
705 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
706 $error++;
707 $errorforline++;
708 $errorforinvoice[$key] = 'alreadyjournalized';
709 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
710 } else {
711 $error++;
712 $errorforline++;
713 $errorforinvoice[$key] = 'other';
714 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
715 }
716 }
717 }
718 }
719 }
720
721 // Protection against a bug on lines before
722 if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
723 $error++;
724 $errorforline++;
725 $errorforinvoice[$key] = 'amountsnotbalanced';
726 setEventMessages('We tried to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors');
727 }
728
729 if (!$errorforline) {
730 $db->commit();
731 } else {
732 $db->rollback();
733
734 if ($error >= 10) {
735 setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
736 break; // Break in the foreach
737 }
738 }
739 }
740
741 $tabpay = $tabfac;
742
743 if (empty($error) && count($tabpay) > 0) {
744 setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
745 } elseif (count($tabpay) == $error) {
746 setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
747 } else {
748 setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
749 }
750
751 $action = '';
752
753 // Must reload data, so we make a redirect
754 if (count($tabpay) != $error) {
755 $param = 'id_journal='.$id_journal;
756 $param .= '&date_startday='.$date_startday;
757 $param .= '&date_startmonth='.$date_startmonth;
758 $param .= '&date_startyear='.$date_startyear;
759 $param .= '&date_endday='.$date_endday;
760 $param .= '&date_endmonth='.$date_endmonth;
761 $param .= '&date_endyear='.$date_endyear;
762 $param .= '&in_bookkeeping='.$in_bookkeeping;
763 header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
764 exit;
765 }
766}
767
768/*
769 * View
770 */
771
772$form = new Form($db);
773
774// Export
775if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
776 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
777
778 $filename = 'journal';
779 $type_export = 'journal';
780 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
781
782 $companystatic = new Fournisseur($db);
783 $invoicestatic = new FactureFournisseur($db);
784
785 foreach ($tabfac as $key => $val) {
786 $companystatic->id = $tabcompany[$key]['id'];
787 $companystatic->name = $tabcompany[$key]['name'];
788 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
789 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
790 $companystatic->fournisseur = 1;
791
792 $invoicestatic->id = $key;
793 $invoicestatic->ref = $val["refsologest"];
794 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
795 $invoicestatic->type = $val["type"];
796 $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
797 $invoicestatic->close_code = $val["close_code"];
798
799 $date = dol_print_date($val["date"], 'day');
800
801 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
802 $replacedinvoice = 0;
803 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
804 $replacedinvoice = 1;
805 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
806 if ($alreadydispatched) {
807 $replacedinvoice = 2;
808 }
809 }
810
811 // 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)
812 if ($replacedinvoice == 1) {
813 continue;
814 }
815
816 // Third party
817 foreach ($tabttc[$key] as $k => $mt) {
818 //if ($mt) {
819 print '"'.$key.'"'.$sep;
820 print '"'.$date.'"'.$sep;
821 print '"'.$val["refsologest"].'"'.$sep;
822 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
823 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
824 print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER')).'"'.$sep;
825 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
826 print '"'.$langs->trans("Thirdparty").'"'.$sep;
827 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.$langs->trans("Thirdparty").'"'.$sep;
828 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
829 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
830 print '"'.$journal.'"';
831 print "\n";
832 //}
833 }
834
835 // Product / Service
836 foreach ($tabht[$key] as $k => $mt) {
837 $accountingaccount = new AccountingAccount($db);
838 $accountingaccount->fetch(null, $k, true);
839 //if ($mt) {
840 print '"'.$key.'"'.$sep;
841 print '"'.$date.'"'.$sep;
842 print '"'.$val["refsologest"].'"'.$sep;
843 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
844 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
845 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
846 print '""'.$sep;
847 print '"'.mb_convert_encoding(dol_trunc($accountingaccount->label, 32), 'ISO-8859-1').'"'.$sep;
848 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.dol_trunc($accountingaccount->label, 32).'"'.$sep;
849 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
850 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
851 print '"'.$journal.'"';
852 print "\n";
853 //}
854 }
855
856 // VAT
857 $listoftax = array(0, 1, 2);
858 foreach ($listoftax as $numtax) {
859 $arrayofvat = $tabtva;
860 if ($numtax == 1) {
861 $arrayofvat = $tablocaltax1;
862 }
863 if ($numtax == 2) {
864 $arrayofvat = $tablocaltax2;
865 }
866
867 // VAT Reverse charge
868 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
869 $has_vat = false;
870 foreach ($arrayofvat[$key] as $k => $mt) {
871 if ($mt) {
872 $has_vat = true;
873 }
874 }
875
876 if (!$has_vat) {
877 $arrayofvat = $tabrctva;
878 if ($numtax == 1) {
879 $arrayofvat = $tabrclocaltax1;
880 }
881 if ($numtax == 2) {
882 $arrayofvat = $tabrclocaltax2;
883 }
884 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
885 $arrayofvat[$key] = array();
886 }
887 }
888 }
889
890 foreach ($arrayofvat[$key] as $k => $mt) {
891 if ($mt) {
892 print '"'.$key.'"'.$sep;
893 print '"'.$date.'"'.$sep;
894 print '"'.$val["refsologest"].'"'.$sep;
895 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
896 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
897 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
898 print '""'.$sep;
899 print '"'.$langs->trans("VAT").' - '.implode(', ', $def_tva[$key][$k]).' %"'.$sep;
900 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.$langs->trans("VAT").implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '').'"'.$sep;
901 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
902 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
903 print '"'.$journal.'"';
904 print "\n";
905 }
906 }
907
908 // VAT counterpart for NPR
909 if (isset($tabother[$key]) && is_array($tabother[$key])) {
910 foreach ($tabother[$key] as $k => $mt) {
911 if ($mt) {
912 print '"'.$key.'"'.$sep;
913 print '"'.$date.'"'.$sep;
914 print '"'.$val["refsologest"].'"'.$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 '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
919 print '"'.$langs->trans("Thirdparty").'"'.$sep;
920 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.$langs->trans("VAT").' NPR"'.$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 }
929 }
930}
931
932if (empty($action) || $action == 'view') {
933 $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
934 $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;';
935 llxHeader('', dol_string_nohtmltag($title), $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-generation page-purchasesjournal');
936
937 $nom = $title;
938 $nomlink = '';
939 $periodlink = '';
940 $exportlink = '';
941 $builddate = dol_now();
942 $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
943 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
944 $description .= $langs->trans("DepositsAreNotIncluded");
945 } else {
946 $description .= $langs->trans("DepositsAreIncluded");
947 }
948
949 $listofchoices = array('notyet' => $langs->trans("NotYetInGeneralLedger"), 'already' => $langs->trans("AlreadyInGeneralLedger"));
950 $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);
951 $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
952
953 $varlink = 'id_journal='.$id_journal;
954
955 journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
956
957 if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
958 // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
959 // Fiscal period test
960 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
961 $resql = $db->query($sql);
962 if ($resql) {
963 $obj = $db->fetch_object($resql);
964 if ($obj->nb == 0) {
965 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
966 $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
967 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
968 print $desc;
969 print '</div>';
970 }
971 } else {
972 dol_print_error($db);
973 }
974 }
975
976 // Button to write into Ledger
977 $acctSupplierNotConfigured = in_array(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), ['','-1']);
978 if ($acctSupplierNotConfigured) {
979 print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
980 $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
981 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
982 print $desc;
983 print '</div>';
984 }
985 print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
986 if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
987 print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
988 }
989 if ($acctSupplierNotConfigured) {
990 print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
991 } else {
992 if ($in_bookkeeping == 'notyet') {
993 print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
994 } else {
995 print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
996 }
997 }
998 print '</div>';
999
1000 // TODO Avoid using js. We can use a direct link with $param
1001 print '
1002 <script type="text/javascript">
1003 function launch_export() {
1004 $("div.fiche form input[name=\"action\"]").val("exportcsv");
1005 $("div.fiche form input[type=\"submit\"]").click();
1006 $("div.fiche form input[name=\"action\"]").val("");
1007 }
1008 function writebookkeeping() {
1009 console.log("click on writebookkeeping");
1010 $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
1011 $("div.fiche form input[type=\"submit\"]").click();
1012 $("div.fiche form input[name=\"action\"]").val("");
1013 }
1014 </script>';
1015
1016 /*
1017 * Show result array
1018 */
1019 print '<br>';
1020
1021 print '<div class="div-table-responsive">';
1022 print "<table class=\"noborder\" width=\"100%\">";
1023 print "<tr class=\"liste_titre\">";
1024 print "<td>".$langs->trans("Date")."</td>";
1025 print "<td>".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")</td>";
1026 print "<td>".$langs->trans("AccountAccounting")."</td>";
1027 print "<td>".$langs->trans("SubledgerAccount")."</td>";
1028 print "<td>".$langs->trans("LabelOperation")."</td>";
1029 print '<td class="center">'.$langs->trans("AccountingDebit")."</td>";
1030 print '<td class="center">'.$langs->trans("AccountingCredit")."</td>";
1031 print "</tr>\n";
1032
1033 $i = 0;
1034
1035 $invoicestatic = new FactureFournisseur($db);
1036 $companystatic = new Fournisseur($db);
1037
1038 foreach ($tabfac as $key => $val) {
1039 $companystatic->id = $tabcompany[$key]['id'];
1040 $companystatic->name = $tabcompany[$key]['name'];
1041 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
1042 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
1043 $companystatic->fournisseur = 1;
1044
1045 $invoicestatic->id = $key;
1046 $invoicestatic->ref = $val["refsologest"];
1047 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
1048 $invoicestatic->type = $val["type"];
1049 $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
1050 $invoicestatic->close_code = $val["close_code"];
1051
1052 $date = dol_print_date($val["date"], 'day');
1053
1054 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
1055 $replacedinvoice = 0;
1056 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
1057 $replacedinvoice = 1;
1058 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
1059 if ($alreadydispatched) {
1060 $replacedinvoice = 2;
1061 }
1062 }
1063
1064 // If not already into bookkeeping, we won't add it, if yes, add the counterpart ???.
1065 if ($replacedinvoice == 1) {
1066 print '<tr class="oddeven">';
1067 print "<!-- Replaced invoice -->";
1068 print "<td>".$date."</td>";
1069 print "<td><strike>".$invoicestatic->getNomUrl(1)."</strike></td>";
1070 // Account
1071 print "<td>";
1072 print $langs->trans("Replaced");
1073 print '</td>';
1074 // Subledger account
1075 print "<td>";
1076 print '</td>';
1077 print "<td>";
1078 print "</td>";
1079 print '<td class="right"></td>';
1080 print '<td class="right"></td>';
1081 print "</tr>";
1082
1083 $i++;
1084 continue;
1085 }
1086 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
1087 print '<tr class="oddeven">';
1088 print "<!-- Some lines are not bound -->";
1089 print "<td>".$date."</td>";
1090 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1091 // Account
1092 print "<td>";
1093 print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
1094 print '</td>';
1095 // Subledger account
1096 print "<td>";
1097 print '</td>';
1098 print "<td>";
1099 print "</td>";
1100 print '<td class="right"></td>';
1101 print '<td class="right"></td>';
1102 print "</tr>";
1103
1104 $i++;
1105 }
1106
1107 // Third party
1108 foreach ($tabttc[$key] as $k => $mt) {
1109 print '<tr class="oddeven">';
1110 print "<!-- Thirdparty -->";
1111 print "<td>".$date."</td>";
1112 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1113 // Account
1114 print "<td>";
1115 $accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'));
1116 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1117 print '<span class="error">'.$langs->trans("MainAccountForSuppliersNotDefined").'</span>';
1118 } else {
1119 print $accountoshow;
1120 }
1121 print '</td>';
1122 // Subledger account
1123 print "<td>";
1124 $accountoshow = length_accounta($k);
1125 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1126 print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
1127 } else {
1128 print $accountoshow;
1129 }
1130 print '</td>';
1131 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("SubledgerAccount")."</td>";
1132 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1133 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1134 print "</tr>";
1135
1136 $i++;
1137 }
1138
1139 // Product / Service
1140 foreach ($tabht[$key] as $k => $mt) {
1141 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
1142 $accountingaccount = new AccountingAccount($db);
1143 $accountingaccount->fetch(0, $k, true);
1144 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
1145 } else {
1146 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
1147 }
1148
1149 print '<tr class="oddeven">';
1150 print "<!-- Product -->";
1151 print "<td>".$date."</td>";
1152 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1153 // Account
1154 print "<td>";
1155 $accountoshow = length_accountg($k);
1156 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1157 print '<span class="error">'.$langs->trans("ProductAccountNotDefined").'</span>';
1158 } else {
1159 print $accountoshow;
1160 }
1161 print "</td>";
1162 // Subledger account
1163 print "<td>";
1164 if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
1165 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
1166 print length_accounta($tabcompany[$key]['code_compta']);
1167 }
1168 } elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
1169 print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
1170 }
1171 print '</td>';
1172 $companystatic->id = $tabcompany[$key]['id'];
1173 $companystatic->name = $tabcompany[$key]['name'];
1174 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$accountingaccount->label."</td>";
1175 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1176 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1177 print "</tr>";
1178
1179 $i++;
1180 }
1181
1182 // VAT
1183 $listoftax = array(0, 1, 2);
1184 foreach ($listoftax as $numtax) {
1185 $arrayofvat = $tabtva;
1186 if ($numtax == 1) {
1187 $arrayofvat = $tablocaltax1;
1188 }
1189 if ($numtax == 2) {
1190 $arrayofvat = $tablocaltax2;
1191 }
1192
1193 // VAT Reverse charge
1194 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
1195 $has_vat = false;
1196 foreach ($arrayofvat[$key] as $k => $mt) {
1197 if ($mt) {
1198 $has_vat = true;
1199 }
1200 }
1201
1202 if (!$has_vat) {
1203 $arrayofvat = $tabrctva;
1204 if ($numtax == 1) {
1205 $arrayofvat = $tabrclocaltax1;
1206 }
1207 if ($numtax == 2) {
1208 $arrayofvat = $tabrclocaltax2;
1209 }
1210 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
1211 $arrayofvat[$key] = array();
1212 }
1213 }
1214 }
1215
1216 foreach ($arrayofvat[$key] as $k => $mt) {
1217 if ($mt) {
1218 print '<tr class="oddeven">';
1219 print "<!-- VAT -->";
1220 print "<td>".$date."</td>";
1221 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1222 // Account
1223 print "<td>";
1224 $accountoshow = length_accountg($k);
1225 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1226 print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("AccountingJournalType3").')</span>';
1227 } else {
1228 print $accountoshow;
1229 }
1230 print "</td>";
1231 // Subledger account
1232 print "<td>";
1233 print '</td>';
1234 print "<td>";
1235 print $companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
1236 print "</td>";
1237 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1238 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1239 print "</tr>";
1240
1241 $i++;
1242 }
1243 }
1244 }
1245
1246 // VAT counterpart for NPR
1247 if (isset($tabother[$key]) && is_array($tabother[$key])) {
1248 foreach ($tabother[$key] as $k => $mt) {
1249 if ($mt) {
1250 print '<tr class="oddeven">';
1251 print '<!-- VAT counterpart NPR -->';
1252 print "<td>".$date."</td>";
1253 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1254 // Account
1255 print '<td>';
1256 $accountoshow = length_accountg($k);
1257 if ($accountoshow == '' || $accountoshow == 'NotDefined') {
1258 print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account</span>';
1259 } else {
1260 print $accountoshow;
1261 }
1262 print '</td>';
1263 // Subledger account
1264 print "<td>";
1265 print '</td>';
1266 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT")." NPR (counterpart)</td>";
1267 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1268 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1269 print "</tr>";
1270
1271 $i++;
1272 }
1273 }
1274 }
1275 }
1276
1277 if (!$i) {
1278 print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1279 }
1280
1281 print "</table>";
1282 print '</div>';
1283
1284 // End of page
1285 llxFooter();
1286}
1287$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()
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)
const TYPE_SITUATION
Situation invoice.
Class to manage suppliers invoices.
const TYPE_DEPOSIT
Deposit invoice.
const TYPE_CREDIT_NOTE
Credit note invoice.
const TYPE_REPLACEMENT
Replacement invoice.
Class to manage generation of HTML components Only common components must be here.
Class to manage suppliers.
Class Lettering.
Class to manage third parties objects (customers, suppliers, prospects...)
getCountriesInEEC()
Return list of countries that are inside the EEC (European Economic Community) Note: Try to keep this...
dol_get_first_day($year, $month=1, $gm=false)
Return GMT time for first day of a month or year.
Definition date.lib.php:595
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:614
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...
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.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
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 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.