purchasesjournal.php 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  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 (!$user->hasRight('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('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 (getDolGlobalString('ACCOUNTING_DATE_START_BINDING')) {
  134. $sql .= " AND f.datef >= '".$db->idate(getDolGlobalString('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 = getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER', 'NotDefined');
  162. $cpttva = getDolGlobalString('ACCOUNTING_VAT_BUY_ACCOUNT', 'NotDefined');
  163. $rcctva = getDolGlobalString('ACCOUNTING_VAT_BUY_REVERSE_CHARGES_CREDIT', 'NotDefined');
  164. $rcdtva = getDolGlobalString('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 = getDolGlobalString('ACCOUNTING_PRODUCT_BUY_ACCOUNT', 'NotDefined');
  175. } else {
  176. $compta_prod = getDolGlobalString('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 = getDolGlobalString('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' || getDolGlobalString('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, getDolGlobalString('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 = getDolGlobalString('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. }
  387. }
  388. }
  389. }
  390. // Product / Service
  391. if (!$errorforline) {
  392. foreach ($tabht[$key] as $k => $mt) {
  393. $resultfetch = $accountingaccount->fetch(null, $k, true); // TODO Use a cache
  394. $label_account = $accountingaccount->label;
  395. // get compte id and label
  396. if ($resultfetch > 0) {
  397. $bookkeeping = new BookKeeping($db);
  398. $bookkeeping->doc_date = $val["date"];
  399. $bookkeeping->date_lim_reglement = $val["datereg"];
  400. $bookkeeping->doc_ref = $val["refsologest"];
  401. $bookkeeping->date_creation = $now;
  402. $bookkeeping->doc_type = 'supplier_invoice';
  403. $bookkeeping->fk_doc = $key;
  404. $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
  405. $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
  406. if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
  407. if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
  408. $bookkeeping->subledger_account = $tabcompany[$key]['code_compta'];
  409. $bookkeeping->subledger_label = $tabcompany[$key]['name'];
  410. } else {
  411. $bookkeeping->subledger_account = '';
  412. $bookkeeping->subledger_label = '';
  413. }
  414. } else {
  415. $bookkeeping->subledger_account = '';
  416. $bookkeeping->subledger_label = '';
  417. }
  418. $bookkeeping->numero_compte = $k;
  419. $bookkeeping->label_compte = $label_account;
  420. $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$label_account;
  421. $bookkeeping->montant = $mt;
  422. $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
  423. $bookkeeping->debit = ($mt > 0) ? $mt : 0;
  424. $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
  425. $bookkeeping->code_journal = $journal;
  426. $bookkeeping->journal_label = $langs->transnoentities($journal_label);
  427. $bookkeeping->fk_user_author = $user->id;
  428. $bookkeeping->entity = $conf->entity;
  429. $totaldebit += $bookkeeping->debit;
  430. $totalcredit += $bookkeeping->credit;
  431. $result = $bookkeeping->create($user);
  432. if ($result < 0) {
  433. if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
  434. $error++;
  435. $errorforline++;
  436. $errorforinvoice[$key] = 'alreadyjournalized';
  437. //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
  438. } else {
  439. $error++;
  440. $errorforline++;
  441. $errorforinvoice[$key] = 'other';
  442. setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
  443. }
  444. }
  445. }
  446. }
  447. }
  448. // VAT
  449. // var_dump($tabtva);
  450. if (!$errorforline) {
  451. $listoftax = array(0, 1, 2);
  452. foreach ($listoftax as $numtax) {
  453. $arrayofvat = $tabtva;
  454. if ($numtax == 1) {
  455. $arrayofvat = $tablocaltax1;
  456. }
  457. if ($numtax == 2) {
  458. $arrayofvat = $tablocaltax2;
  459. }
  460. // VAT Reverse charge
  461. if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
  462. $has_vat = false;
  463. foreach ($arrayofvat[$key] as $k => $mt) {
  464. if ($mt) {
  465. $has_vat = true;
  466. }
  467. }
  468. if (!$has_vat) {
  469. $arrayofvat = $tabrctva;
  470. if ($numtax == 1) {
  471. $arrayofvat = $tabrclocaltax1;
  472. }
  473. if ($numtax == 2) {
  474. $arrayofvat = $tabrclocaltax2;
  475. }
  476. if (!is_array($arrayofvat[$key])) {
  477. $arrayofvat[$key] = array();
  478. }
  479. }
  480. }
  481. foreach ($arrayofvat[$key] as $k => $mt) {
  482. if ($mt) {
  483. $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
  484. $label_account = $accountingaccount->label;
  485. $bookkeeping = new BookKeeping($db);
  486. $bookkeeping->doc_date = $val["date"];
  487. $bookkeeping->date_lim_reglement = $val["datereg"];
  488. $bookkeeping->doc_ref = $val["refsologest"];
  489. $bookkeeping->date_creation = $now;
  490. $bookkeeping->doc_type = 'supplier_invoice';
  491. $bookkeeping->fk_doc = $key;
  492. $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
  493. $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
  494. $bookkeeping->subledger_account = '';
  495. $bookkeeping->subledger_label = '';
  496. $bookkeeping->numero_compte = $k;
  497. $bookkeeping->label_compte = $label_account;
  498. $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
  499. $bookkeeping->montant = $mt;
  500. $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
  501. $bookkeeping->debit = ($mt > 0) ? $mt : 0;
  502. $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
  503. $bookkeeping->code_journal = $journal;
  504. $bookkeeping->journal_label = $langs->transnoentities($journal_label);
  505. $bookkeeping->fk_user_author = $user->id;
  506. $bookkeeping->entity = $conf->entity;
  507. $totaldebit += $bookkeeping->debit;
  508. $totalcredit += $bookkeeping->credit;
  509. $result = $bookkeeping->create($user);
  510. if ($result < 0) {
  511. if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
  512. $error++;
  513. $errorforline++;
  514. $errorforinvoice[$key] = 'alreadyjournalized';
  515. //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
  516. } else {
  517. $error++;
  518. $errorforline++;
  519. $errorforinvoice[$key] = 'other';
  520. setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
  521. }
  522. }
  523. }
  524. }
  525. }
  526. }
  527. // Counterpart of VAT for VAT NPR
  528. // var_dump($tabother);
  529. if (!$errorforline && is_array($tabother[$key])) {
  530. foreach ($tabother[$key] as $k => $mt) {
  531. if ($mt) {
  532. $bookkeeping = new BookKeeping($db);
  533. $bookkeeping->doc_date = $val["date"];
  534. $bookkeeping->date_lim_reglement = $val["datereg"];
  535. $bookkeeping->doc_ref = $val["refsologest"];
  536. $bookkeeping->date_creation = $now;
  537. $bookkeeping->doc_type = 'supplier_invoice';
  538. $bookkeeping->fk_doc = $key;
  539. $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
  540. $bookkeeping->thirdparty_code = $companystatic->code_fournisseur;
  541. $bookkeeping->subledger_account = '';
  542. $bookkeeping->subledger_label = '';
  543. $bookkeeping->numero_compte = $k;
  544. $bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' NPR';
  545. $bookkeeping->montant = $mt;
  546. $bookkeeping->sens = ($mt < 0) ? 'C' : 'D';
  547. $bookkeeping->debit = ($mt > 0) ? $mt : 0;
  548. $bookkeeping->credit = ($mt <= 0) ? -$mt : 0;
  549. $bookkeeping->code_journal = $journal;
  550. $bookkeeping->journal_label = $langs->transnoentities($journal_label);
  551. $bookkeeping->fk_user_author = $user->id;
  552. $bookkeeping->entity = $conf->entity;
  553. $totaldebit += $bookkeeping->debit;
  554. $totalcredit += $bookkeeping->credit;
  555. $result = $bookkeeping->create($user);
  556. if ($result < 0) {
  557. if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
  558. $error++;
  559. $errorforline++;
  560. $errorforinvoice[$key] = 'alreadyjournalized';
  561. //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
  562. } else {
  563. $error++;
  564. $errorforline++;
  565. $errorforinvoice[$key] = 'other';
  566. setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
  567. }
  568. }
  569. }
  570. }
  571. }
  572. // Protection against a bug on lines before
  573. if (!$errorforline && (price2num($totaldebit, 'MT') != price2num($totalcredit, 'MT'))) {
  574. $error++;
  575. $errorforline++;
  576. $errorforinvoice[$key] = 'amountsnotbalanced';
  577. setEventMessages('Try to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors');
  578. }
  579. if (!$errorforline) {
  580. $db->commit();
  581. } else {
  582. $db->rollback();
  583. if ($error >= 10) {
  584. setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped"), null, 'errors');
  585. break; // Break in the foreach
  586. }
  587. }
  588. }
  589. $tabpay = $tabfac;
  590. if (empty($error) && count($tabpay) > 0) {
  591. setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs');
  592. } elseif (count($tabpay) == $error) {
  593. setEventMessages($langs->trans("NoNewRecordSaved"), null, 'warnings');
  594. } else {
  595. setEventMessages($langs->trans("GeneralLedgerSomeRecordWasNotRecorded"), null, 'warnings');
  596. }
  597. $action = '';
  598. // Must reload data, so we make a redirect
  599. if (count($tabpay) != $error) {
  600. $param = 'id_journal='.$id_journal;
  601. $param .= '&date_startday='.$date_startday;
  602. $param .= '&date_startmonth='.$date_startmonth;
  603. $param .= '&date_startyear='.$date_startyear;
  604. $param .= '&date_endday='.$date_endday;
  605. $param .= '&date_endmonth='.$date_endmonth;
  606. $param .= '&date_endyear='.$date_endyear;
  607. $param .= '&in_bookkeeping='.$in_bookkeeping;
  608. header("Location: ".$_SERVER['PHP_SELF'].($param ? '?'.$param : ''));
  609. exit;
  610. }
  611. }
  612. /*
  613. * View
  614. */
  615. $form = new Form($db);
  616. // Export
  617. if ($action == 'exportcsv') { // ISO and not UTF8 !
  618. $sep = getDolGlobalString('ACCOUNTING_EXPORT_SEPARATORCSV');
  619. $filename = 'journal';
  620. $type_export = 'journal';
  621. include DOL_DOCUMENT_ROOT.'/accountancy/tpl/export_journal.tpl.php';
  622. $companystatic = new Fournisseur($db);
  623. $invoicestatic = new FactureFournisseur($db);
  624. foreach ($tabfac as $key => $val) {
  625. $companystatic->id = $tabcompany[$key]['id'];
  626. $companystatic->name = $tabcompany[$key]['name'];
  627. $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
  628. $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
  629. $companystatic->fournisseur = 1;
  630. $invoicestatic->id = $key;
  631. $invoicestatic->ref = $val["refsologest"];
  632. $invoicestatic->ref_supplier = $val["refsuppliersologest"];
  633. $invoicestatic->type = $val["type"];
  634. $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
  635. $invoicestatic->close_code = $val["close_code"];
  636. $date = dol_print_date($val["date"], 'day');
  637. // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
  638. $replacedinvoice = 0;
  639. if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
  640. $replacedinvoice = 1;
  641. $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
  642. if ($alreadydispatched) {
  643. $replacedinvoice = 2;
  644. }
  645. }
  646. // 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)
  647. if ($replacedinvoice == 1) {
  648. continue;
  649. }
  650. // Third party
  651. foreach ($tabttc[$key] as $k => $mt) {
  652. //if ($mt) {
  653. print '"'.$key.'"'.$sep;
  654. print '"'.$date.'"'.$sep;
  655. print '"'.$val["refsologest"].'"'.$sep;
  656. print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
  657. print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
  658. print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER')).'"'.$sep;
  659. print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
  660. print '"'.$langs->trans("Thirdparty").'"'.$sep;
  661. print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$val["refsuppliersologest"].' - '.$langs->trans("Thirdparty").'"'.$sep;
  662. print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
  663. print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
  664. print '"'.$journal.'"';
  665. print "\n";
  666. //}
  667. }
  668. // Product / Service
  669. foreach ($tabht[$key] as $k => $mt) {
  670. $accountingaccount = new AccountingAccount($db);
  671. $accountingaccount->fetch(null, $k, true);
  672. //if ($mt) {
  673. print '"'.$key.'"'.$sep;
  674. print '"'.$date.'"'.$sep;
  675. print '"'.$val["refsologest"].'"'.$sep;
  676. print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
  677. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  678. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  679. print '""'.$sep;
  680. print '"'.utf8_decode(dol_trunc($accountingaccount->label, 32)).'"'.$sep;
  681. print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$val["refsuppliersologest"].' - '.dol_trunc($accountingaccount->label, 32).'"'.$sep;
  682. print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
  683. print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
  684. print '"'.$journal.'"';
  685. print "\n";
  686. //}
  687. }
  688. // VAT
  689. $listoftax = array(0, 1, 2);
  690. foreach ($listoftax as $numtax) {
  691. $arrayofvat = $tabtva;
  692. if ($numtax == 1) {
  693. $arrayofvat = $tablocaltax1;
  694. }
  695. if ($numtax == 2) {
  696. $arrayofvat = $tablocaltax2;
  697. }
  698. // VAT Reverse charge
  699. if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
  700. $has_vat = false;
  701. foreach ($arrayofvat[$key] as $k => $mt) {
  702. if ($mt) {
  703. $has_vat = true;
  704. }
  705. }
  706. if (!$has_vat) {
  707. $arrayofvat = $tabrctva;
  708. if ($numtax == 1) {
  709. $arrayofvat = $tabrclocaltax1;
  710. }
  711. if ($numtax == 2) {
  712. $arrayofvat = $tabrclocaltax2;
  713. }
  714. if (!is_array($arrayofvat[$key])) {
  715. $arrayofvat[$key] = array();
  716. }
  717. }
  718. }
  719. foreach ($arrayofvat[$key] as $k => $mt) {
  720. if ($mt) {
  721. print '"'.$key.'"'.$sep;
  722. print '"'.$date.'"'.$sep;
  723. print '"'.$val["refsologest"].'"'.$sep;
  724. print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
  725. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  726. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  727. print '""'.$sep;
  728. print '"'.$langs->trans("VAT").' - '.join(', ', $def_tva[$key][$k]).' %"'.$sep;
  729. print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$val["refsuppliersologest"].' - '.$langs->trans("VAT").join(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '').'"'.$sep;
  730. print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
  731. print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
  732. print '"'.$journal.'"';
  733. print "\n";
  734. }
  735. }
  736. // VAT counterpart for NPR
  737. if (is_array($tabother[$key])) {
  738. foreach ($tabother[$key] as $k => $mt) {
  739. if ($mt) {
  740. print '"'.$key.'"'.$sep;
  741. print '"'.$date.'"'.$sep;
  742. print '"'.$val["refsologest"].'"'.$sep;
  743. print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
  744. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  745. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  746. print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
  747. print '"'.$langs->trans("Thirdparty").'"'.$sep;
  748. print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$val["refsuppliersologest"].' - '.$langs->trans("VAT").' NPR"'.$sep;
  749. print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
  750. print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
  751. print '"'.$journal.'"';
  752. print "\n";
  753. }
  754. }
  755. }
  756. }
  757. }
  758. }
  759. if (empty($action) || $action == 'view') {
  760. $title = $langs->trans("GenerationOfAccountingEntries").' - '.$accountingjournalstatic->getNomUrl(0, 2, 1, '', 1);
  761. llxHeader('', dol_string_nohtmltag($title));
  762. $nom = $title;
  763. $nomlink = '';
  764. $periodlink = '';
  765. $exportlink = '';
  766. $builddate = dol_now();
  767. $description = $langs->trans("DescJournalOnlyBindedVisible").'<br>';
  768. if (getDolGlobalString('FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS')) {
  769. $description .= $langs->trans("DepositsAreNotIncluded");
  770. } else {
  771. $description .= $langs->trans("DepositsAreIncluded");
  772. }
  773. $listofchoices = array('notyet'=>$langs->trans("NotYetInGeneralLedger"), 'already'=>$langs->trans("AlreadyInGeneralLedger"));
  774. $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);
  775. $period .= ' - '.$langs->trans("JournalizationInLedgerStatus").' '.$form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1);
  776. $varlink = 'id_journal='.$id_journal;
  777. journalHead($nom, $nomlink, $period, $periodlink, $description, $builddate, $exportlink, array('action' => ''), '', $varlink);
  778. // Button to write into Ledger
  779. $acctSupplierNotConfigured = in_array(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'), ['','-1']);
  780. if ($acctSupplierNotConfigured) {
  781. print '<br><div class="warning">'.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone");
  782. $desc = ' : '.$langs->trans("AccountancyAreaDescMisc", 4, '{link}');
  783. $desc = str_replace('{link}', '<strong>'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").'</strong>', $desc);
  784. print $desc;
  785. print '</div>';
  786. }
  787. print '<div class="tabsAction tabsActionNoBottom centerimp">';
  788. if (getDolGlobalString('ACCOUNTING_ENABLE_EXPORT_DRAFT_JOURNAL') && $in_bookkeeping == 'notyet') {
  789. print '<input type="button" class="butAction" name="exportcsv" value="'.$langs->trans("ExportDraftJournal").'" onclick="launch_export();" />';
  790. }
  791. if ($acctSupplierNotConfigured) {
  792. print '<input type="button" class="butActionRefused classfortooltip" title="'.dol_escape_htmltag($langs->trans("SomeMandatoryStepsOfSetupWereNotDone")).'" value="'.$langs->trans("WriteBookKeeping").'" />';
  793. } else {
  794. if ($in_bookkeeping == 'notyet') {
  795. print '<input type="button" class="butAction" name="writebookkeeping" value="'.$langs->trans("WriteBookKeeping").'" onclick="writebookkeeping();" />';
  796. } else {
  797. print '<a href="#" class="butActionRefused classfortooltip" name="writebookkeeping">'.$langs->trans("WriteBookKeeping").'</a>';
  798. }
  799. }
  800. print '</div>';
  801. // TODO Avoid using js. We can use a direct link with $param
  802. print '
  803. <script type="text/javascript">
  804. function launch_export() {
  805. $("div.fiche form input[name=\"action\"]").val("exportcsv");
  806. $("div.fiche form input[type=\"submit\"]").click();
  807. $("div.fiche form input[name=\"action\"]").val("");
  808. }
  809. function writebookkeeping() {
  810. console.log("click on writebookkeeping");
  811. $("div.fiche form input[name=\"action\"]").val("writebookkeeping");
  812. $("div.fiche form input[type=\"submit\"]").click();
  813. $("div.fiche form input[name=\"action\"]").val("");
  814. }
  815. </script>';
  816. /*
  817. * Show result array
  818. */
  819. print '<br>';
  820. print '<div class="div-table-responsive">';
  821. print "<table class=\"noborder\" width=\"100%\">";
  822. print "<tr class=\"liste_titre\">";
  823. print "<td>".$langs->trans("Date")."</td>";
  824. print "<td>".$langs->trans("Piece").' ('.$langs->trans("InvoiceRef").")</td>";
  825. print "<td>".$langs->trans("AccountAccounting")."</td>";
  826. print "<td>".$langs->trans("SubledgerAccount")."</td>";
  827. print "<td>".$langs->trans("LabelOperation")."</td>";
  828. print '<td class="center">'.$langs->trans("AccountingDebit")."</td>";
  829. print '<td class="center">'.$langs->trans("AccountingCredit")."</td>";
  830. print "</tr>\n";
  831. $i = 0;
  832. $invoicestatic = new FactureFournisseur($db);
  833. $companystatic = new Fournisseur($db);
  834. foreach ($tabfac as $key => $val) {
  835. $companystatic->id = $tabcompany[$key]['id'];
  836. $companystatic->name = $tabcompany[$key]['name'];
  837. $companystatic->code_compta_fournisseur = $tabcompany[$key]['code_compta_fournisseur'];
  838. $companystatic->code_fournisseur = $tabcompany[$key]['code_fournisseur'];
  839. $companystatic->fournisseur = 1;
  840. $invoicestatic->id = $key;
  841. $invoicestatic->ref = $val["refsologest"];
  842. $invoicestatic->ref_supplier = $val["refsuppliersologest"];
  843. $invoicestatic->type = $val["type"];
  844. $invoicestatic->description = dol_trunc(html_entity_decode($val["description"]), 32);
  845. $invoicestatic->close_code = $val["close_code"];
  846. $date = dol_print_date($val["date"], 'day');
  847. // Is it a replaced invoice ? 0=not a replaced invoice, 1=replaced invoice not yet dispatched, 2=replaced invoice dispatched
  848. $replacedinvoice = 0;
  849. if ($invoicestatic->close_code == FactureFournisseur::CLOSECODE_REPLACED) {
  850. $replacedinvoice = 1;
  851. $alreadydispatched = $invoicestatic->getVentilExportCompta(); // Test if replaced invoice already into bookkeeping.
  852. if ($alreadydispatched) {
  853. $replacedinvoice = 2;
  854. }
  855. }
  856. // If not already into bookkeeping, we won't add it, if yes, add the counterpart ???.
  857. if ($replacedinvoice == 1) {
  858. print '<tr class="oddeven">';
  859. print "<!-- Replaced invoice -->";
  860. print "<td>".$date."</td>";
  861. print "<td><strike>".$invoicestatic->getNomUrl(1)."</strike></td>";
  862. // Account
  863. print "<td>";
  864. print $langs->trans("Replaced");
  865. print '</td>';
  866. // Subledger account
  867. print "<td>";
  868. print '</td>';
  869. print "<td>";
  870. print "</td>";
  871. print '<td class="right"></td>';
  872. print '<td class="right"></td>';
  873. print "</tr>";
  874. $i++;
  875. continue;
  876. }
  877. if ($errorforinvoice[$key] == 'somelinesarenotbound') {
  878. print '<tr class="oddeven">';
  879. print "<!-- Some lines are not bound -->";
  880. print "<td>".$date."</td>";
  881. print "<td>".$invoicestatic->getNomUrl(1)."</td>";
  882. // Account
  883. print "<td>";
  884. print '<span class="error">'.$langs->trans('ErrorInvoiceContainsLinesNotYetBoundedShort', $val['ref']).'</span>';
  885. print '</td>';
  886. // Subledger account
  887. print "<td>";
  888. print '</td>';
  889. print "<td>";
  890. print "</td>";
  891. print '<td class="right"></td>';
  892. print '<td class="right"></td>';
  893. print "</tr>";
  894. $i++;
  895. }
  896. // Third party
  897. foreach ($tabttc[$key] as $k => $mt) {
  898. print '<tr class="oddeven">';
  899. print "<!-- Thirdparty -->";
  900. print "<td>".$date."</td>";
  901. print "<td>".$invoicestatic->getNomUrl(1)."</td>";
  902. // Account
  903. print "<td>";
  904. $accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER'));
  905. if (($accountoshow == "") || $accountoshow == 'NotDefined') {
  906. print '<span class="error">'.$langs->trans("MainAccountForSuppliersNotDefined").'</span>';
  907. } else {
  908. print $accountoshow;
  909. }
  910. print '</td>';
  911. // Subledger account
  912. print "<td>";
  913. $accountoshow = length_accounta($k);
  914. if (($accountoshow == "") || $accountoshow == 'NotDefined') {
  915. print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
  916. } else {
  917. print $accountoshow;
  918. }
  919. print '</td>';
  920. print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("SubledgerAccount")."</td>";
  921. print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
  922. print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
  923. print "</tr>";
  924. $i++;
  925. }
  926. // Product / Service
  927. foreach ($tabht[$key] as $k => $mt) {
  928. $accountingaccount = new AccountingAccount($db);
  929. $accountingaccount->fetch(null, $k, true);
  930. print '<tr class="oddeven">';
  931. print "<!-- Product -->";
  932. print "<td>".$date."</td>";
  933. print "<td>".$invoicestatic->getNomUrl(1)."</td>";
  934. // Account
  935. print "<td>";
  936. $accountoshow = length_accountg($k);
  937. if (($accountoshow == "") || $accountoshow == 'NotDefined') {
  938. print '<span class="error">'.$langs->trans("ProductAccountNotDefined").'</span>';
  939. } else {
  940. print $accountoshow;
  941. }
  942. print "</td>";
  943. // Subledger account
  944. print "<td>";
  945. if (getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_USE_AUXILIARY_ON_DEPOSIT')) {
  946. if ($k == getDolGlobalString('ACCOUNTING_ACCOUNT_SUPPLIER_DEPOSIT')) {
  947. print length_accounta($tabcompany[$key]['code_compta']);
  948. }
  949. } elseif (($accountoshow == "") || $accountoshow == 'NotDefined') {
  950. print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
  951. }
  952. print '</td>';
  953. $companystatic->id = $tabcompany[$key]['id'];
  954. $companystatic->name = $tabcompany[$key]['name'];
  955. print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$accountingaccount->label."</td>";
  956. print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
  957. print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
  958. print "</tr>";
  959. $i++;
  960. }
  961. // VAT
  962. $listoftax = array(0, 1, 2);
  963. foreach ($listoftax as $numtax) {
  964. $arrayofvat = $tabtva;
  965. if ($numtax == 1) {
  966. $arrayofvat = $tablocaltax1;
  967. }
  968. if ($numtax == 2) {
  969. $arrayofvat = $tablocaltax2;
  970. }
  971. // VAT Reverse charge
  972. if ($mysoc->country_code == 'FR' || getDolGlobalString('ACCOUNTING_FORCE_ENABLE_VAT_REVERSE_CHARGE')) {
  973. $has_vat = false;
  974. foreach ($arrayofvat[$key] as $k => $mt) {
  975. if ($mt) {
  976. $has_vat = true;
  977. }
  978. }
  979. if (!$has_vat) {
  980. $arrayofvat = $tabrctva;
  981. if ($numtax == 1) {
  982. $arrayofvat = $tabrclocaltax1;
  983. }
  984. if ($numtax == 2) {
  985. $arrayofvat = $tabrclocaltax2;
  986. }
  987. if (!is_array($arrayofvat[$key])) {
  988. $arrayofvat[$key] = array();
  989. }
  990. }
  991. }
  992. foreach ($arrayofvat[$key] as $k => $mt) {
  993. if ($mt) {
  994. print '<tr class="oddeven">';
  995. print "<!-- VAT -->";
  996. print "<td>".$date."</td>";
  997. print "<td>".$invoicestatic->getNomUrl(1)."</td>";
  998. // Account
  999. print "<td>";
  1000. $accountoshow = length_accountg($k);
  1001. if (($accountoshow == "") || $accountoshow == 'NotDefined') {
  1002. print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("Purchase").')</span>';
  1003. } else {
  1004. print $accountoshow;
  1005. }
  1006. print "</td>";
  1007. // Subledger account
  1008. print "<td>";
  1009. print '</td>';
  1010. print "<td>";
  1011. print $companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT").' '.join(', ', $def_tva[$key][$k]).' %'.($numtax ? ' - Localtax '.$numtax : '');
  1012. print "</td>";
  1013. print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
  1014. print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
  1015. print "</tr>";
  1016. $i++;
  1017. }
  1018. }
  1019. }
  1020. // VAT counterpart for NPR
  1021. if (is_array($tabother[$key])) {
  1022. foreach ($tabother[$key] as $k => $mt) {
  1023. if ($mt) {
  1024. print '<tr class="oddeven">';
  1025. print '<!-- VAT counterpart NPR -->';
  1026. print "<td>".$date."</td>";
  1027. print "<td>".$invoicestatic->getNomUrl(1)."</td>";
  1028. // Account
  1029. print '<td>';
  1030. $accountoshow = length_accountg($k);
  1031. if ($accountoshow == '' || $accountoshow == 'NotDefined') {
  1032. print '<span class="error">'.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account</span>';
  1033. } else {
  1034. print $accountoshow;
  1035. }
  1036. print '</td>';
  1037. // Subledger account
  1038. print "<td>";
  1039. print '</td>';
  1040. print "<td>".$companystatic->getNomUrl(0, 'supplier', 16).' - '.$invoicestatic->ref_supplier.' - '.$langs->trans("VAT")." NPR (counterpart)</td>";
  1041. print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
  1042. print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
  1043. print "</tr>";
  1044. $i++;
  1045. }
  1046. }
  1047. }
  1048. }
  1049. if (!$i) {
  1050. print '<tr class="oddeven"><td colspan="7"><span class="opacitymedium">'.$langs->trans("NoRecordFound").'</span></td></tr>';
  1051. }
  1052. print "</table>";
  1053. print '</div>';
  1054. // End of page
  1055. llxFooter();
  1056. }
  1057. $db->close();