dolibarr 20.0.0
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
366$sql = "
367SELECT
368 fk_facture_fourn,
369 COUNT(fd.rowid) as nb
370FROM
371 " . MAIN_DB_PREFIX . "facture_fourn_det as fd
372WHERE
373 fd.product_type <= 2
374 AND fd.fk_code_ventilation <= 0
375 AND fd.total_ttc <> 0
376 AND fk_facture_fourn IN (".$db->sanitize(implode(",", array_keys($tabfac))).")
377GROUP BY fk_facture_fourn
378";
379$resql = $db->query($sql);
380
381$num = $db->num_rows($resql);
382$i = 0;
383while ($i < $num) {
384 $obj = $db->fetch_object($resql);
385 if ($obj->nb > 0) {
386 $errorforinvoice[$obj->fk_facture_fourn] = 'somelinesarenotbound';
387 }
388 $i++;
389}
390//var_dump($errorforinvoice);exit;
391
392
393
394// Bookkeeping Write
395if ($action == 'writebookkeeping' && !$error && $user->hasRight('accounting', 'bind', 'write')) {
396 $now = dol_now();
397 $error = 0;
398
399 $companystatic = new Societe($db);
400 $invoicestatic = new FactureFournisseur($db);
401 $accountingaccountsupplier = new AccountingAccount($db);
402
403 $accountingaccountsupplier->fetch(null, getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), true);
404
405 foreach ($tabfac as $key => $val) { // Loop on each invoice
406 $errorforline = 0;
407
408 $totalcredit = 0;
409 $totaldebit = 0;
410
411 $db->begin(); // We accept transaction into loop so if we hang, we can continue transfer from last error
412
413 $companystatic->id = $tabcompany[$key]['id'];
414 $companystatic->name = $tabcompany[$key]['name'];
415 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
416 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
417 $companystatic->fournisseur = 1;
418
419 $invoicestatic->id = $key;
420 $invoicestatic->ref = (string) $val["refsologest"];
421 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
422 $invoicestatic->type = $val["type"];
423 $invoicestatic->description = html_entity_decode(dol_trunc($val["description"], 32));
424 $invoicestatic->close_code = $val["close_code"];
425
426 $date = dol_print_date($val["date"], 'day');
427
428 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
429 $replacedinvoice = 0;
430 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
431 $replacedinvoice = 1;
432 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
433 if ($alreadydispatched) {
434 $replacedinvoice = 2;
435 }
436 }
437
438 // 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)
439 if ($replacedinvoice == 1) {
440 $db->rollback();
441 continue;
442 }
443
444 // Error if some lines are not binded/ready to be journalized
445 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
446 $error++;
447 $errorforline++;
448 setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
449 }
450
451 // Thirdparty
452 if (!$errorforline) {
453 foreach ($tabttc[$key] as $k => $mt) {
454 $bookkeeping = new BookKeeping($db);
455 $bookkeeping->doc_date = $val["date"];
456 $bookkeeping->date_lim_reglement = $val["datereg"];
457 $bookkeeping->doc_ref = $val["refsologest"];
458 $bookkeeping->date_creation = $now;
459 $bookkeeping->doc_type = 'supplier_invoice';
460 $bookkeeping->fk_doc = $key;
461 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
462 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
463
464 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta_fournisseur'];
465 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
466
467 $bookkeeping->numero_compte = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER');
468 $bookkeeping->label_compte = $accountingaccountsupplier->label;
469
470 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("SubledgerAccount");
471 $bookkeeping->montant = $mt;
472 $bookkeeping->sens = ($mt >= 0) ? 'C' : 'D';
473 $bookkeeping->debit = ($mt <= 0) ? -$mt : 0;
474 $bookkeeping->credit = ($mt > 0) ? $mt : 0;
475 $bookkeeping->code_journal = $journal;
476 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
477 $bookkeeping->fk_user_author = $user->id;
478 $bookkeeping->entity = $conf->entity;
479
480 $totaldebit += $bookkeeping->debit;
481 $totalcredit += $bookkeeping->credit;
482
483 $result = $bookkeeping->create($user);
484 if ($result < 0) {
485 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
486 $error++;
487 $errorforline++;
488 $errorforinvoice[$key] = 'alreadyjournalized';
489 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
490 } else {
491 $error++;
492 $errorforline++;
493 $errorforinvoice[$key] = 'other';
494 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
495 }
496 } else {
497 if (getDolGlobalInt('ACCOUNTING_ENABLE_LETTERING') && getDolGlobalInt('ACCOUNTING_ENABLE_AUTOLETTERING')) {
498 require_once DOL_DOCUMENT_ROOT . '/accountancy/class/lettering.class.php';
499 $lettering_static = new Lettering($db);
500
501 $nb_lettering = $lettering_static->bookkeepingLettering(array($bookkeeping->id));
502 }
503 }
504 }
505 }
506
507 // Product / Service
508 if (!$errorforline) {
509 foreach ($tabht[$key] as $k => $mt) {
510 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
511 $accountingaccount = new AccountingAccount($db);
512 $accountingaccount->fetch(0, $k, true);
513 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
514 } else {
515 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
516 }
517
518 $label_account = $accountingaccount->label;
519
520 // get compte id and label
521 if ($accountingaccount->id > 0) {
522 $bookkeeping = new BookKeeping($db);
523 $bookkeeping->doc_date = $val["date"];
524 $bookkeeping->date_lim_reglement = $val["datereg"];
525 $bookkeeping->doc_ref = $val["refsologest"];
526 $bookkeeping->date_creation = $now;
527 $bookkeeping->doc_type = 'supplier_invoice';
528 $bookkeeping->fk_doc = $key;
529 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
530 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
531
532 if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
533 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
534 $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
535 $bookkeeping->subledger_label = $tabcompany[$key]['name'];
536 } else {
537 $bookkeeping->subledger_account = '';
538 $bookkeeping->subledger_label = '';
539 }
540 } else {
541 $bookkeeping->subledger_account = '';
542 $bookkeeping->subledger_label = '';
543 }
544
545 $bookkeeping->numero_compte = $k;
546 $bookkeeping->label_compte = $label_account;
547
548 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$label_account;
549 $bookkeeping->montant = $mt;
550 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
551 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
552 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
553 $bookkeeping->code_journal = $journal;
554 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
555 $bookkeeping->fk_user_author = $user->id;
556 $bookkeeping->entity = $conf->entity;
557
558 $totaldebit += $bookkeeping->debit;
559 $totalcredit += $bookkeeping->credit;
560
561 $result = $bookkeeping->create($user);
562 if ($result < 0) {
563 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
564 $error++;
565 $errorforline++;
566 $errorforinvoice[$key] = 'alreadyjournalized';
567 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
568 } else {
569 $error++;
570 $errorforline++;
571 $errorforinvoice[$key] = 'other';
572 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
573 }
574 }
575 }
576 }
577 }
578
579 // VAT
580 // var_dump($tabtva);
581 if (!$errorforline) {
582 $listoftax = array(0, 1, 2);
583 foreach ($listoftax as $numtax) {
584 $arrayofvat = $tabtva;
585 if ($numtax == 1) {
586 $arrayofvat = $tablocaltax1;
587 }
588 if ($numtax == 2) {
589 $arrayofvat = $tablocaltax2;
590 }
591
592 // VAT Reverse charge
593 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
594 $has_vat = false;
595 foreach ($arrayofvat[$key] as $k => $mt) {
596 if ($mt) {
597 $has_vat = true;
598 }
599 }
600
601 if (!$has_vat) {
602 $arrayofvat = $tabrctva;
603 if ($numtax == 1) {
604 $arrayofvat = $tabrclocaltax1;
605 }
606 if ($numtax == 2) {
607 $arrayofvat = $tabrclocaltax2;
608 }
609 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
610 $arrayofvat[$key] = array();
611 }
612 }
613 }
614
615 foreach ($arrayofvat[$key] as $k => $mt) {
616 if ($mt) {
617 $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
618 $label_account = $accountingaccount->label;
619
620 $bookkeeping = new BookKeeping($db);
621 $bookkeeping->doc_date = $val["date"];
622 $bookkeeping->date_lim_reglement = $val["datereg"];
623 $bookkeeping->doc_ref = $val["refsologest"];
624 $bookkeeping->date_creation = $now;
625 $bookkeeping->doc_type = 'supplier_invoice';
626 $bookkeeping->fk_doc = $key;
627 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
628 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
629
630 $bookkeeping->subledger_account = '';
631 $bookkeeping->subledger_label = '';
632
633 $bookkeeping->numero_compte = $k;
634 $bookkeeping->label_compte = $label_account;
635
636 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
637 $bookkeeping->montant = $mt;
638 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
639 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
640 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
641 $bookkeeping->code_journal = $journal;
642 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
643 $bookkeeping->fk_user_author = $user->id;
644 $bookkeeping->entity = $conf->entity;
645
646 $totaldebit += $bookkeeping->debit;
647 $totalcredit += $bookkeeping->credit;
648
649 $result = $bookkeeping->create($user);
650 if ($result < 0) {
651 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
652 $error++;
653 $errorforline++;
654 $errorforinvoice[$key] = 'alreadyjournalized';
655 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
656 } else {
657 $error++;
658 $errorforline++;
659 $errorforinvoice[$key] = 'other';
660 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
661 }
662 }
663 }
664 }
665 }
666 }
667
668 // Counterpart of VAT for VAT NPR
669 // var_dump($tabother);
670 if (!$errorforline && isset($tabother[$key]) && is_array($tabother[$key])) {
671 foreach ($tabother[$key] as $k => $mt) {
672 if ($mt) {
673 $bookkeeping = new BookKeeping($db);
674 $bookkeeping->doc_date = $val["date"];
675 $bookkeeping->date_lim_reglement = $val["datereg"];
676 $bookkeeping->doc_ref = $val["refsologest"];
677 $bookkeeping->date_creation = $now;
678 $bookkeeping->doc_type = 'supplier_invoice';
679 $bookkeeping->fk_doc = $key;
680 $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
681 $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
682
683 $bookkeeping->subledger_account = '';
684 $bookkeeping->subledger_label = '';
685
686 $bookkeeping->numero_compte = $k;
687
688 $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' NPR';
689 $bookkeeping->montant = $mt;
690 $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
691 $bookkeeping->debit = ($mt > 0) ? $mt : 0;
692 $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
693 $bookkeeping->code_journal = $journal;
694 $bookkeeping->journal_label = $langs->transnoentities($journal_label);
695 $bookkeeping->fk_user_author = $user->id;
696 $bookkeeping->entity = $conf->entity;
697
698 $totaldebit += $bookkeeping->debit;
699 $totalcredit += $bookkeeping->credit;
700
701 $result = $bookkeeping->create($user);
702 if ($result < 0) {
703 if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
704 $error++;
705 $errorforline++;
706 $errorforinvoice[$key] = 'alreadyjournalized';
707 //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
708 } else {
709 $error++;
710 $errorforline++;
711 $errorforinvoice[$key] = 'other';
712 setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
713 }
714 }
715 }
716 }
717 }
718
719 // Protection against a bug on lines before
720 if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
721 $error++;
722 $errorforline++;
723 $errorforinvoice[$key] = 'amountsnotbalanced';
724 setEventMessages('We tried to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors');
725 }
726
727 if (!$errorforline) {
728 $db->commit();
729 } else {
730 $db->rollback();
731
732 if ($error >= 10) {
733 setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
734 break; // Break in the foreach
735 }
736 }
737 }
738
739 $tabpay = $tabfac;
740
741 if (empty($error) && count($tabpay) > 0) {
742 setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
743 } elseif (count($tabpay) == $error) {
744 setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
745 } else {
746 setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
747 }
748
749 $action = '';
750
751 // Must reload data, so we make a redirect
752 if (count($tabpay) != $error) {
753 $param = 'id_journal='.$id_journal;
754 $param .= '&date_startday='.$date_startday;
755 $param .= '&date_startmonth='.$date_startmonth;
756 $param .= '&date_startyear='.$date_startyear;
757 $param .= '&date_endday='.$date_endday;
758 $param .= '&date_endmonth='.$date_endmonth;
759 $param .= '&date_endyear='.$date_endyear;
760 $param .= '&in_bookkeeping='.$in_bookkeeping;
761 header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
762 exit;
763 }
764}
765
766/*
767 * View
768 */
769
770$form = new Form($db);
771
772// Export
773if ($action == 'exportcsv' && !$error) { // ISO and not UTF8 !
774 $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
775
776 $filename = 'journal';
777 $type_export = 'journal';
778 include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
779
780 $companystatic = new Fournisseur($db);
781 $invoicestatic = new FactureFournisseur($db);
782
783 foreach ($tabfac as $key => $val) {
784 $companystatic->id = $tabcompany[$key]['id'];
785 $companystatic->name = $tabcompany[$key]['name'];
786 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
787 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
788 $companystatic->fournisseur = 1;
789
790 $invoicestatic->id = $key;
791 $invoicestatic->ref = $val["refsologest"];
792 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
793 $invoicestatic->type = $val["type"];
794 $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
795 $invoicestatic->close_code = $val["close_code"];
796
797 $date = dol_print_date($val["date"], 'day');
798
799 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
800 $replacedinvoice = 0;
801 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
802 $replacedinvoice = 1;
803 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
804 if ($alreadydispatched) {
805 $replacedinvoice = 2;
806 }
807 }
808
809 // 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)
810 if ($replacedinvoice == 1) {
811 continue;
812 }
813
814 // Third party
815 foreach ($tabttc[$key] as $k => $mt) {
816 //if ($mt) {
817 print '"'.$key.'"'.$sep;
818 print '"'.$date.'"'.$sep;
819 print '"'.$val["refsologest"].'"'.$sep;
820 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
821 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
822 print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER')).'"'.$sep;
823 print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
824 print '"'.$langs->trans("Thirdparty").'"'.$sep;
825 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.$langs->trans("Thirdparty").'"'.$sep;
826 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
827 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
828 print '"'.$journal.'"';
829 print "\n";
830 //}
831 }
832
833 // Product / Service
834 foreach ($tabht[$key] as $k => $mt) {
835 $accountingaccount = new AccountingAccount($db);
836 $accountingaccount->fetch(null, $k, true);
837 //if ($mt) {
838 print '"'.$key.'"'.$sep;
839 print '"'.$date.'"'.$sep;
840 print '"'.$val["refsologest"].'"'.$sep;
841 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
842 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
843 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
844 print '""'.$sep;
845 print '"'.mb_convert_encoding(dol_trunc($accountingaccount->label, 32), 'ISO-8859-1').'"'.$sep;
846 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.dol_trunc($accountingaccount->label, 32).'"'.$sep;
847 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
848 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
849 print '"'.$journal.'"';
850 print "\n";
851 //}
852 }
853
854 // VAT
855 $listoftax = array(0, 1, 2);
856 foreach ($listoftax as $numtax) {
857 $arrayofvat = $tabtva;
858 if ($numtax == 1) {
859 $arrayofvat = $tablocaltax1;
860 }
861 if ($numtax == 2) {
862 $arrayofvat = $tablocaltax2;
863 }
864
865 // VAT Reverse charge
866 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
867 $has_vat = false;
868 foreach ($arrayofvat[$key] as $k => $mt) {
869 if ($mt) {
870 $has_vat = true;
871 }
872 }
873
874 if (!$has_vat) {
875 $arrayofvat = $tabrctva;
876 if ($numtax == 1) {
877 $arrayofvat = $tabrclocaltax1;
878 }
879 if ($numtax == 2) {
880 $arrayofvat = $tabrclocaltax2;
881 }
882 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
883 $arrayofvat[$key] = array();
884 }
885 }
886 }
887
888 foreach ($arrayofvat[$key] as $k => $mt) {
889 if ($mt) {
890 print '"'.$key.'"'.$sep;
891 print '"'.$date.'"'.$sep;
892 print '"'.$val["refsologest"].'"'.$sep;
893 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
894 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
895 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
896 print '""'.$sep;
897 print '"'.$langs->trans("VAT").' - '.implode(', ', $def_tva[$key][$k]).' %"'.$sep;
898 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;
899 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
900 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
901 print '"'.$journal.'"';
902 print "\n";
903 }
904 }
905
906 // VAT counterpart for NPR
907 if (isset($tabother[$key]) && is_array($tabother[$key])) {
908 foreach ($tabother[$key] as $k => $mt) {
909 if ($mt) {
910 print '"'.$key.'"'.$sep;
911 print '"'.$date.'"'.$sep;
912 print '"'.$val["refsologest"].'"'.$sep;
913 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 32), 'ISO-8859-1').'"'.$sep;
914 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
915 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
916 print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
917 print '"'.$langs->trans("Thirdparty").'"'.$sep;
918 print '"'.mb_convert_encoding(dol_trunc($companystatic->name, 16), 'ISO-8859-1').' - '.$val["refsuppliersologest"].' - '.$langs->trans("VAT").' NPR"'.$sep;
919 print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
920 print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
921 print '"'.$journal.'"';
922 print "\n";
923 }
924 }
925 }
926 }
927 }
928}
929
930if (empty($action) || $action == 'view') {
931 $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
932 $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;';
933 llxHeader('', dol_string_nohtmltag($title), $help_url, '', 0, 0, '', '', '', 'mod-accountancy accountancy-generation page-purchasesjournal');
934
935 $nom = $title;
936 $nomlink = '';
937 $periodlink = '';
938 $exportlink = '';
939 $builddate = dol_now();
940 $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
941 if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
942 $description .= $langs->trans("DepositsAreNotIncluded");
943 } else {
944 $description .= $langs->trans("DepositsAreIncluded");
945 }
946
947 $listofchoices = array('notyet' => $langs->trans("NotYetInGeneralLedger"), 'already' => $langs->trans("AlreadyInGeneralLedger"));
948 $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);
949 $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
950
951 $varlink = 'id_journal='.$id_journal;
952
953 journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
954
955 if (getDolGlobalString('ACCOUNTANCY_FISCAL_PERIOD_MODE') != 'blockedonclosed') {
956 // Test that setup is complete (we are in accounting, so test on entity is always on $conf->entity only, no sharing allowed)
957 // Fiscal period test
958 $sql = "SELECT COUNT(rowid) as nb FROM ".MAIN_DB_PREFIX."accounting_fiscalyear WHERE entity = ".((int) $conf->entity);
959 $resql = $db->query($sql);
960 if ($resql) {
961 $obj = $db->fetch_object($resql);
962 if ($obj->nb == 0) {
963 print '<br><div class="warning">'.img_warning().' '.$langs->trans("TheFiscalPeriodIsNotDefined");
964 $desc = ' : '.$langs->trans("AccountancyAreaDescFiscalPeriod", 4, '{link}');
965 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("FiscalPeriod").'</strong>', $desc);
966 print $desc;
967 print '</div>';
968 }
969 } else {
970 dol_print_error($db);
971 }
972 }
973
974 // Button to write into Ledger
975 $acctSupplierNotConfigured = in_array(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), ['','-1']);
976 if ($acctSupplierNotConfigured) {
977 print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
978 $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
979 $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
980 print $desc;
981 print '</div>';
982 }
983 print '<br><div class="tabsAction tabsActionNoBottom centerimp">';
984 if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
985 print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
986 }
987 if ($acctSupplierNotConfigured) {
988 print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
989 } else {
990 if ($in_bookkeeping == 'notyet') {
991 print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
992 } else {
993 print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
994 }
995 }
996 print '</div>';
997
998 // TODO Avoid using js. We can use a direct link with $param
999 print '
1000 <script type="text/javascript">
1001 function launch_export() {
1002 $("div.fiche form input[name=\"action\"]").val("exportcsv");
1003 $("div.fiche form input[type=\"submit\"]").click();
1004 $("div.fiche form input[name=\"action\"]").val("");
1005 }
1006 function writebookkeeping() {
1007 console.log("click on writebookkeeping");
1008 $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
1009 $("div.fiche form input[type=\"submit\"]").click();
1010 $("div.fiche form input[name=\"action\"]").val("");
1011 }
1012 </script>';
1013
1014 /*
1015 * Show result array
1016 */
1017 print '<br>';
1018
1019 print '<div class="div-table-responsive">';
1020 print "<table class=\"noborder\" width=\"100%\">";
1021 print "<tr class=\"liste_titre\">";
1022 print "<td>".$langs->trans("Date")."</td>";
1023 print "<td>".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")</td>";
1024 print "<td>".$langs->trans("AccountAccounting")."</td>";
1025 print "<td>".$langs->trans("SubledgerAccount")."</td>";
1026 print "<td>".$langs->trans("LabelOperation")."</td>";
1027 print '<td class="center">'.$langs->trans("AccountingDebit")."</td>";
1028 print '<td class="center">'.$langs->trans("AccountingCredit")."</td>";
1029 print "</tr>\n";
1030
1031 $i = 0;
1032
1033 $invoicestatic = new FactureFournisseur($db);
1034 $companystatic = new Fournisseur($db);
1035
1036 foreach ($tabfac as $key => $val) {
1037 $companystatic->id = $tabcompany[$key]['id'];
1038 $companystatic->name = $tabcompany[$key]['name'];
1039 $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
1040 $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
1041 $companystatic->fournisseur = 1;
1042
1043 $invoicestatic->id = $key;
1044 $invoicestatic->ref = $val["refsologest"];
1045 $invoicestatic->ref_supplier = $val["refsuppliersologest"];
1046 $invoicestatic->type = $val["type"];
1047 $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
1048 $invoicestatic->close_code = $val["close_code"];
1049
1050 $date = dol_print_date($val["date"], 'day');
1051
1052 // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
1053 $replacedinvoice = 0;
1054 if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
1055 $replacedinvoice = 1;
1056 $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
1057 if ($alreadydispatched) {
1058 $replacedinvoice = 2;
1059 }
1060 }
1061
1062 // If not already into bookkeeping, we won't add it, if yes, add the counterpart ???.
1063 if ($replacedinvoice == 1) {
1064 print '<tr class="oddeven">';
1065 print "<!-- Replaced invoice -->";
1066 print "<td>".$date."</td>";
1067 print "<td><strike>".$invoicestatic->getNomUrl(1)."</strike></td>";
1068 // Account
1069 print "<td>";
1070 print $langs->trans("Replaced");
1071 print '</td>';
1072 // Subledger account
1073 print "<td>";
1074 print '</td>';
1075 print "<td>";
1076 print "</td>";
1077 print '<td class="right"></td>';
1078 print '<td class="right"></td>';
1079 print "</tr>";
1080
1081 $i++;
1082 continue;
1083 }
1084 if (isset($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
1085 print '<tr class="oddeven">';
1086 print "<!-- Some lines are not bound -->";
1087 print "<td>".$date."</td>";
1088 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1089 // Account
1090 print "<td>";
1091 print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
1092 print '</td>';
1093 // Subledger account
1094 print "<td>";
1095 print '</td>';
1096 print "<td>";
1097 print "</td>";
1098 print '<td class="right"></td>';
1099 print '<td class="right"></td>';
1100 print "</tr>";
1101
1102 $i++;
1103 }
1104
1105 // Third party
1106 foreach ($tabttc[$key] as $k => $mt) {
1107 print '<tr class="oddeven">';
1108 print "<!-- Thirdparty -->";
1109 print "<td>".$date."</td>";
1110 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1111 // Account
1112 print "<td>";
1113 $accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'));
1114 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1115 print '<span class="error">'.$langs->trans("MainAccountForSuppliersNotDefined").'</span>';
1116 } else {
1117 print $accountoshow;
1118 }
1119 print '</td>';
1120 // Subledger account
1121 print "<td>";
1122 $accountoshow = length_accounta($k);
1123 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1124 print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
1125 } else {
1126 print $accountoshow;
1127 }
1128 print '</td>';
1129 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("SubledgerAccount")."</td>";
1130 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1131 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1132 print "</tr>";
1133
1134 $i++;
1135 }
1136
1137 // Product / Service
1138 foreach ($tabht[$key] as $k => $mt) {
1139 if (empty($conf->cache['accountingaccountincurrententity'][$k])) {
1140 $accountingaccount = new AccountingAccount($db);
1141 $accountingaccount->fetch(0, $k, true);
1142 $conf->cache['accountingaccountincurrententity'][$k] = $accountingaccount;
1143 } else {
1144 $accountingaccount = $conf->cache['accountingaccountincurrententity'][$k];
1145 }
1146
1147 print '<tr class="oddeven">';
1148 print "<!-- Product -->";
1149 print "<td>".$date."</td>";
1150 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1151 // Account
1152 print "<td>";
1153 $accountoshow = length_accountg($k);
1154 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1155 print '<span class="error">'.$langs->trans("ProductAccountNotDefined").'</span>';
1156 } else {
1157 print $accountoshow;
1158 }
1159 print "</td>";
1160 // Subledger account
1161 print "<td>";
1162 if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
1163 if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
1164 print length_accounta($tabcompany[$key]['code_compta']);
1165 }
1166 } elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
1167 print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
1168 }
1169 print '</td>';
1170 $companystatic->id = $tabcompany[$key]['id'];
1171 $companystatic->name = $tabcompany[$key]['name'];
1172 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$accountingaccount->label."</td>";
1173 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1174 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1175 print "</tr>";
1176
1177 $i++;
1178 }
1179
1180 // VAT
1181 $listoftax = array(0, 1, 2);
1182 foreach ($listoftax as $numtax) {
1183 $arrayofvat = $tabtva;
1184 if ($numtax == 1) {
1185 $arrayofvat = $tablocaltax1;
1186 }
1187 if ($numtax == 2) {
1188 $arrayofvat = $tablocaltax2;
1189 }
1190
1191 // VAT Reverse charge
1192 if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
1193 $has_vat = false;
1194 foreach ($arrayofvat[$key] as $k => $mt) {
1195 if ($mt) {
1196 $has_vat = true;
1197 }
1198 }
1199
1200 if (!$has_vat) {
1201 $arrayofvat = $tabrctva;
1202 if ($numtax == 1) {
1203 $arrayofvat = $tabrclocaltax1;
1204 }
1205 if ($numtax == 2) {
1206 $arrayofvat = $tabrclocaltax2;
1207 }
1208 if (!isset($arrayofvat[$key]) || !is_array($arrayofvat[$key])) {
1209 $arrayofvat[$key] = array();
1210 }
1211 }
1212 }
1213
1214 foreach ($arrayofvat[$key] as $k => $mt) {
1215 if ($mt) {
1216 print '<tr class="oddeven">';
1217 print "<!-- VAT -->";
1218 print "<td>".$date."</td>";
1219 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1220 // Account
1221 print "<td>";
1222 $accountoshow = length_accountg($k);
1223 if (($accountoshow == "") || $accountoshow == 'NotDefined') {
1224 print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("AccountingJournalType3").')</span>';
1225 } else {
1226 print $accountoshow;
1227 }
1228 print "</td>";
1229 // Subledger account
1230 print "<td>";
1231 print '</td>';
1232 print "<td>";
1233 print $companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.implode(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
1234 print "</td>";
1235 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1236 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1237 print "</tr>";
1238
1239 $i++;
1240 }
1241 }
1242 }
1243
1244 // VAT counterpart for NPR
1245 if (isset($tabother[$key]) && is_array($tabother[$key])) {
1246 foreach ($tabother[$key] as $k => $mt) {
1247 if ($mt) {
1248 print '<tr class="oddeven">';
1249 print '<!-- VAT counterpart NPR -->';
1250 print "<td>".$date."</td>";
1251 print "<td>".$invoicestatic->getNomUrl(1)."</td>";
1252 // Account
1253 print '<td>';
1254 $accountoshow = length_accountg($k);
1255 if ($accountoshow == '' || $accountoshow == 'NotDefined') {
1256 print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account</span>';
1257 } else {
1258 print $accountoshow;
1259 }
1260 print '</td>';
1261 // Subledger account
1262 print "<td>";
1263 print '</td>';
1264 print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT")." NPR (counterpart)</td>";
1265 print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
1266 print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
1267 print "</tr>";
1268
1269 $i++;
1270 }
1271 }
1272 }
1273 }
1274
1275 if (!$i) {
1276 print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
1277 }
1278
1279 print "</table>";
1280 print '</div>';
1281
1282 // End of page
1283 llxFooter();
1284}
1285$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.