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