tax.lib.php 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. <?php
  2. /* Copyright (C) 2004-2009 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2006-2007 Yannick Warnier <ywarnier@beeznest.org>
  4. * Copyright (C) 2011 Regis Houssin <regis.houssin@capnetworks.com>
  5. * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/core/lib/tax.lib.php
  22. * \ingroup tax
  23. * \brief Library for tax module
  24. */
  25. /**
  26. * Prepare array with list of tabs
  27. *
  28. * @param Object $object Object related to tabs
  29. * @return array Array of tabs to shoc
  30. */
  31. function tax_prepare_head($object)
  32. {
  33. global $langs, $conf;
  34. $h = 0;
  35. $head = array();
  36. $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/charges.php?id='.$object->id;
  37. $head[$h][1] = $langs->trans('Card');
  38. $head[$h][2] = 'card';
  39. $h++;
  40. // Show more tabs from modules
  41. // Entries must be declared in modules descriptor with line
  42. // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
  43. // $this->tabs = array('entity:-tabname); to remove a tab
  44. complete_head_from_modules($conf,$langs,$object,$head,$h,'tax');
  45. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
  46. $upload_dir = $conf->tax->dir_output . "/" . dol_sanitizeFileName($object->ref);
  47. $nbFiles = count(dol_dir_list($upload_dir,'files',0,'','(\.meta|_preview\.png)$'));
  48. $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/document.php?id='.$object->id;
  49. $head[$h][1] = $langs->trans("Documents");
  50. if($nbFiles > 0) $head[$h][1].= ' ('.$nbFiles.')';
  51. $head[$h][2] = 'documents';
  52. $h++;
  53. $head[$h][0] = DOL_URL_ROOT.'/compta/sociales/info.php?id='.$object->id;
  54. $head[$h][1] = $langs->trans("Info");
  55. $head[$h][2] = 'info';
  56. $h++;
  57. complete_head_from_modules($conf,$langs,$object,$head,$h,'tax','remove');
  58. return $head;
  59. }
  60. /**
  61. * Look for collectable VAT clients in the chosen year (and month)
  62. *
  63. * @param DoliDB $db Database handle
  64. * @param int $y Year
  65. * @param string $date_start Start date
  66. * @param string $date_end End date
  67. * @param int $modetax 0 or 1 (option vat on debit)
  68. * @param string $direction 'sell' or 'buy'
  69. * @param int $m Month
  70. * @return array List of customers third parties with vat, -1 if no accountancy module, -2 if not yet developped, -3 if error
  71. */
  72. function vat_by_thirdparty($db, $y, $date_start, $date_end, $modetax, $direction, $m=0)
  73. {
  74. global $conf;
  75. $list=array();
  76. //print "xx".$conf->global->MAIN_MODULE_ACCOUNTING;
  77. //print "xx".$conf->global->MAIN_MODULE_COMPTABILITE;
  78. if ($direction == 'sell')
  79. {
  80. $invoicetable='facture';
  81. $invoicedettable='facturedet';
  82. $fk_facture='fk_facture';
  83. $total_tva='total_tva';
  84. $total_localtax1='total_localtax1';
  85. $total_localtax2='total_localtax2';
  86. }
  87. if ($direction == 'buy')
  88. {
  89. $invoicetable='facture_fourn';
  90. $invoicedettable='facture_fourn_det';
  91. $fk_facture='fk_facture_fourn';
  92. $total_tva='tva';
  93. $total_localtax1='total_localtax1';
  94. $total_localtax2='total_localtax2';
  95. }
  96. // Define sql request
  97. $sql='';
  98. if ($modetax == 1)
  99. {
  100. // If vat paid on due invoices (non draft)
  101. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  102. {
  103. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  104. // n'est pas stocke dans la table des payments.
  105. // Seul le module compta expert peut resoudre ce probleme.
  106. // (Il faut quand un payment a lieu, stocker en plus du montant du paiement le
  107. // detail part tva et part ht).
  108. $sql = 'TODO';
  109. }
  110. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  111. {
  112. $sql = "SELECT s.rowid as socid, s.nom as nom, s.siren as tva_intra, s.tva_assuj as assuj,";
  113. $sql.= " sum(fd.total_ht) as amount, sum(fd.".$total_tva.") as tva,";
  114. $sql.= " sum(fd.".$total_localtax1.") as localtax1,";
  115. $sql.= " sum(fd.".$total_localtax2.") as localtax2";
  116. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f,";
  117. $sql.= " ".MAIN_DB_PREFIX.$invoicedettable." as fd,";
  118. $sql.= " ".MAIN_DB_PREFIX."societe as s";
  119. $sql.= " WHERE f.entity = " . $conf->entity;
  120. $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
  121. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  122. else $sql.= " AND f.type IN (0,1,2,3)";
  123. if ($y && $m)
  124. {
  125. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  126. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  127. }
  128. else if ($y)
  129. {
  130. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  131. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  132. }
  133. if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
  134. $sql.= " AND s.rowid = f.fk_soc AND f.rowid = fd.".$fk_facture;
  135. $sql.= " GROUP BY s.rowid, s.nom, s.tva_intra, s.tva_assuj";
  136. }
  137. }
  138. else
  139. {
  140. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  141. {
  142. // If vat paid on payments
  143. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  144. // n'est pas stocke dans la table des payments.
  145. // Seul le module compta expert peut resoudre ce probleme.
  146. // (Il faut quand un payment a lieu, stocker en plus du montant du paiement le
  147. // detail part tva et part ht).
  148. $sql = 'TODO';
  149. }
  150. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  151. {
  152. // Tva sur factures payes (should be on payment)
  153. /* $sql = "SELECT s.rowid as socid, s.nom as nom, s.tva_intra as tva_intra, s.tva_assuj as assuj,";
  154. $sql.= " sum(fd.total_ht) as amount, sum(".$total_tva.") as tva";
  155. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f, ".MAIN_DB_PREFIX.$invoicetable." as fd, ".MAIN_DB_PREFIX."societe as s";
  156. $sql.= " WHERE ";
  157. $sql.= " f.fk_statut in (2)"; // Paid (partially or completely)
  158. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  159. else $sql.= " AND f.type IN (0,1,2,3)";
  160. if ($y && $m)
  161. {
  162. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  163. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  164. }
  165. else if ($y)
  166. {
  167. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  168. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  169. }
  170. if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
  171. $sql.= " AND s.rowid = f.fk_soc AND f.rowid = fd.".$fk_facture;
  172. $sql.= " GROUP BY s.rowid as socid, s.nom as nom, s.tva_intra as tva_intra, s.tva_assuj as assuj";
  173. */
  174. $sql = 'TODO';
  175. }
  176. }
  177. if (! $sql) return -1;
  178. if ($sql == 'TODO') return -2;
  179. if ($sql != 'TODO')
  180. {
  181. dol_syslog("Tax.lib:thirdparty sql=".$sql);
  182. $resql = $db->query($sql);
  183. if ($resql)
  184. {
  185. while($assoc = $db->fetch_object($resql))
  186. {
  187. $list[] = $assoc;
  188. }
  189. $db->free($resql);
  190. return $list;
  191. }
  192. else
  193. {
  194. dol_print_error($db);
  195. return -3;
  196. }
  197. }
  198. }
  199. /**
  200. * Gets VAT to collect for the given year (and given quarter or month)
  201. * The function gets the VAT in split results, as the VAT declaration asks
  202. * to report the amounts for different VAT rates as different lines.
  203. * This function also accounts recurrent invoices.
  204. *
  205. * @param DoliDB $db Database handler object
  206. * @param int $y Year
  207. * @param int $q Quarter
  208. * @param string $date_start Start date
  209. * @param string $date_end End date
  210. * @param int $modetax 0 or 1 (option vat on debit)
  211. * @param int $direction 'sell' (customer invoice) or 'buy' (supplier invoices)
  212. * @param int $m Month
  213. * @return array List of quarters with vat
  214. */
  215. function vat_by_date($db, $y, $q, $date_start, $date_end, $modetax, $direction, $m=0)
  216. {
  217. global $conf;
  218. $list=array();
  219. if ($direction == 'sell')
  220. {
  221. $invoicetable='facture';
  222. $invoicedettable='facturedet';
  223. $fk_facture='fk_facture';
  224. $fk_facture2='fk_facture';
  225. $fk_payment='fk_paiement';
  226. $total_tva='total_tva';
  227. $total_localtax1='total_localtax1';
  228. $total_localtax2='total_localtax2';
  229. $paymenttable='paiement';
  230. $paymentfacturetable='paiement_facture';
  231. $invoicefieldref='facnumber';
  232. }
  233. if ($direction == 'buy')
  234. {
  235. $invoicetable='facture_fourn';
  236. $invoicedettable='facture_fourn_det';
  237. $fk_facture='fk_facture_fourn';
  238. $fk_facture2='fk_facturefourn';
  239. $fk_payment='fk_paiementfourn';
  240. $total_tva='tva';
  241. $total_localtax1='total_localtax1';
  242. $total_localtax2='total_localtax2';
  243. $paymenttable='paiementfourn';
  244. $paymentfacturetable='paiementfourn_facturefourn';
  245. $invoicefieldref='ref';
  246. }
  247. // CAS DES BIENS
  248. // Define sql request
  249. $sql='';
  250. if ($modetax == 1) // Option vat on delivery for goods (payment) and debit invoice for services
  251. {
  252. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  253. {
  254. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  255. // n'est pas stocke dans la table des payments.
  256. // Seul le module compta expert peut resoudre ce probleme.
  257. // (Il faut quand un payment a lieu, stocker en plus du montant du paiement le
  258. // detail part tva et part ht).
  259. $sql='TODO';
  260. }
  261. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  262. {
  263. // Count on delivery date (use invoice date as delivery is unknown)
  264. $sql = "SELECT d.rowid, d.product_type as dtype, d.".$fk_facture." as facid, d.tva_tx as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.".$total_tva." as total_vat, d.description as descr,";
  265. $sql .=" d.".$total_localtax1." as total_localtax1, d.".$total_localtax2." as total_localtax2, ";
  266. $sql.= " d.date_start as date_start, d.date_end as date_end,";
  267. $sql.= " f.".$invoicefieldref." as facnum, f.type, f.total_ttc as ftotal_ttc,";
  268. $sql.= " p.rowid as pid, p.ref as pref, p.fk_product_type as ptype,";
  269. $sql.= " 0 as payment_id, 0 as payment_amount";
  270. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f,";
  271. $sql.= " ".MAIN_DB_PREFIX.$invoicedettable." as d" ;
  272. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
  273. $sql.= " WHERE f.entity = " . $conf->entity;
  274. $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
  275. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  276. else $sql.= " AND f.type IN (0,1,2,3)";
  277. $sql.= " AND f.rowid = d.".$fk_facture;
  278. if ($y && $m)
  279. {
  280. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  281. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  282. }
  283. else if ($y)
  284. {
  285. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  286. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  287. }
  288. if ($q) $sql.= " AND (date_format(f.datef,'%m') > ".(($q-1)*3)." AND date_format(f.datef,'%m') <= ".($q*3).")";
  289. if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
  290. $sql.= " AND (d.product_type = 0"; // Limit to products
  291. $sql.= " AND d.date_start is null AND d.date_end IS NULL)"; // enhance detection of service
  292. $sql.= " ORDER BY d.rowid, d.".$fk_facture;
  293. }
  294. }
  295. else // Option vat on delivery for goods (payments) and payments for services
  296. {
  297. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  298. {
  299. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  300. // n'est pas stocke dans la table des payments.
  301. // Seul le module compta expert peut resoudre ce probleme.
  302. // (Il faut quand un payment a lieu, stocker en plus du montant du paiement le
  303. // detail part tva et part ht).
  304. $sql='TODO';
  305. }
  306. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  307. {
  308. // Count on delivery date (use invoice date as delivery is unknown)
  309. $sql = "SELECT d.rowid, d.product_type as dtype, d.".$fk_facture." as facid, d.tva_tx as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.".$total_tva." as total_vat, d.description as descr,";
  310. $sql .=" d.".$total_localtax1." as total_localtax1, d.".$total_localtax2." as total_localtax2, ";
  311. $sql.= " d.date_start as date_start, d.date_end as date_end,";
  312. $sql.= " f.".$invoicefieldref." as facnum, f.type, f.total_ttc as ftotal_ttc,";
  313. $sql.= " p.rowid as pid, p.ref as pref, p.fk_product_type as ptype,";
  314. $sql.= " 0 as payment_id, 0 as payment_amount";
  315. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f,";
  316. $sql.= " ".MAIN_DB_PREFIX.$invoicedettable." as d" ;
  317. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
  318. $sql.= " WHERE f.entity = " . $conf->entity;
  319. $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
  320. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  321. else $sql.= " AND f.type IN (0,1,2,3)";
  322. $sql.= " AND f.rowid = d.".$fk_facture;
  323. if ($y && $m)
  324. {
  325. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  326. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  327. }
  328. else if ($y)
  329. {
  330. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  331. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  332. }
  333. if ($q) $sql.= " AND (date_format(f.datef,'%m') > ".(($q-1)*3)." AND date_format(f.datef,'%m') <= ".($q*3).")";
  334. if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
  335. $sql.= " AND (d.product_type = 0"; // Limit to products
  336. $sql.= " AND d.date_start is null AND d.date_end IS NULL)"; // enhance detection of service
  337. $sql.= " ORDER BY d.rowid, d.".$fk_facture;
  338. //print $sql;
  339. }
  340. }
  341. //print $sql.'<br>';
  342. if (! $sql) return -1;
  343. if ($sql == 'TODO') return -2;
  344. if ($sql != 'TODO')
  345. {
  346. dol_syslog("Tax.lib.php::vat_by_date sql=".$sql);
  347. $resql = $db->query($sql);
  348. if ($resql)
  349. {
  350. $rate = -1;
  351. $oldrowid='';
  352. while($assoc = $db->fetch_array($resql))
  353. {
  354. if (! isset($list[$assoc['rate']]['totalht'])) $list[$assoc['rate']]['totalht']=0;
  355. if (! isset($list[$assoc['rate']]['vat'])) $list[$assoc['rate']]['vat']=0;
  356. if (! isset($list[$assoc['rate']]['localtax1'])) $list[$assoc['rate']]['localtax1']=0;
  357. if (! isset($list[$assoc['rate']]['localtax2'])) $list[$assoc['rate']]['localtax2']=0;
  358. if ($assoc['rowid'] != $oldrowid) // Si rupture sur d.rowid
  359. {
  360. $oldrowid=$assoc['rowid'];
  361. $list[$assoc['rate']]['totalht'] += $assoc['total_ht'];
  362. $list[$assoc['rate']]['vat'] += $assoc['total_vat'];
  363. $list[$assoc['rate']]['localtax1'] += $assoc['total_localtax1'];
  364. $list[$assoc['rate']]['localtax2'] += $assoc['total_localtax2'];
  365. }
  366. $list[$assoc['rate']]['dtotal_ttc'][] = $assoc['total_ttc'];
  367. $list[$assoc['rate']]['dtype'][] = $assoc['dtype'];
  368. $list[$assoc['rate']]['ddate_start'][] = $db->jdate($assoc['date_start']);
  369. $list[$assoc['rate']]['ddate_end'][] = $db->jdate($assoc['date_end']);
  370. $list[$assoc['rate']]['facid'][] = $assoc['facid'];
  371. $list[$assoc['rate']]['facnum'][] = $assoc['facnum'];
  372. $list[$assoc['rate']]['type'][] = $assoc['type'];
  373. $list[$assoc['rate']]['ftotal_ttc'][] = $assoc['ftotal_ttc'];
  374. $list[$assoc['rate']]['descr'][] = $assoc['descr'];
  375. $list[$assoc['rate']]['totalht_list'][] = $assoc['total_ht'];
  376. $list[$assoc['rate']]['vat_list'][] = $assoc['total_vat'];
  377. $list[$assoc['rate']]['localtax1_list'][] = $assoc['total_localtax1'];
  378. $list[$assoc['rate']]['localtax2_list'][] = $assoc['total_localtax2'];
  379. $list[$assoc['rate']]['pid'][] = $assoc['pid'];
  380. $list[$assoc['rate']]['pref'][] = $assoc['pref'];
  381. $list[$assoc['rate']]['ptype'][] = $assoc['ptype'];
  382. $list[$assoc['rate']]['payment_id'][] = $assoc['payment_id'];
  383. $list[$assoc['rate']]['payment_amount'][] = $assoc['payment_amount'];
  384. $rate = $assoc['rate'];
  385. }
  386. }
  387. else
  388. {
  389. dol_print_error($db);
  390. return -3;
  391. }
  392. }
  393. // CAS DES SERVICES
  394. // Define sql request
  395. $sql='';
  396. if ($modetax == 1) // Option vat on delivery for goods (payment) and debit invoice for services
  397. {
  398. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  399. {
  400. // Count on invoice date
  401. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  402. // n'est pas stocke dans la table des payments.
  403. // Seul le module compta expert peut resoudre ce probleme.
  404. // (Il faut quand un payment a lieu, stocker en plus du montant du paiement le
  405. // detail part tva et part ht).
  406. $sql='TODO';
  407. }
  408. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  409. {
  410. // Count on invoice date
  411. $sql = "SELECT d.rowid, d.product_type as dtype, d.".$fk_facture." as facid, d.tva_tx as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.".$total_tva." as total_vat, d.description as descr,";
  412. $sql .=" d.".$total_localtax1." as total_localtax1, d.".$total_localtax2." as total_localtax2, ";
  413. $sql.= " d.date_start as date_start, d.date_end as date_end,";
  414. $sql.= " f.".$invoicefieldref." as facnum, f.type, f.total_ttc as ftotal_ttc,";
  415. $sql.= " p.rowid as pid, p.ref as pref, p.fk_product_type as ptype,";
  416. $sql.= " 0 as payment_id, 0 as payment_amount";
  417. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f,";
  418. $sql.= " ".MAIN_DB_PREFIX.$invoicedettable." as d" ;
  419. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
  420. $sql.= " WHERE f.entity = " . $conf->entity;
  421. $sql.= " AND f.fk_statut in (1,2)"; // Validated or paid (partially or completely)
  422. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  423. else $sql.= " AND f.type IN (0,1,2,3)";
  424. $sql.= " AND f.rowid = d.".$fk_facture;
  425. if ($y && $m)
  426. {
  427. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  428. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  429. }
  430. else if ($y)
  431. {
  432. $sql.= " AND f.datef >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  433. $sql.= " AND f.datef <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  434. }
  435. if ($q) $sql.= " AND (date_format(f.datef,'%m') > ".(($q-1)*3)." AND date_format(f.datef,'%m') <= ".($q*3).")";
  436. if ($date_start && $date_end) $sql.= " AND f.datef >= '".$db->idate($date_start)."' AND f.datef <= '".$db->idate($date_end)."'";
  437. $sql.= " AND (d.product_type = 1"; // Limit to services
  438. $sql.= " OR d.date_start is NOT null OR d.date_end IS NOT NULL)"; // enhance detection of service
  439. $sql.= " ORDER BY d.rowid, d.".$fk_facture;
  440. }
  441. }
  442. else // Option vat on delivery for goods (payments) and payments for services
  443. {
  444. if (! empty($conf->global->MAIN_MODULE_ACCOUNTING))
  445. {
  446. // Count on payments date
  447. // TODO a ce jour on se sait pas la compter car le montant tva d'un payment
  448. // n'est pas stocke dans la table des payments.
  449. // Seul le module compta expert peut resoudre ce probleme.
  450. // (Il faut quand un paiement a lieu, stocker en plus du montant du paiement le
  451. // detail part tva et part ht).
  452. $sql='TODO';
  453. }
  454. if (! empty($conf->global->MAIN_MODULE_COMPTABILITE))
  455. {
  456. // Count on payments date
  457. $sql = "SELECT d.rowid, d.product_type as dtype, d.".$fk_facture." as facid, d.tva_tx as rate, d.total_ht as total_ht, d.total_ttc as total_ttc, d.".$total_tva." as total_vat, d.description as descr,";
  458. $sql .=" d.".$total_localtax1." as total_localtax1, d.".$total_localtax2." as total_localtax2, ";
  459. $sql.= " d.date_start as date_start, d.date_end as date_end,";
  460. $sql.= " f.".$invoicefieldref." as facnum, f.type, f.total_ttc as ftotal_ttc,";
  461. $sql.= " p.rowid as pid, p.ref as pref, p.fk_product_type as ptype,";
  462. $sql.= " pf.".$fk_payment." as payment_id, pf.amount as payment_amount";
  463. $sql.= " FROM ".MAIN_DB_PREFIX.$invoicetable." as f,";
  464. $sql.= " ".MAIN_DB_PREFIX.$paymentfacturetable." as pf,";
  465. $sql.= " ".MAIN_DB_PREFIX.$paymenttable." as pa,";
  466. $sql.= " ".MAIN_DB_PREFIX.$invoicedettable." as d";
  467. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p on d.fk_product = p.rowid";
  468. $sql.= " WHERE f.entity = " . $conf->entity;
  469. $sql.= " AND f.fk_statut in (1,2)"; // Paid (partially or completely)
  470. if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) $sql.= " AND f.type IN (0,1,2)";
  471. else $sql.= " AND f.type IN (0,1,2,3)";
  472. $sql.= " AND f.rowid = d.".$fk_facture;;
  473. $sql.= " AND pf.".$fk_facture2." = f.rowid";
  474. $sql.= " AND pa.rowid = pf.".$fk_payment;
  475. if ($y && $m)
  476. {
  477. $sql.= " AND pa.datep >= '".$db->idate(dol_get_first_day($y,$m,false))."'";
  478. $sql.= " AND pa.datep <= '".$db->idate(dol_get_last_day($y,$m,false))."'";
  479. }
  480. else if ($y)
  481. {
  482. $sql.= " AND pa.datep >= '".$db->idate(dol_get_first_day($y,1,false))."'";
  483. $sql.= " AND pa.datep <= '".$db->idate(dol_get_last_day($y,12,false))."'";
  484. }
  485. if ($q) $sql.= " AND (date_format(pa.datep,'%m') > ".(($q-1)*3)." AND date_format(pa.datep,'%m') <= ".($q*3).")";
  486. if ($date_start && $date_end) $sql.= " AND pa.datep >= '".$db->idate($date_start)."' AND pa.datep <= '".$db->idate($date_end)."'";
  487. $sql.= " AND (d.product_type = 1"; // Limit to services
  488. $sql.= " OR d.date_start is NOT null OR d.date_end IS NOT NULL)"; // enhance detection of service
  489. $sql.= " ORDER BY d.rowid, d.".$fk_facture.", pf.rowid";
  490. }
  491. }
  492. if (! $sql)
  493. {
  494. dol_syslog("Tax.lib.php::vat_by_date no accountancy module enabled".$sql,LOG_ERR);
  495. return -1; // -1 = Not accountancy module enabled
  496. }
  497. if ($sql == 'TODO') return -2; // -2 = Feature not yet available
  498. if ($sql != 'TODO')
  499. {
  500. dol_syslog("Tax.lib.php::vat_by_date sql=".$sql);
  501. $resql = $db->query($sql);
  502. if ($resql)
  503. {
  504. $rate = -1;
  505. $oldrowid='';
  506. while($assoc = $db->fetch_array($resql))
  507. {
  508. if (! isset($list[$assoc['rate']]['totalht'])) $list[$assoc['rate']]['totalht']=0;
  509. if (! isset($list[$assoc['rate']]['vat'])) $list[$assoc['rate']]['vat']=0;
  510. if (! isset($list[$assoc['rate']]['localtax1'])) $list[$assoc['rate']]['localtax1']=0;
  511. if (! isset($list[$assoc['rate']]['localtax2'])) $list[$assoc['rate']]['localtax2']=0;
  512. if ($assoc['rowid'] != $oldrowid) // Si rupture sur d.rowid
  513. {
  514. $oldrowid=$assoc['rowid'];
  515. $list[$assoc['rate']]['totalht'] += $assoc['total_ht'];
  516. $list[$assoc['rate']]['vat'] += $assoc['total_vat'];
  517. $list[$assoc['rate']]['localtax1'] += $assoc['total_localtax1'];
  518. $list[$assoc['rate']]['localtax2'] += $assoc['total_localtax2'];
  519. }
  520. $list[$assoc['rate']]['dtotal_ttc'][] = $assoc['total_ttc'];
  521. $list[$assoc['rate']]['dtype'][] = $assoc['dtype'];
  522. $list[$assoc['rate']]['ddate_start'][] = $db->jdate($assoc['date_start']);
  523. $list[$assoc['rate']]['ddate_end'][] = $db->jdate($assoc['date_end']);
  524. $list[$assoc['rate']]['facid'][] = $assoc['facid'];
  525. $list[$assoc['rate']]['facnum'][] = $assoc['facnum'];
  526. $list[$assoc['rate']]['type'][] = $assoc['type'];
  527. $list[$assoc['rate']]['ftotal_ttc'][] = $assoc['ftotal_ttc'];
  528. $list[$assoc['rate']]['descr'][] = $assoc['descr'];
  529. $list[$assoc['rate']]['totalht_list'][] = $assoc['total_ht'];
  530. $list[$assoc['rate']]['vat_list'][] = $assoc['total_vat'];
  531. $list[$assoc['rate']]['localtax1_list'][] = $assoc['total_localtax1'];
  532. $list[$assoc['rate']]['localtax2_list'][] = $assoc['total_localtax2'];
  533. $list[$assoc['rate']]['pid'][] = $assoc['pid'];
  534. $list[$assoc['rate']]['pref'][] = $assoc['pref'];
  535. $list[$assoc['rate']]['ptype'][] = $assoc['ptype'];
  536. $list[$assoc['rate']]['payment_id'][] = $assoc['payment_id'];
  537. $list[$assoc['rate']]['payment_amount'][] = $assoc['payment_amount'];
  538. $rate = $assoc['rate'];
  539. }
  540. }
  541. else
  542. {
  543. dol_print_error($db);
  544. return -3;
  545. }
  546. }
  547. return $list;
  548. }