discount.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
  1. <?php
  2. /* Copyright (C) 2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004-2018 Laurent Destailleur <eldy@users.sourceforge.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file htdocs/core/class/discount.class.php
  20. * \ingroup core propal facture commande
  21. * \brief File of class to manage absolute discounts
  22. */
  23. /**
  24. * Class to manage absolute discounts
  25. */
  26. class DiscountAbsolute
  27. {
  28. /**
  29. * @var DoliDB Database handler.
  30. */
  31. public $db;
  32. /**
  33. * @var string Error code (or message)
  34. */
  35. public $error;
  36. /**
  37. * @var string[] Array of error strings
  38. */
  39. public $errors = array();
  40. /**
  41. * @var int ID discount
  42. */
  43. public $id;
  44. /**
  45. * @var int Thirdparty ID
  46. */
  47. public $fk_soc;
  48. public $discount_type; // 0 => customer discount, 1 => supplier discount
  49. public $total_ht;
  50. public $total_tva;
  51. public $total_ttc;
  52. public $amount_ht; // deprecated
  53. public $amount_tva; // deprecated
  54. public $amount_ttc; // deprecated
  55. public $multicurrency_total_ht;
  56. public $multicurrency_total_tva;
  57. public $multicurrency_total_ttc;
  58. public $multicurrency_amount_ht; // deprecated
  59. public $multicurrency_amount_tva; // deprecated
  60. public $multicurrency_amount_ttc; // deprecated
  61. // Vat rate
  62. public $tva_tx;
  63. public $vat_src_code;
  64. /**
  65. * @var int User ID Id utilisateur qui accorde la remise
  66. */
  67. public $fk_user;
  68. /**
  69. * @var string description
  70. */
  71. public $description;
  72. /**
  73. * Date creation record (datec)
  74. *
  75. * @var integer
  76. */
  77. public $datec;
  78. /**
  79. * @var int ID invoice line when a discount is used into an invoice line (for absolute discounts)
  80. */
  81. public $fk_facture_line;
  82. /**
  83. * @var int ID invoice when a discount line is used into an invoice (for credit note)
  84. */
  85. public $fk_facture;
  86. /**
  87. * @var int ID credit note or deposit used to create the discount
  88. */
  89. public $fk_facture_source;
  90. public $ref_facture_source; // Ref credit note or deposit used to create the discount
  91. public $type_facture_source;
  92. public $fk_invoice_supplier_source;
  93. public $ref_invoice_supplier_source; // Ref credit note or deposit used to create the discount
  94. public $type_invoice_supplier_source;
  95. /**
  96. * Constructor
  97. *
  98. * @param DoliDB $db Database handler
  99. */
  100. public function __construct($db)
  101. {
  102. $this->db = $db;
  103. }
  104. /**
  105. * Load object from database into memory
  106. *
  107. * @param int $rowid id discount to load
  108. * @param int $fk_facture_source fk_facture_source
  109. * @param int $fk_invoice_supplier_source fk_invoice_supplier_source
  110. * @return int <0 if KO, =0 if not found, >0 if OK
  111. */
  112. public function fetch($rowid, $fk_facture_source = 0, $fk_invoice_supplier_source = 0)
  113. {
  114. global $conf;
  115. // Check parameters
  116. if (!$rowid && !$fk_facture_source && !$fk_invoice_supplier_source) {
  117. $this->error = 'ErrorBadParameters';
  118. return -1;
  119. }
  120. $sql = "SELECT sr.rowid, sr.fk_soc, sr.discount_type,";
  121. $sql .= " sr.fk_user,";
  122. $sql .= " sr.amount_ht, sr.amount_tva, sr.amount_ttc, sr.tva_tx, sr.vat_src_code,";
  123. $sql .= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,";
  124. $sql .= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.fk_invoice_supplier_line, sr.fk_invoice_supplier, sr.fk_invoice_supplier_source, sr.description,";
  125. $sql .= " sr.datec,";
  126. $sql .= " f.ref as ref_facture_source, f.type as type_facture_source,";
  127. $sql .= " fsup.ref as ref_invoice_supplier_source, fsup.type as type_invoice_supplier_source";
  128. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as sr";
  129. $sql .= " LEFT JOIN ".$this->db->prefix()."facture as f ON sr.fk_facture_source = f.rowid";
  130. $sql .= " LEFT JOIN ".$this->db->prefix()."facture_fourn as fsup ON sr.fk_invoice_supplier_source = fsup.rowid";
  131. $sql .= " WHERE sr.entity IN (".getEntity('invoice').")";
  132. if ($rowid) {
  133. $sql .= " AND sr.rowid = ".((int) $rowid);
  134. }
  135. if ($fk_facture_source) {
  136. $sql .= " AND sr.fk_facture_source = ".((int) $fk_facture_source);
  137. }
  138. if ($fk_invoice_supplier_source) {
  139. $sql .= " AND sr.fk_invoice_supplier_source = ".((int) $fk_invoice_supplier_source);
  140. }
  141. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  142. $resql = $this->db->query($sql);
  143. if ($resql) {
  144. if ($this->db->num_rows($resql)) {
  145. $obj = $this->db->fetch_object($resql);
  146. $this->id = $obj->rowid;
  147. $this->fk_soc = $obj->fk_soc;
  148. $this->discount_type = $obj->discount_type;
  149. $this->total_ht = $obj->amount_ht;
  150. $this->total_tva = $obj->amount_tva;
  151. $this->total_ttc = $obj->amount_ttc;
  152. // For backward compatibility
  153. $this->amount_ht = $this->total_ht;
  154. $this->amount_tva = $this->total_tva;
  155. $this->amount_ttc = $this->total_ttc;
  156. $this->multicurrency_total_ht = $this->multicurrency_subprice = $obj->multicurrency_amount_ht;
  157. $this->multicurrency_total_tva = $obj->multicurrency_amount_tva;
  158. $this->multicurrency_total_ttc = $obj->multicurrency_amount_ttc;
  159. // For backward compatibility
  160. $this->multicurrency_amount_ht = $this->multicurrency_total_ht;
  161. $this->multicurrency_amount_tva = $this->multicurrency_total_tva;
  162. $this->multicurrency_amount_ttc = $this->multicurrency_total_ttc;
  163. $this->tva_tx = $obj->tva_tx;
  164. $this->vat_src_code = $obj->vat_src_code;
  165. $this->fk_user = $obj->fk_user;
  166. $this->fk_facture_line = $obj->fk_facture_line;
  167. $this->fk_facture = $obj->fk_facture;
  168. $this->fk_facture_source = $obj->fk_facture_source; // Id credit note or deposit source
  169. $this->ref_facture_source = $obj->ref_facture_source; // Ref credit note or deposit source
  170. $this->type_facture_source = $obj->type_facture_source; // Type credit note or deposit source
  171. $this->fk_invoice_supplier_line = $obj->fk_invoice_supplier_line;
  172. $this->fk_invoice_supplier = $obj->fk_invoice_supplier;
  173. $this->fk_invoice_supplier_source = $obj->fk_invoice_supplier_source; // Id credit note or deposit source
  174. $this->ref_invoice_supplier_source = $obj->ref_invoice_supplier_source; // Ref credit note or deposit source
  175. $this->type_invoice_supplier_source = $obj->type_invoice_supplier_source; // Type credit note or deposit source
  176. $this->description = $obj->description;
  177. $this->datec = $this->db->jdate($obj->datec);
  178. $this->db->free($resql);
  179. return 1;
  180. } else {
  181. $this->db->free($resql);
  182. return 0;
  183. }
  184. } else {
  185. $this->error = $this->db->error();
  186. return -1;
  187. }
  188. }
  189. /**
  190. * Create a discount into database
  191. *
  192. * @param User $user User that create
  193. * @return int <0 if KO, >0 if OK
  194. */
  195. public function create($user)
  196. {
  197. global $conf, $langs;
  198. // Clean parameters
  199. $this->amount_ht = price2num($this->amount_ht);
  200. $this->amount_tva = price2num($this->amount_tva);
  201. $this->amount_ttc = price2num($this->amount_ttc);
  202. $this->tva_tx = price2num($this->tva_tx);
  203. $this->multicurrency_amount_ht = price2num($this->multicurrency_amount_ht);
  204. $this->multicurrency_amount_tva = price2num($this->multicurrency_amount_tva);
  205. $this->multicurrency_amount_ttc = price2num($this->multicurrency_amount_ttc);
  206. if (empty($this->multicurrency_amount_ht)) {
  207. $this->multicurrency_amount_ht = 0;
  208. }
  209. if (empty($this->multicurrency_amount_tva)) {
  210. $this->multicurrency_amount_tva = 0;
  211. }
  212. if (empty($this->multicurrency_amount_ttc)) {
  213. $this->multicurrency_amount_ttc = 0;
  214. }
  215. if (empty($this->tva_tx)) {
  216. $this->tva_tx = 0;
  217. }
  218. // Check parameters
  219. if (empty($this->description)) {
  220. $this->error = 'BadValueForPropertyDescription';
  221. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  222. return -1;
  223. }
  224. $userid = $user->id;
  225. if (!($userid > 0)) { // For example when record is saved into an anonymous context with a not loaded object $user.
  226. include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  227. $tmpinvoice = new Facture($this->db);
  228. $tmpinvoice->fetch($this->fk_facture_source);
  229. $userid = $tmpinvoice->fk_user_author; // We use the author of invoice
  230. }
  231. // Insert request
  232. $sql = "INSERT INTO ".$this->db->prefix()."societe_remise_except";
  233. $sql .= " (entity, datec, fk_soc, discount_type, fk_user, description,";
  234. $sql .= " amount_ht, amount_tva, amount_ttc, tva_tx, vat_src_code,";
  235. $sql .= " multicurrency_amount_ht, multicurrency_amount_tva, multicurrency_amount_ttc,";
  236. $sql .= " fk_facture_source, fk_invoice_supplier_source";
  237. $sql .= ")";
  238. $sql .= " VALUES (".$conf->entity.", '".$this->db->idate($this->datec != '' ? $this->datec : dol_now())."', ".((int) $this->fk_soc).", ".(empty($this->discount_type) ? 0 : intval($this->discount_type)).", ".((int) $userid).", '".$this->db->escape($this->description)."',";
  239. $sql .= " ".price2num($this->amount_ht).", ".price2num($this->amount_tva).", ".price2num($this->amount_ttc).", ".price2num($this->tva_tx).", '".$this->db->escape($this->vat_src_code)."',";
  240. $sql .= " ".price2num($this->multicurrency_amount_ht).", ".price2num($this->multicurrency_amount_tva).", ".price2num($this->multicurrency_amount_ttc).", ";
  241. $sql .= " ".($this->fk_facture_source ? ((int) $this->fk_facture_source) : "null").",";
  242. $sql .= " ".($this->fk_invoice_supplier_source ? ((int) $this->fk_invoice_supplier_source) : "null");
  243. $sql .= ")";
  244. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  245. $resql = $this->db->query($sql);
  246. if ($resql) {
  247. $this->id = $this->db->last_insert_id($this->db->prefix()."societe_remise_except");
  248. return $this->id;
  249. } else {
  250. $this->error = $this->db->lasterror().' - sql='.$sql;
  251. return -1;
  252. }
  253. }
  254. /**
  255. * Delete object in database. If fk_facture_source is defined, we delete all familiy with same fk_facture_source. If not, only with id is removed
  256. *
  257. * @param User $user Object of user asking to delete
  258. * @return int <0 if KO, >0 if OK
  259. */
  260. public function delete($user)
  261. {
  262. global $conf, $langs;
  263. // Check if we can remove the discount
  264. if ($this->fk_facture_source) {
  265. $sql = "SELECT COUNT(rowid) as nb";
  266. $sql .= " FROM ".$this->db->prefix()."societe_remise_except";
  267. $sql .= " WHERE (fk_facture_line IS NOT NULL"; // Not used as absolute simple discount
  268. $sql .= " OR fk_facture IS NOT NULL)"; // Not used as credit note and not used as deposit
  269. $sql .= " AND fk_facture_source = ".((int) $this->fk_facture_source);
  270. //$sql.=" AND rowid != ".$this->id;
  271. dol_syslog(get_class($this)."::delete Check if we can remove discount", LOG_DEBUG);
  272. $resql = $this->db->query($sql);
  273. if ($resql) {
  274. $obj = $this->db->fetch_object($resql);
  275. if ($obj->nb > 0) {
  276. $this->error = 'ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved';
  277. return -2;
  278. }
  279. } else {
  280. dol_print_error($this->db);
  281. return -1;
  282. }
  283. }
  284. // Check if we can remove the discount
  285. if ($this->fk_invoice_supplier_source) {
  286. $sql = "SELECT COUNT(rowid) as nb";
  287. $sql .= " FROM ".$this->db->prefix()."societe_remise_except";
  288. $sql .= " WHERE (fk_invoice_supplier_line IS NOT NULL"; // Not used as absolute simple discount
  289. $sql .= " OR fk_invoice_supplier IS NOT NULL)"; // Not used as credit note and not used as deposit
  290. $sql .= " AND fk_invoice_supplier_source = ".((int) $this->fk_invoice_supplier_source);
  291. //$sql.=" AND rowid != ".$this->id;
  292. dol_syslog(get_class($this)."::delete Check if we can remove discount", LOG_DEBUG);
  293. $resql = $this->db->query($sql);
  294. if ($resql) {
  295. $obj = $this->db->fetch_object($resql);
  296. if ($obj->nb > 0) {
  297. $this->error = 'ErrorThisPartOrAnotherIsAlreadyUsedSoDiscountSerieCantBeRemoved';
  298. return -2;
  299. }
  300. } else {
  301. dol_print_error($this->db);
  302. return -1;
  303. }
  304. }
  305. $this->db->begin();
  306. // Delete but only if not used
  307. $sql = "DELETE FROM ".$this->db->prefix()."societe_remise_except ";
  308. if ($this->fk_facture_source) {
  309. $sql .= " WHERE fk_facture_source = ".((int) $this->fk_facture_source); // Delete all lines of same serie
  310. } elseif ($this->fk_invoice_supplier_source) {
  311. $sql .= " WHERE fk_invoice_supplier_source = ".((int) $this->fk_invoice_supplier_source); // Delete all lines of same serie
  312. } else {
  313. $sql .= " WHERE rowid = ".((int) $this->id); // Delete only line
  314. }
  315. $sql .= " AND (fk_facture_line IS NULL"; // Not used as absolute simple discount
  316. $sql .= " AND fk_facture IS NULL)"; // Not used as credit note and not used as deposit
  317. $sql .= " AND (fk_invoice_supplier_line IS NULL"; // Not used as absolute simple discount
  318. $sql .= " AND fk_invoice_supplier IS NULL)"; // Not used as credit note and not used as deposit
  319. dol_syslog(get_class($this)."::delete Delete discount", LOG_DEBUG);
  320. $result = $this->db->query($sql);
  321. if ($result) {
  322. // If source of discount was a credit note or deposit, we change source statut.
  323. if ($this->fk_facture_source) {
  324. $sql = "UPDATE ".$this->db->prefix()."facture";
  325. $sql .= " set paye=0, fk_statut=1";
  326. $sql .= " WHERE (type = 2 or type = 3) AND rowid = ".((int) $this->fk_facture_source);
  327. dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG);
  328. $result = $this->db->query($sql);
  329. if ($result) {
  330. $this->db->commit();
  331. return 1;
  332. } else {
  333. $this->error = $this->db->lasterror();
  334. $this->db->rollback();
  335. return -1;
  336. }
  337. } elseif ($this->fk_invoice_supplier_source) {
  338. $sql = "UPDATE ".$this->db->prefix()."facture_fourn";
  339. $sql .= " set paye=0, fk_statut=1";
  340. $sql .= " WHERE (type = 2 or type = 3) AND rowid = ".((int) $this->fk_invoice_supplier_source);
  341. dol_syslog(get_class($this)."::delete Update credit note or deposit invoice statut", LOG_DEBUG);
  342. $result = $this->db->query($sql);
  343. if ($result) {
  344. $this->db->commit();
  345. return 1;
  346. } else {
  347. $this->error = $this->db->lasterror();
  348. $this->db->rollback();
  349. return -1;
  350. }
  351. } else {
  352. $this->db->commit();
  353. return 1;
  354. }
  355. } else {
  356. $this->error = $this->db->lasterror();
  357. $this->db->rollback();
  358. return -1;
  359. }
  360. }
  361. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  362. /**
  363. * Link the discount to a particular invoice line or a particular invoice.
  364. * When discount is a global discount used as an invoice line, we link using rowidline.
  365. * When discount is from a credit note used to reduce payment of an invoice, we link using rowidinvoice
  366. *
  367. * @param int $rowidline Invoice line id (To use discount into invoice lines)
  368. * @param int $rowidinvoice Invoice id (To use discount as a credit note to reduce payment of invoice)
  369. * @return int <0 if KO, >0 if OK
  370. */
  371. public function link_to_invoice($rowidline, $rowidinvoice)
  372. {
  373. // phpcs:enable
  374. // Check parameters
  375. if (!$rowidline && !$rowidinvoice) {
  376. $this->error = 'ErrorBadParameters';
  377. return -1;
  378. }
  379. if ($rowidline && $rowidinvoice) {
  380. $this->error = 'ErrorBadParameters';
  381. return -2;
  382. }
  383. $sql = "UPDATE ".$this->db->prefix()."societe_remise_except";
  384. if (!empty($this->discount_type)) {
  385. if ($rowidline) {
  386. $sql .= " SET fk_invoice_supplier_line = ".((int) $rowidline);
  387. }
  388. if ($rowidinvoice) {
  389. $sql .= " SET fk_invoice_supplier = ".((int) $rowidinvoice);
  390. }
  391. } else {
  392. if ($rowidline) {
  393. $sql .= " SET fk_facture_line = ".((int) $rowidline);
  394. }
  395. if ($rowidinvoice) {
  396. $sql .= " SET fk_facture = ".((int) $rowidinvoice);
  397. }
  398. }
  399. $sql .= " WHERE rowid = ".((int) $this->id);
  400. dol_syslog(get_class($this)."::link_to_invoice", LOG_DEBUG);
  401. $resql = $this->db->query($sql);
  402. if ($resql) {
  403. if (!empty($this->discount_type)) {
  404. $this->fk_invoice_supplier_line = $rowidline;
  405. $this->fk_invoice_supplier = $rowidinvoice;
  406. } else {
  407. $this->fk_facture_line = $rowidline;
  408. $this->fk_facture = $rowidinvoice;
  409. }
  410. return 1;
  411. } else {
  412. $this->error = $this->db->error();
  413. return -3;
  414. }
  415. }
  416. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  417. /**
  418. * Link the discount to a particular invoice line or a particular invoice.
  419. * Do not call this if discount is linked to a reconcialiated invoice
  420. *
  421. * @return int <0 if KO, >0 if OK
  422. */
  423. public function unlink_invoice()
  424. {
  425. // phpcs:enable
  426. $sql = "UPDATE ".$this->db->prefix()."societe_remise_except";
  427. if (!empty($this->discount_type)) {
  428. $sql .= " SET fk_invoice_supplier_line = NULL, fk_invoice_supplier = NULL";
  429. } else {
  430. $sql .= " SET fk_facture_line = NULL, fk_facture = NULL";
  431. }
  432. $sql .= " WHERE rowid = ".((int) $this->id);
  433. dol_syslog(get_class($this)."::unlink_invoice", LOG_DEBUG);
  434. $resql = $this->db->query($sql);
  435. if ($resql) {
  436. return 1;
  437. } else {
  438. $this->error = $this->db->error();
  439. return -3;
  440. }
  441. }
  442. /**
  443. * Return amount (with tax) of discounts currently available for a company, user or other criteria
  444. *
  445. * @param Societe $company Object third party for filter
  446. * @param User $user Filtre sur un user auteur des remises
  447. * @param string $filter Filter other. Warning: Do not use a user input value here.
  448. * @param int $maxvalue Filter on max value for discount
  449. * @param int $discount_type 0 => customer discount, 1 => supplier discount
  450. * @param int $multicurrency Return multicurrency_amount instead of amount
  451. * @return int <0 if KO, amount otherwise
  452. */
  453. public function getAvailableDiscounts($company = '', $user = '', $filter = '', $maxvalue = 0, $discount_type = 0, $multicurrency = 0)
  454. {
  455. global $conf;
  456. dol_syslog(get_class($this)."::getAvailableDiscounts discount_type=".$discount_type, LOG_DEBUG);
  457. $sql = "SELECT SUM(rc.amount_ttc) as amount, SUM(rc.multicurrency_amount_ttc) as multicurrency_amount";
  458. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc";
  459. $sql .= " WHERE rc.entity = ".$conf->entity;
  460. $sql .= " AND rc.discount_type=".((int) $discount_type);
  461. if (!empty($discount_type)) {
  462. $sql .= " AND (rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_line IS NULL)"; // Available from supplier
  463. } else {
  464. $sql .= " AND (rc.fk_facture IS NULL AND rc.fk_facture_line IS NULL)"; // Available to customer
  465. }
  466. if (is_object($company)) {
  467. $sql .= " AND rc.fk_soc = ".((int) $company->id);
  468. }
  469. if (is_object($user)) {
  470. $sql .= " AND rc.fk_user = ".((int) $user->id);
  471. }
  472. if ($filter) {
  473. $sql .= " AND (".$filter.")";
  474. }
  475. if ($maxvalue) {
  476. $sql .= ' AND rc.amount_ttc <= '.((float) price2num($maxvalue));
  477. }
  478. $resql = $this->db->query($sql);
  479. if ($resql) {
  480. $obj = $this->db->fetch_object($resql);
  481. //while ($obj)
  482. //{
  483. //print 'zz'.$obj->amount;
  484. //$obj = $this->db->fetch_object($resql);
  485. //}
  486. if ($multicurrency) {
  487. return $obj->multicurrency_amount;
  488. }
  489. return $obj->amount;
  490. }
  491. return -1;
  492. }
  493. /**
  494. * Return amount (with tax) of all deposits invoices used by invoice as a payment.
  495. * Should always be empty, except if option FACTURE_DEPOSITS_ARE_JUST_PAYMENTS or FACTURE_SUPPLIER_DEPOSITS_ARE_JUST_PAYMENTS is on (not recommended).
  496. *
  497. * @param CommonInvoice $invoice Object invoice (customer of supplier)
  498. * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount
  499. * @return int <0 if KO, Sum of credit notes and deposits amount otherwise
  500. */
  501. public function getSumDepositsUsed($invoice, $multicurrency = 0)
  502. {
  503. dol_syslog(get_class($this)."::getSumDepositsUsed", LOG_DEBUG);
  504. if ($invoice->element == 'facture' || $invoice->element == 'invoice') {
  505. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  506. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc, ".$this->db->prefix()."facture as f";
  507. $sql .= " WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = ".((int) $invoice->id);
  508. $sql .= " AND f.type = 3";
  509. } elseif ($invoice->element == 'invoice_supplier') {
  510. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  511. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc, ".$this->db->prefix()."facture_fourn as f";
  512. $sql .= " WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = ".((int) $invoice->id);
  513. $sql .= " AND f.type = 3";
  514. } else {
  515. $this->error = get_class($this)."::getSumDepositsUsed was called with a bad object as a first parameter";
  516. dol_print_error($this->error);
  517. return -1;
  518. }
  519. $resql = $this->db->query($sql);
  520. if ($resql) {
  521. $obj = $this->db->fetch_object($resql);
  522. if ($multicurrency == 1) {
  523. return $obj->multicurrency_amount;
  524. } else {
  525. return $obj->amount;
  526. }
  527. } else {
  528. $this->error = $this->db->lasterror();
  529. return -1;
  530. }
  531. }
  532. /**
  533. * Return amount (with tax) of all credit notes invoices + excess received used by invoice as a payment
  534. *
  535. * @param CommonInvoice $invoice Object invoice
  536. * @param int $multicurrency 1=Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount
  537. * @return int <0 if KO, Sum of credit notes and excess received amount otherwise
  538. */
  539. public function getSumCreditNotesUsed($invoice, $multicurrency = 0)
  540. {
  541. dol_syslog(get_class($this)."::getSumCreditNotesUsed", LOG_DEBUG);
  542. if ($invoice->element == 'facture' || $invoice->element == 'invoice') {
  543. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  544. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc, ".$this->db->prefix()."facture as f";
  545. $sql .= " WHERE rc.fk_facture_source=f.rowid AND rc.fk_facture = ".((int) $invoice->id);
  546. $sql .= " AND f.type IN (".$this->db->sanitize($invoice::TYPE_STANDARD.", ".$invoice::TYPE_CREDIT_NOTE.", ".$invoice::TYPE_SITUATION).")"; // Find discount coming from credit note or excess received
  547. } elseif ($invoice->element == 'invoice_supplier') {
  548. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  549. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc, ".$this->db->prefix()."facture_fourn as f";
  550. $sql .= " WHERE rc.fk_invoice_supplier_source=f.rowid AND rc.fk_invoice_supplier = ".((int) $invoice->id);
  551. $sql .= " AND f.type IN (".$this->db->sanitize($invoice::TYPE_STANDARD.", ".$invoice::TYPE_CREDIT_NOTE).")"; // Find discount coming from credit note or excess paid
  552. } else {
  553. $this->error = get_class($this)."::getSumCreditNotesUsed was called with a bad object as a first parameter";
  554. dol_print_error($this->error);
  555. return -1;
  556. }
  557. $resql = $this->db->query($sql);
  558. if ($resql) {
  559. $obj = $this->db->fetch_object($resql);
  560. if ($multicurrency == 1) {
  561. return $obj->multicurrency_amount;
  562. } else {
  563. return $obj->amount;
  564. }
  565. } else {
  566. $this->error = $this->db->lasterror();
  567. return -1;
  568. }
  569. }
  570. /**
  571. * Return amount (with tax) of all converted amount for this credit note
  572. *
  573. * @param CommonInvoice $invoice Object invoice
  574. * @param int $multicurrency Return multicurrency_amount instead of amount. TODO Add a mode multicurrency = -1 to return array with amount + multicurrency amount
  575. * @return int <0 if KO, Sum of credit notes and deposits amount otherwise
  576. */
  577. public function getSumFromThisCreditNotesNotUsed($invoice, $multicurrency = 0)
  578. {
  579. dol_syslog(get_class($this)."::getSumCreditNotesUsed", LOG_DEBUG);
  580. if ($invoice->element == 'facture' || $invoice->element == 'invoice') {
  581. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  582. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc";
  583. $sql .= " WHERE rc.fk_facture IS NULL AND rc.fk_facture_source = ".((int) $invoice->id);
  584. } elseif ($invoice->element == 'invoice_supplier') {
  585. $sql = "SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount";
  586. $sql .= " FROM ".$this->db->prefix()."societe_remise_except as rc";
  587. $sql .= " WHERE rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_source = ".((int) $invoice->id);
  588. } else {
  589. $this->error = get_class($this)."::getSumCreditNotesUsed was called with a bad object as a first parameter";
  590. dol_print_error($this->error);
  591. return -1;
  592. }
  593. $resql = $this->db->query($sql);
  594. if ($resql) {
  595. $obj = $this->db->fetch_object($resql);
  596. if ($multicurrency) {
  597. return $obj->multicurrency_amount;
  598. } else {
  599. return $obj->amount;
  600. }
  601. } else {
  602. $this->error = $this->db->lasterror();
  603. return -1;
  604. }
  605. }
  606. /**
  607. * Return clickable ref of object (with picto or not)
  608. *
  609. * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Picto only
  610. * @param string $option Where to link to ('invoice' or 'discount')
  611. * @return string String with URL
  612. */
  613. public function getNomUrl($withpicto, $option = 'invoice')
  614. {
  615. global $langs;
  616. $result = '';
  617. $link = '';
  618. $linkend = '';
  619. $label = '';
  620. $picto = '';
  621. $ref = '';
  622. if ($option == 'invoice') {
  623. $facid = !empty($this->discount_type) ? $this->fk_invoice_supplier_source : $this->fk_facture_source;
  624. $link = !empty($this->discount_type) ? '/fourn/facture/card.php' : '/compta/facture/card.php';
  625. $label = $langs->trans("ShowSourceInvoice").': '.$this->ref_facture_source;
  626. $link = '<a href="'.DOL_URL_ROOT.$link.'?facid='.$facid.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
  627. $linkend = '</a>';
  628. $ref = !empty($this->discount_type) ? $this->ref_invoice_supplier_source : $this->ref_facture_source;
  629. $picto = 'bill';
  630. }
  631. if ($option == 'discount') {
  632. $label = $langs->trans("Discount");
  633. $link = '<a href="'.DOL_URL_ROOT.'/comm/remx.php?id='.$this->fk_soc.'" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
  634. $linkend = '</a>';
  635. $ref = $langs->trans("Discount");
  636. $picto = 'generic';
  637. }
  638. if ($withpicto) {
  639. $result .= ($link.img_object($label, $picto, 'class="classfortooltip"').$linkend);
  640. }
  641. if ($withpicto && $withpicto != 2) {
  642. $result .= ' ';
  643. }
  644. $result .= $link.$ref.$linkend;
  645. return $result;
  646. }
  647. /**
  648. * Initialise an instance with random values.
  649. * Used to build previews or test instances.
  650. * id must be 0 if object instance is a specimen.
  651. *
  652. * @return void
  653. */
  654. public function initAsSpecimen()
  655. {
  656. global $user, $langs, $conf;
  657. $this->fk_soc = 1;
  658. $this->amount_ht = 10;
  659. $this->amount_tva = 1.96;
  660. $this->amount_ttc = 11.96;
  661. $this->tva_tx = 19.6;
  662. $this->description = 'Specimen discount';
  663. }
  664. }