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