purchasesjournal.php 47 KB

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