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