dolibarr 18.0.6
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
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
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
93if (empty($date_startmonth) || empty($date_endmonth)) {
94 // Period by default on transfer
96 $date_start = $dates['date_start'];
97 $date_end = $dates['date_end'];
98 $pastmonthyear = $dates['pastmonthyear'];
99 $pastmonth = $dates['pastmonth'];
100}
101
102if (!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,";
112if (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}
119if (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";
127if (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 ";
134if (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
140if (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}
145if ($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
149if (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
150 $sql .= " AND f.datef >= '".$db->idate(getDolGlobalString('ACCOUNTING_DATE_START_BINDING'))."'";
151}
152// Already in bookkeeping or not
153if ($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}
156if ($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
161dol_syslog('accountancy/journal/purchasesjournal.php', LOG_DEBUG);
162$result = $db->query($sql);
163if ($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
315foreach ($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
335if ($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('We tried 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
706if ($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
863if (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("AccountingJournalType3").')</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 accounts.
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:577
dol_get_last_day($year, $month=12, $gm=false)
Return GMT time for last day of a month or year.
Definition date.lib.php:596
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.
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.