productcustomerprice.class.php 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. <?php
  2. /* Copyright (C) 2007-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2014 Florian Henry <florian.henry@open-concept.pro>
  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/product/class/productcustomerprice.class.php
  20. * \ingroup produit
  21. * \brief File of class to manage predefined price products or services by customer
  22. */
  23. require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php';
  24. /**
  25. * File of class to manage predefined price products or services by customer
  26. */
  27. class Productcustomerprice extends CommonObject
  28. {
  29. /**
  30. * @var string ID to identify managed object
  31. */
  32. public $element = 'product_customer_price';
  33. /**
  34. * @var string Name of table without prefix where object is stored
  35. */
  36. public $table_element = 'product_customer_price';
  37. /**
  38. * @var int Entity
  39. */
  40. public $entity;
  41. public $datec = '';
  42. public $tms = '';
  43. /**
  44. * @var int ID
  45. */
  46. public $fk_product;
  47. /**
  48. * @var int Thirdparty ID
  49. */
  50. public $fk_soc;
  51. /**
  52. * @var string Customer reference
  53. */
  54. public $ref_customer;
  55. public $price;
  56. public $price_ttc;
  57. public $price_min;
  58. public $price_min_ttc;
  59. public $price_base_type;
  60. public $tva_tx;
  61. public $recuperableonly;
  62. public $localtax1_type;
  63. public $localtax1_tx;
  64. public $localtax2_type;
  65. public $localtax2_tx;
  66. /**
  67. * @var int User ID
  68. */
  69. public $fk_user;
  70. public $lines = array();
  71. /**
  72. * Constructor
  73. *
  74. * @param DoliDb $db handler
  75. */
  76. public function __construct($db)
  77. {
  78. $this->db = $db;
  79. }
  80. /**
  81. * Create object into database
  82. *
  83. * @param User $user that creates
  84. * @param int $notrigger triggers after, 1=disable triggers
  85. * @param int $forceupdateaffiliate update price on each soc child
  86. * @return int <0 if KO, Id of created object if OK
  87. */
  88. public function create($user, $notrigger = 0, $forceupdateaffiliate = 0)
  89. {
  90. global $conf, $langs;
  91. $error = 0;
  92. // Clean parameters
  93. if (isset($this->entity)) {
  94. $this->entity = trim($this->entity);
  95. }
  96. if (isset($this->fk_product)) {
  97. $this->fk_product = trim($this->fk_product);
  98. }
  99. if (isset($this->fk_soc)) {
  100. $this->fk_soc = trim($this->fk_soc);
  101. }
  102. if (isset($this->ref_customer)) {
  103. $this->ref_customer = trim($this->ref_customer);
  104. }
  105. if (isset($this->price)) {
  106. $this->price = trim($this->price);
  107. }
  108. if (isset($this->price_ttc)) {
  109. $this->price_ttc = trim($this->price_ttc);
  110. }
  111. if (isset($this->price_min)) {
  112. $this->price_min = trim($this->price_min);
  113. }
  114. if (isset($this->price_min_ttc)) {
  115. $this->price_min_ttc = trim($this->price_min_ttc);
  116. }
  117. if (isset($this->price_base_type)) {
  118. $this->price_base_type = trim($this->price_base_type);
  119. }
  120. if (isset($this->tva_tx)) {
  121. $this->tva_tx = trim($this->tva_tx);
  122. }
  123. if (isset($this->recuperableonly)) {
  124. $this->recuperableonly = trim($this->recuperableonly);
  125. }
  126. if (isset($this->localtax1_tx)) {
  127. $this->localtax1_tx = trim($this->localtax1_tx);
  128. }
  129. if (isset($this->localtax2_tx)) {
  130. $this->localtax2_tx = trim($this->localtax2_tx);
  131. }
  132. if (isset($this->fk_user)) {
  133. $this->fk_user = trim($this->fk_user);
  134. }
  135. if (isset($this->import_key)) {
  136. $this->import_key = trim($this->import_key);
  137. }
  138. // Check parameters
  139. // Put here code to add control on parameters values
  140. if ($this->price != '' || $this->price == 0) {
  141. if ($this->price_base_type == 'TTC') {
  142. $this->price_ttc = price2num($this->price, 'MU');
  143. $this->price = price2num($this->price) / (1 + ($this->tva_tx / 100));
  144. $this->price = price2num($this->price, 'MU');
  145. if ($this->price_min != '' || $this->price_min == 0) {
  146. $this->price_min_ttc = price2num($this->price_min, 'MU');
  147. $this->price_min = price2num($this->price_min) / (1 + ($this->tva_tx / 100));
  148. $this->price_min = price2num($this->price_min, 'MU');
  149. } else {
  150. $this->price_min = 0;
  151. $this->price_min_ttc = 0;
  152. }
  153. } else {
  154. $this->price = price2num($this->price, 'MU');
  155. $this->price_ttc = ($this->recuperableonly != 1) ? price2num($this->price) * (1 + ($this->tva_tx / 100)) : $this->price;
  156. $this->price_ttc = price2num($this->price_ttc, 'MU');
  157. if ($this->price_min != '' || $this->price_min == 0) {
  158. $this->price_min = price2num($this->price_min, 'MU');
  159. $this->price_min_ttc = price2num($this->price_min) * (1 + ($this->tva_tx / 100));
  160. $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
  161. // print 'X'.$newminprice.'-'.$price_min;
  162. } else {
  163. $this->price_min = 0;
  164. $this->price_min_ttc = 0;
  165. }
  166. }
  167. }
  168. // Insert request
  169. $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_customer_price(";
  170. $sql .= "entity,";
  171. $sql .= "datec,";
  172. $sql .= "fk_product,";
  173. $sql .= "fk_soc,";
  174. $sql .= 'ref_customer,';
  175. $sql .= "price,";
  176. $sql .= "price_ttc,";
  177. $sql .= "price_min,";
  178. $sql .= "price_min_ttc,";
  179. $sql .= "price_base_type,";
  180. $sql .= "default_vat_code,";
  181. $sql .= "tva_tx,";
  182. $sql .= "recuperableonly,";
  183. $sql .= "localtax1_type,";
  184. $sql .= "localtax1_tx,";
  185. $sql .= "localtax2_type,";
  186. $sql .= "localtax2_tx,";
  187. $sql .= "fk_user,";
  188. $sql .= "import_key";
  189. $sql .= ") VALUES (";
  190. $sql .= " ".((int) $conf->entity).",";
  191. $sql .= " '".$this->db->idate(dol_now())."',";
  192. $sql .= " ".(!isset($this->fk_product) ? 'NULL' : "'".$this->db->escape($this->fk_product)."'").",";
  193. $sql .= " ".(!isset($this->fk_soc) ? 'NULL' : "'".$this->db->escape($this->fk_soc)."'").",";
  194. $sql .= " ".(!isset($this->ref_customer) ? 'NULL' : "'".$this->db->escape($this->ref_customer)."'").",";
  195. $sql .= " ".(empty($this->price) ? '0' : "'".$this->db->escape($this->price)."'").",";
  196. $sql .= " ".(empty($this->price_ttc) ? '0' : "'".$this->db->escape($this->price_ttc)."'").",";
  197. $sql .= " ".(empty($this->price_min) ? '0' : "'".$this->db->escape($this->price_min)."'").",";
  198. $sql .= " ".(empty($this->price_min_ttc) ? '0' : "'".$this->db->escape($this->price_min_ttc)."'").",";
  199. $sql .= " ".(!isset($this->price_base_type) ? 'NULL' : "'".$this->db->escape($this->price_base_type)."'").",";
  200. $sql .= " ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
  201. $sql .= " ".(!isset($this->tva_tx) ? 'NULL' : (empty($this->tva_tx) ? 0 : $this->tva_tx)).",";
  202. $sql .= " ".(!isset($this->recuperableonly) ? 'NULL' : "'".$this->db->escape($this->recuperableonly)."'").",";
  203. $sql .= " ".(empty($this->localtax1_type) ? "'0'" : "'".$this->db->escape($this->localtax1_type)."'").",";
  204. $sql .= " ".(!isset($this->localtax1_tx) ? 'NULL' : (empty($this->localtax1_tx) ? 0 : $this->localtax1_tx)).",";
  205. $sql .= " ".(empty($this->localtax2_type) ? "'0'" : "'".$this->db->escape($this->localtax2_type)."'").",";
  206. $sql .= " ".(!isset($this->localtax2_tx) ? 'NULL' : (empty($this->localtax2_tx) ? 0 : $this->localtax2_tx)).",";
  207. $sql .= " ".((int) $user->id).",";
  208. $sql .= " ".(!isset($this->import_key) ? 'NULL' : "'".$this->db->escape($this->import_key)."'")."";
  209. $sql .= ")";
  210. $this->db->begin();
  211. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  212. $resql = $this->db->query($sql);
  213. if (!$resql) {
  214. $error++;
  215. $this->errors [] = "Error ".$this->db->lasterror();
  216. }
  217. if (!$error) {
  218. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."product_customer_price");
  219. if (!$notrigger) {
  220. $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_CREATE', $user);
  221. if ($result < 0) {
  222. $error++;
  223. }
  224. }
  225. }
  226. if (!$error) {
  227. $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
  228. if ($result < 0) {
  229. $error++;
  230. }
  231. }
  232. // Commit or rollback
  233. if ($error) {
  234. foreach ($this->errors as $errmsg) {
  235. dol_syslog(get_class($this)."::create ".$errmsg, LOG_ERR);
  236. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  237. }
  238. $this->db->rollback();
  239. return -1 * $error;
  240. } else {
  241. $this->db->commit();
  242. return $this->id;
  243. }
  244. }
  245. /**
  246. * Load object in memory from the database
  247. *
  248. * @param int $id ID of customer price
  249. * @return int <0 if KO, 0 if not found, >0 if OK
  250. */
  251. public function fetch($id)
  252. {
  253. global $langs;
  254. $sql = "SELECT";
  255. $sql .= " t.rowid,";
  256. $sql .= " t.entity,";
  257. $sql .= " t.datec,";
  258. $sql .= " t.tms,";
  259. $sql .= " t.fk_product,";
  260. $sql .= " t.fk_soc,";
  261. $sql .= " t.ref_customer,";
  262. $sql .= " t.price,";
  263. $sql .= " t.price_ttc,";
  264. $sql .= " t.price_min,";
  265. $sql .= " t.price_min_ttc,";
  266. $sql .= " t.price_base_type,";
  267. $sql .= " t.default_vat_code,";
  268. $sql .= " t.tva_tx,";
  269. $sql .= " t.recuperableonly,";
  270. $sql .= " t.localtax1_tx,";
  271. $sql .= " t.localtax2_tx,";
  272. $sql .= " t.fk_user,";
  273. $sql .= " t.import_key";
  274. $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price as t";
  275. $sql .= " WHERE t.rowid = ".((int) $id);
  276. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  277. $resql = $this->db->query($sql);
  278. if ($resql) {
  279. if ($this->db->num_rows($resql)) {
  280. $obj = $this->db->fetch_object($resql);
  281. $this->id = $obj->rowid;
  282. $this->entity = $obj->entity;
  283. $this->datec = $this->db->jdate($obj->datec);
  284. $this->tms = $this->db->jdate($obj->tms);
  285. $this->fk_product = $obj->fk_product;
  286. $this->fk_soc = $obj->fk_soc;
  287. $this->ref_customer = $obj->ref_customer;
  288. $this->price = $obj->price;
  289. $this->price_ttc = $obj->price_ttc;
  290. $this->price_min = $obj->price_min;
  291. $this->price_min_ttc = $obj->price_min_ttc;
  292. $this->price_base_type = $obj->price_base_type;
  293. $this->default_vat_code = $obj->default_vat_code;
  294. $this->tva_tx = $obj->tva_tx;
  295. $this->recuperableonly = $obj->recuperableonly;
  296. $this->localtax1_tx = $obj->localtax1_tx;
  297. $this->localtax2_tx = $obj->localtax2_tx;
  298. $this->fk_user = $obj->fk_user;
  299. $this->import_key = $obj->import_key;
  300. $this->db->free($resql);
  301. return 1;
  302. } else {
  303. $this->db->free($resql);
  304. return 0;
  305. }
  306. } else {
  307. $this->error = "Error ".$this->db->lasterror();
  308. return -1;
  309. }
  310. }
  311. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  312. /**
  313. * Load all customer prices in memory from database
  314. *
  315. * @param string $sortorder order
  316. * @param string $sortfield field
  317. * @param int $limit page
  318. * @param int $offset offset
  319. * @param array $filter Filter for select
  320. * @return int <0 if KO, >0 if OK
  321. */
  322. public function fetch_all($sortorder = '', $sortfield = '', $limit = 0, $offset = 0, $filter = array())
  323. {
  324. // phpcs:enable
  325. global $langs;
  326. if (empty($sortfield)) {
  327. $sortfield = "t.rowid";
  328. }
  329. if (empty($sortorder)) {
  330. $sortorder = "DESC";
  331. }
  332. $sql = "SELECT";
  333. $sql .= " t.rowid,";
  334. $sql .= " t.entity,";
  335. $sql .= " t.datec,";
  336. $sql .= " t.tms,";
  337. $sql .= " t.fk_product,";
  338. $sql .= " t.fk_soc,";
  339. $sql .= " t.ref_customer,";
  340. $sql .= " t.price,";
  341. $sql .= " t.price_ttc,";
  342. $sql .= " t.price_min,";
  343. $sql .= " t.price_min_ttc,";
  344. $sql .= " t.price_base_type,";
  345. $sql .= " t.default_vat_code,";
  346. $sql .= " t.tva_tx,";
  347. $sql .= " t.recuperableonly,";
  348. $sql .= " t.localtax1_tx,";
  349. $sql .= " t.localtax2_tx,";
  350. $sql .= " t.localtax1_type,";
  351. $sql .= " t.localtax2_type,";
  352. $sql .= " t.fk_user,";
  353. $sql .= " t.import_key,";
  354. $sql .= " soc.nom as socname,";
  355. $sql .= " prod.ref as prodref";
  356. $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price as t ";
  357. $sql .= " ,".MAIN_DB_PREFIX."product as prod ";
  358. $sql .= " ,".MAIN_DB_PREFIX."societe as soc ";
  359. $sql .= " WHERE soc.rowid=t.fk_soc ";
  360. $sql .= " AND prod.rowid=t.fk_product ";
  361. $sql .= " AND prod.entity IN (".getEntity('product').")";
  362. $sql .= " AND t.entity IN (".getEntity('productprice').")";
  363. // Manage filter
  364. if (count($filter) > 0) {
  365. foreach ($filter as $key => $value) {
  366. if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
  367. $sql .= " AND ".$key." = '".$this->db->escape($value)."'";
  368. } elseif ($key == 'soc.nom') {
  369. $sql .= " AND ".$key." LIKE '%".$this->db->escape($value)."%'";
  370. } elseif ($key == 'prod.ref' || $key == 'prod.label') {
  371. $sql .= " AND ".$key." LIKE '%".$this->db->escape($value)."%'";
  372. } elseif ($key == 't.price' || $key == 't.price_ttc') {
  373. $sql .= " AND ".$key." LIKE '%".price2num($value)."%'";
  374. } else {
  375. $sql .= " AND ".$key." = ".((int) $value);
  376. }
  377. }
  378. }
  379. $sql .= $this->db->order($sortfield, $sortorder);
  380. if (!empty($limit)) {
  381. $sql .= $this->db->plimit($limit + 1, $offset);
  382. }
  383. dol_syslog(get_class($this)."::fetch_all", LOG_DEBUG);
  384. $resql = $this->db->query($sql);
  385. if ($resql) {
  386. $this->lines = array();
  387. $num = $this->db->num_rows($resql);
  388. while ($obj = $this->db->fetch_object($resql)) {
  389. $line = new PriceByCustomerLine();
  390. $line->id = $obj->rowid;
  391. $line->entity = $obj->entity;
  392. $line->datec = $this->db->jdate($obj->datec);
  393. $line->tms = $this->db->jdate($obj->tms);
  394. $line->fk_product = $obj->fk_product;
  395. $line->fk_soc = $obj->fk_soc;
  396. $line->ref_customer = $obj->ref_customer;
  397. $line->price = $obj->price;
  398. $line->price_ttc = $obj->price_ttc;
  399. $line->price_min = $obj->price_min;
  400. $line->price_min_ttc = $obj->price_min_ttc;
  401. $line->price_base_type = $obj->price_base_type;
  402. $line->default_vat_code = $obj->default_vat_code;
  403. $line->tva_tx = $obj->tva_tx;
  404. $line->recuperableonly = $obj->recuperableonly;
  405. $line->localtax1_tx = $obj->localtax1_tx;
  406. $line->localtax2_tx = $obj->localtax2_tx;
  407. $line->localtax1_type = $obj->localtax1_type;
  408. $line->localtax2_type = $obj->localtax2_type;
  409. $line->fk_user = $obj->fk_user;
  410. $line->import_key = $obj->import_key;
  411. $line->socname = $obj->socname;
  412. $line->prodref = $obj->prodref;
  413. $this->lines[] = $line;
  414. }
  415. $this->db->free($resql);
  416. return $num;
  417. } else {
  418. $this->error = "Error ".$this->db->lasterror();
  419. return -1;
  420. }
  421. }
  422. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  423. /**
  424. * Load all objects in memory from database
  425. *
  426. * @param string $sortorder order
  427. * @param string $sortfield field
  428. * @param int $limit page
  429. * @param int $offset offset
  430. * @param array $filter Filter for sql request
  431. * @return int <0 if KO, >0 if OK
  432. */
  433. public function fetch_all_log($sortorder, $sortfield, $limit, $offset, $filter = array())
  434. {
  435. // phpcs:enable
  436. global $langs;
  437. if (!empty($sortfield)) {
  438. $sortfield = "t.rowid";
  439. }
  440. if (!empty($sortorder)) {
  441. $sortorder = "DESC";
  442. }
  443. $sql = "SELECT";
  444. $sql .= " t.rowid,";
  445. $sql .= " t.entity,";
  446. $sql .= " t.datec,";
  447. $sql .= " t.fk_product,";
  448. $sql .= " t.fk_soc,";
  449. $sql .= " t.ref_customer,";
  450. $sql .= " t.price,";
  451. $sql .= " t.price_ttc,";
  452. $sql .= " t.price_min,";
  453. $sql .= " t.price_min_ttc,";
  454. $sql .= " t.price_base_type,";
  455. $sql .= " t.default_vat_code,";
  456. $sql .= " t.tva_tx,";
  457. $sql .= " t.recuperableonly,";
  458. $sql .= " t.localtax1_tx,";
  459. $sql .= " t.localtax2_tx,";
  460. $sql .= " t.fk_user,";
  461. $sql .= " t.import_key,";
  462. $sql .= " soc.nom as socname,";
  463. $sql .= " prod.ref as prodref";
  464. $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price_log as t";
  465. $sql .= " ,".MAIN_DB_PREFIX."product as prod";
  466. $sql .= " ,".MAIN_DB_PREFIX."societe as soc";
  467. $sql .= " WHERE soc.rowid=t.fk_soc";
  468. $sql .= " AND prod.rowid=t.fk_product ";
  469. $sql .= " AND prod.entity IN (".getEntity('product').")";
  470. $sql .= " AND t.entity IN (".getEntity('productprice').")";
  471. // Manage filter
  472. if (count($filter) > 0) {
  473. foreach ($filter as $key => $value) {
  474. if (strpos($key, 'date')) { // To allow $filter['YEAR(s.dated)']=>$year
  475. $sql .= " AND ".$key." = '".$db->escape($value)."'";
  476. } elseif ($key == 'soc.nom') {
  477. $sql .= " AND ".$key." LIKE '%".$this->db->escape($value)."%'";
  478. } else {
  479. $sql .= " AND ".$key." = ".((int) $value);
  480. }
  481. }
  482. }
  483. $sql .= $this->db->order($sortfield, $sortorder);
  484. if (!empty($limit)) {
  485. $sql .= $this->db->plimit($limit + 1, $offset);
  486. }
  487. dol_syslog(get_class($this)."::fetch_all_log", LOG_DEBUG);
  488. $resql = $this->db->query($sql);
  489. if ($resql) {
  490. $this->lines = array();
  491. $num = $this->db->num_rows($resql);
  492. while ($obj = $this->db->fetch_object($resql)) {
  493. $line = new PriceByCustomerLine();
  494. $line->id = $obj->rowid;
  495. $line->entity = $obj->entity;
  496. $line->datec = $this->db->jdate($obj->datec);
  497. $line->tms = $this->db->jdate($obj->tms);
  498. $line->fk_product = $obj->fk_product;
  499. $line->fk_soc = $obj->fk_soc;
  500. $line->ref_customer = $obj->ref_customer;
  501. $line->price = $obj->price;
  502. $line->price_ttc = $obj->price_ttc;
  503. $line->price_min = $obj->price_min;
  504. $line->price_min_ttc = $obj->price_min_ttc;
  505. $line->price_base_type = $obj->price_base_type;
  506. $line->default_vat_code = $obj->default_vat_code;
  507. $line->tva_tx = $obj->tva_tx;
  508. $line->recuperableonly = $obj->recuperableonly;
  509. $line->localtax1_tx = $obj->localtax1_tx;
  510. $line->localtax2_tx = $obj->localtax2_tx;
  511. $line->fk_user = $obj->fk_user;
  512. $line->import_key = $obj->import_key;
  513. $line->socname = $obj->socname;
  514. $line->prodref = $obj->prodref;
  515. $this->lines [] = $line;
  516. }
  517. $this->db->free($resql);
  518. return $num;
  519. } else {
  520. $this->error = "Error ".$this->db->lasterror();
  521. return -1;
  522. }
  523. }
  524. /**
  525. * Update object into database
  526. *
  527. * @param User $user that modifies
  528. * @param int $notrigger triggers after, 1=disable triggers
  529. * @param int $forceupdateaffiliate update price on each soc child
  530. * @return int <0 if KO, >0 if OK
  531. */
  532. public function update($user = 0, $notrigger = 0, $forceupdateaffiliate = 0)
  533. {
  534. global $conf, $langs;
  535. $error = 0;
  536. // Clean parameters
  537. if (isset($this->entity)) {
  538. $this->entity = trim($this->entity);
  539. }
  540. if (isset($this->fk_product)) {
  541. $this->fk_product = trim($this->fk_product);
  542. }
  543. if (isset($this->fk_soc)) {
  544. $this->fk_soc = trim($this->fk_soc);
  545. }
  546. if (isset($this->ref_customer)) {
  547. $this->ref_customer = trim($this->ref_customer);
  548. }
  549. if (isset($this->price)) {
  550. $this->price = trim($this->price);
  551. }
  552. if (isset($this->price_ttc)) {
  553. $this->price_ttc = trim($this->price_ttc);
  554. }
  555. if (isset($this->price_min)) {
  556. $this->price_min = trim($this->price_min);
  557. }
  558. if (isset($this->price_min_ttc)) {
  559. $this->price_min_ttc = trim($this->price_min_ttc);
  560. }
  561. if (isset($this->price_base_type)) {
  562. $this->price_base_type = trim($this->price_base_type);
  563. }
  564. if (isset($this->tva_tx)) {
  565. $this->tva_tx = trim($this->tva_tx);
  566. }
  567. if (isset($this->recuperableonly)) {
  568. $this->recuperableonly = trim($this->recuperableonly);
  569. }
  570. if (isset($this->localtax1_tx)) {
  571. $this->localtax1_tx = trim($this->localtax1_tx);
  572. }
  573. if (isset($this->localtax2_tx)) {
  574. $this->localtax2_tx = trim($this->localtax2_tx);
  575. }
  576. if (isset($this->fk_user)) {
  577. $this->fk_user = trim($this->fk_user);
  578. }
  579. if (isset($this->import_key)) {
  580. $this->import_key = trim($this->import_key);
  581. }
  582. // Check parameters
  583. // Put here code to add a control on parameters values
  584. if ($this->price != '' || $this->price == 0) {
  585. if ($this->price_base_type == 'TTC') {
  586. $this->price_ttc = price2num($this->price, 'MU');
  587. $this->price = price2num($this->price) / (1 + ($this->tva_tx / 100));
  588. $this->price = price2num($this->price, 'MU');
  589. if ($this->price_min != '' || $this->price_min == 0) {
  590. $this->price_min_ttc = price2num($this->price_min, 'MU');
  591. $this->price_min = price2num($this->price_min) / (1 + ($this->tva_tx / 100));
  592. $this->price_min = price2num($this->price_min, 'MU');
  593. } else {
  594. $this->price_min = 0;
  595. $this->price_min_ttc = 0;
  596. }
  597. } else {
  598. $this->price = price2num($this->price, 'MU');
  599. $this->price_ttc = ($this->recuperableonly != 1) ? price2num($this->price) * (1 + ($this->tva_tx / 100)) : $this->price;
  600. $this->price_ttc = price2num($this->price_ttc, 'MU');
  601. if ($this->price_min != '' || $this->price_min == 0) {
  602. $this->price_min = price2num($this->price_min, 'MU');
  603. $this->price_min_ttc = price2num($this->price_min) * (1 + ($this->tva_tx / 100));
  604. $this->price_min_ttc = price2num($this->price_min_ttc, 'MU');
  605. // print 'X'.$newminprice.'-'.$price_min;
  606. } else {
  607. $this->price_min = 0;
  608. $this->price_min_ttc = 0;
  609. }
  610. }
  611. }
  612. // Do a copy of current record into log table
  613. // Insert request
  614. $sql = "INSERT INTO ".MAIN_DB_PREFIX."product_customer_price_log(";
  615. $sql .= "entity,";
  616. $sql .= "datec,";
  617. $sql .= "fk_product,";
  618. $sql .= "fk_soc,";
  619. $sql .= "ref_customer,";
  620. $sql .= "price,";
  621. $sql .= "price_ttc,";
  622. $sql .= "price_min,";
  623. $sql .= "price_min_ttc,";
  624. $sql .= "price_base_type,";
  625. $sql .= "default_vat_code,";
  626. $sql .= "tva_tx,";
  627. $sql .= "recuperableonly,";
  628. $sql .= "localtax1_tx,";
  629. $sql .= "localtax2_tx,";
  630. $sql .= "localtax1_type,";
  631. $sql .= "localtax2_type,";
  632. $sql .= "fk_user,";
  633. $sql .= "import_key";
  634. $sql .= ") ";
  635. $sql .= "SELECT";
  636. $sql .= " t.entity,";
  637. $sql .= " t.datec,";
  638. $sql .= " t.fk_product,";
  639. $sql .= " t.fk_soc,";
  640. $sql .= " t.ref_customer,";
  641. $sql .= " t.price,";
  642. $sql .= " t.price_ttc,";
  643. $sql .= " t.price_min,";
  644. $sql .= " t.price_min_ttc,";
  645. $sql .= " t.price_base_type,";
  646. $sql .= " t.default_vat_code,";
  647. $sql .= " t.tva_tx,";
  648. $sql .= " t.recuperableonly,";
  649. $sql .= " t.localtax1_tx,";
  650. $sql .= " t.localtax2_tx,";
  651. $sql .= " t.localtax1_type,";
  652. $sql .= " t.localtax2_type,";
  653. $sql .= " t.fk_user,";
  654. $sql .= " t.import_key";
  655. $sql .= " FROM ".MAIN_DB_PREFIX."product_customer_price as t";
  656. $sql .= " WHERE t.rowid = ".((int) $this->id);
  657. $this->db->begin();
  658. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  659. $resql = $this->db->query($sql);
  660. if (!$resql) {
  661. $error++;
  662. $this->errors [] = "Error ".$this->db->lasterror();
  663. }
  664. // Update request
  665. $sql = "UPDATE ".MAIN_DB_PREFIX."product_customer_price SET";
  666. $sql .= " entity=".$conf->entity.",";
  667. $sql .= " datec='".$this->db->idate(dol_now())."',";
  668. $sql .= " tms=".(dol_strlen($this->tms) != 0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
  669. $sql .= " fk_product=".(isset($this->fk_product) ? $this->fk_product : "null").",";
  670. $sql .= " fk_soc=".(isset($this->fk_soc) ? $this->fk_soc : "null").",";
  671. $sql .= " ref_customer=".(isset($this->ref_customer) ? "'" . $this->db->escape($this->ref_customer) . "'" : "null").",";
  672. $sql .= " price=".(isset($this->price) ? $this->price : "null").",";
  673. $sql .= " price_ttc=".(isset($this->price_ttc) ? $this->price_ttc : "null").",";
  674. $sql .= " price_min=".(isset($this->price_min) ? $this->price_min : "null").",";
  675. $sql .= " price_min_ttc=".(isset($this->price_min_ttc) ? $this->price_min_ttc : "null").",";
  676. $sql .= " price_base_type=".(isset($this->price_base_type) ? "'".$this->db->escape($this->price_base_type)."'" : "null").",";
  677. $sql .= " default_vat_code = ".($this->default_vat_code ? "'".$this->db->escape($this->default_vat_code)."'" : "null").",";
  678. $sql .= " tva_tx=".(isset($this->tva_tx) ? (empty($this->tva_tx) ? 0 : $this->tva_tx) : "null").",";
  679. $sql .= " recuperableonly=".(isset($this->recuperableonly) ? $this->recuperableonly : "null").",";
  680. $sql .= " localtax1_tx=".(isset($this->localtax1_tx) ? (empty($this->localtax1_tx) ? 0 : $this->localtax1_tx) : "null").",";
  681. $sql .= " localtax2_tx=".(isset($this->localtax2_tx) ? (empty($this->localtax2_tx) ? 0 : $this->localtax2_tx) : "null").",";
  682. $sql .= " localtax1_type=".(!empty($this->localtax1_type) ? "'".$this->db->escape($this->localtax1_type)."'" : "'0'").",";
  683. $sql .= " localtax2_type=".(!empty($this->localtax2_type) ? "'".$this->db->escape($this->localtax2_type)."'" : "'0'").",";
  684. $sql .= " fk_user=".$user->id.",";
  685. $sql .= " import_key=".(isset($this->import_key) ? "'".$this->db->escape($this->import_key)."'" : "null")."";
  686. $sql .= " WHERE rowid=".((int) $this->id);
  687. dol_syslog(get_class($this)."::update", LOG_DEBUG);
  688. $resql = $this->db->query($sql);
  689. if (!$resql) {
  690. $error++;
  691. $this->errors [] = "Error ".$this->db->lasterror();
  692. }
  693. if (!$error && !$notrigger) {
  694. // Call trigger
  695. $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_UPDATE', $user);
  696. if ($result < 0) {
  697. $error++;
  698. }
  699. // End call triggers
  700. }
  701. if (!$error) {
  702. $result = $this->setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate);
  703. if ($result < 0) {
  704. $error++;
  705. }
  706. }
  707. // Commit or rollback
  708. if ($error) {
  709. foreach ($this->errors as $errmsg) {
  710. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  711. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  712. }
  713. $this->db->rollback();
  714. return -1 * $error;
  715. } else {
  716. $this->db->commit();
  717. return 1;
  718. }
  719. }
  720. /**
  721. * Force update price on child companies so child company has same prices than parent.
  722. *
  723. * @param User $user that modifies
  724. * @param int $forceupdateaffiliate update price on each soc child
  725. * @return int <0 if KO, 0 = action disabled, >0 if OK
  726. */
  727. public function setPriceOnAffiliateThirdparty($user, $forceupdateaffiliate)
  728. {
  729. global $conf;
  730. if (!empty($conf->global->PRODUCT_DISABLE_PROPAGATE_CUSTOMER_PRICES_ON_CHILD_COMPANIES)) {
  731. return 0;
  732. }
  733. $error = 0;
  734. // Find all susidiaries
  735. $sql = "SELECT s.rowid";
  736. $sql .= " FROM ".MAIN_DB_PREFIX."societe as s";
  737. $sql .= " WHERE s.parent = ".((int) $this->fk_soc);
  738. $sql .= " AND s.entity IN (".getEntity('societe').")";
  739. dol_syslog(get_class($this)."::setPriceOnAffiliateThirdparty", LOG_DEBUG);
  740. $resql = $this->db->query($sql);
  741. if ($resql) {
  742. $this->lines = array();
  743. $num = $this->db->num_rows($resql);
  744. while (($obj = $this->db->fetch_object($resql)) && (empty($error))) {
  745. // find if there is an existing line for the product and the subsidiaries
  746. $prodsocprice = new Productcustomerprice($this->db);
  747. $filter = array(
  748. 't.fk_product' => $this->fk_product, 't.fk_soc' => $obj->rowid
  749. );
  750. $result = $prodsocprice->fetch_all('', '', 0, 0, $filter);
  751. if ($result < 0) {
  752. $error++;
  753. $this->error = $prodsocprice->error;
  754. } else {
  755. // There is one line
  756. if (count($prodsocprice->lines) > 0) {
  757. // If force update => Update
  758. if (!empty($forceupdateaffiliate)) {
  759. $prodsocpriceupd = new Productcustomerprice($this->db);
  760. $prodsocpriceupd->fetch($prodsocprice->lines [0]->id);
  761. $prodsocpriceupd->price = $this->price;
  762. $prodsocpriceupd->price_min = $this->price_min;
  763. $prodsocpriceupd->price_base_type = $this->price_base_type;
  764. $prodsocpriceupd->tva_tx = $this->tva_tx;
  765. $prodsocpriceupd->recuperableonly = $this->recuperableonly;
  766. $resultupd = $prodsocpriceupd->update($user, 0, $forceupdateaffiliate);
  767. if ($result < 0) {
  768. $error++;
  769. $this->error = $prodsocpriceupd->error;
  770. }
  771. }
  772. } else {
  773. // If line do not exits then create it
  774. $prodsocpricenew = new Productcustomerprice($this->db);
  775. $prodsocpricenew->fk_soc = $obj->rowid;
  776. $prodsocpricenew->ref_customer = $obj->ref_customer;
  777. $prodsocpricenew->fk_product = $this->fk_product;
  778. $prodsocpricenew->price = $this->price;
  779. $prodsocpricenew->price_min = $this->price_min;
  780. $prodsocpricenew->price_base_type = $this->price_base_type;
  781. $prodsocpricenew->tva_tx = $this->tva_tx;
  782. $prodsocpricenew->recuperableonly = $this->recuperableonly;
  783. $resultupd = $prodsocpricenew->create($user, 0, $forceupdateaffiliate);
  784. if ($result < 0) {
  785. $error++;
  786. $this->error = $prodsocpriceupd->error;
  787. }
  788. }
  789. }
  790. }
  791. $this->db->free($resql);
  792. if (empty($error)) {
  793. return 1;
  794. } else {
  795. return -1;
  796. }
  797. } else {
  798. $this->error = "Error ".$this->db->lasterror();
  799. return -1;
  800. }
  801. }
  802. /**
  803. * Delete object in database
  804. *
  805. * @param User $user that deletes
  806. * @param int $notrigger triggers after, 1=disable triggers
  807. * @return int <0 if KO, >0 if OK
  808. */
  809. public function delete($user, $notrigger = 0)
  810. {
  811. global $conf, $langs;
  812. $error = 0;
  813. $this->db->begin();
  814. if (!$error && !$notrigger) {
  815. $result = $this->call_trigger('PRODUCT_CUSTOMER_PRICE_DELETE', $user);
  816. if ($result < 0) {
  817. $error++;
  818. }
  819. }
  820. if (!$error) {
  821. $sql = "DELETE FROM ".MAIN_DB_PREFIX."product_customer_price";
  822. $sql .= " WHERE rowid=".((int) $this->id);
  823. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  824. $resql = $this->db->query($sql);
  825. if (!$resql) {
  826. $error++;
  827. $this->errors [] = "Error ".$this->db->lasterror();
  828. }
  829. }
  830. // Commit or rollback
  831. if ($error) {
  832. foreach ($this->errors as $errmsg) {
  833. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  834. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  835. }
  836. $this->db->rollback();
  837. return -1 * $error;
  838. } else {
  839. $this->db->commit();
  840. return 1;
  841. }
  842. }
  843. /**
  844. * Load an object from its id and create a new one in database
  845. *
  846. * @param User $user User making the clone
  847. * @param int $fromid ID of object to clone
  848. * @return int id of clone
  849. */
  850. public function createFromClone(User $user, $fromid)
  851. {
  852. $error = 0;
  853. $object = new Productcustomerprice($this->db);
  854. $this->db->begin();
  855. // Load source object
  856. $object->fetch($fromid);
  857. $object->id = 0;
  858. $object->statut = 0;
  859. // Clear fields
  860. // ...
  861. // Create clone
  862. $object->context['createfromclone'] = 'createfromclone';
  863. $result = $object->create($user);
  864. // Other options
  865. if ($result < 0) {
  866. $this->error = $object->error;
  867. $this->errors = array_merge($this->errors, $object->errors);
  868. $error++;
  869. }
  870. if (!$error) {
  871. }
  872. unset($object->context['createfromclone']);
  873. // End
  874. if (!$error) {
  875. $this->db->commit();
  876. return $object->id;
  877. } else {
  878. $this->db->rollback();
  879. return -1;
  880. }
  881. }
  882. /**
  883. * Initialise object with example values
  884. * Id must be 0 if object instance is a specimen
  885. *
  886. * @return void
  887. */
  888. public function initAsSpecimen()
  889. {
  890. $this->id = 0;
  891. $this->entity = '';
  892. $this->datec = '';
  893. $this->tms = '';
  894. $this->fk_product = '';
  895. $this->fk_soc = '';
  896. $this->ref_customer = '';
  897. $this->price = '';
  898. $this->price_ttc = '';
  899. $this->price_min = '';
  900. $this->price_min_ttc = '';
  901. $this->price_base_type = '';
  902. $this->default_vat_code = '';
  903. $this->tva_tx = '';
  904. $this->recuperableonly = '';
  905. $this->localtax1_tx = '';
  906. $this->localtax2_tx = '';
  907. $this->fk_user = '';
  908. $this->import_key = '';
  909. }
  910. }
  911. /**
  912. * File of class to manage predefined price products or services by customer lines
  913. */
  914. class PriceByCustomerLine
  915. {
  916. /**
  917. * @var int ID
  918. */
  919. public $id;
  920. /**
  921. * @var int Entity
  922. */
  923. public $entity;
  924. public $datec = '';
  925. public $tms = '';
  926. /**
  927. * @var int ID
  928. */
  929. public $fk_product;
  930. /**
  931. * @var string Customer reference
  932. */
  933. public $ref_customer;
  934. /**
  935. * @var int Thirdparty ID
  936. */
  937. public $fk_soc;
  938. public $price;
  939. public $price_ttc;
  940. public $price_min;
  941. public $price_min_ttc;
  942. public $price_base_type;
  943. public $default_vat_code;
  944. public $tva_tx;
  945. public $recuperableonly;
  946. public $localtax1_tx;
  947. public $localtax2_tx;
  948. /**
  949. * @var int User ID
  950. */
  951. public $fk_user;
  952. public $import_key;
  953. public $socname;
  954. public $prodref;
  955. }