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