PageRenderTime 65ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/comm/propal/class/propal.class.php

https://github.com/zeert/dolibarr
PHP | 2847 lines | 2041 code | 327 blank | 479 comment | 290 complexity | 45466bd1f91db1ac48682924c957143c MD5 | raw file
Possible License(s): LGPL-2.0

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /* Copyright (C) 2002-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  4. * Copyright (C) 2004-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  5. * Copyright (C) 2005 Marc Barilley <marc@ocebo.com>
  6. * Copyright (C) 2005-2012 Regis Houssin <regis@dolibarr.fr>
  7. * Copyright (C) 2006 Andre Cianfarani <acianfa@free.fr>
  8. * Copyright (C) 2008 Raphael Bertrand <raphael.bertrand@resultic.fr>
  9. * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
  10. * Copyright (C) 2010-2011 Philippe Grand <philippe.grand@atoo-net.com>
  11. * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  25. */
  26. /**
  27. * \file htdocs/comm/propal/class/propal.class.php
  28. * \brief Fichier de la classe des propales
  29. */
  30. require_once(DOL_DOCUMENT_ROOT ."/core/class/commonobject.class.php");
  31. require_once(DOL_DOCUMENT_ROOT ."/product/class/product.class.php");
  32. require_once(DOL_DOCUMENT_ROOT ."/contact/class/contact.class.php");
  33. require_once(DOL_DOCUMENT_ROOT ."/margin/lib/margins.lib.php");
  34. /**
  35. * \class Propal
  36. * \brief Classe permettant la gestion des propales
  37. */
  38. class Propal extends CommonObject
  39. {
  40. public $element='propal';
  41. public $table_element='propal';
  42. public $table_element_line='propaldet';
  43. public $fk_element='fk_propal';
  44. protected $ismultientitymanaged = 1; // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  45. var $id;
  46. var $socid; // Id client
  47. var $client; // Objet societe client (a charger par fetch_client)
  48. var $contactid;
  49. var $fk_project;
  50. var $author;
  51. var $ref;
  52. var $ref_client;
  53. var $statut; // 0 (draft), 1 (validated), 2 (signed), 3 (not signed), 4 (billed)
  54. var $datec; // Date of creation
  55. var $datev; // Date of validation
  56. var $date; // Date of proposal
  57. var $datep; // Same than date
  58. var $date_livraison;
  59. var $fin_validite;
  60. var $user_author_id;
  61. var $user_valid_id;
  62. var $user_close_id;
  63. var $total_ht; // Total net of tax
  64. var $total_tva; // Total VAT
  65. var $total_localtax1; // Total Local Taxes 1
  66. var $total_localtax2; // Total Local Taxes 2
  67. var $total_ttc; // Total with tax
  68. var $price; // deprecated (for compatibility)
  69. var $tva; // deprecated (for compatibility)
  70. var $total; // deprecated (for compatibility)
  71. var $cond_reglement_id;
  72. var $cond_reglement_code;
  73. var $mode_reglement_id;
  74. var $mode_reglement_code;
  75. var $remise;
  76. var $remise_percent;
  77. var $remise_absolue;
  78. var $note; // deprecated (for compatibility)
  79. var $note_private;
  80. var $note_public;
  81. var $fk_delivery_address; // deprecated (for compatibility)
  82. var $fk_address;
  83. var $address_type;
  84. var $adresse;
  85. var $availability_id;
  86. var $availability_code;
  87. var $demand_reason_id;
  88. var $demand_reason_code;
  89. var $products=array();
  90. var $extraparams=array();
  91. var $lines = array();
  92. var $line;
  93. var $origin;
  94. var $origin_id;
  95. var $labelstatut=array();
  96. var $labelstatut_short=array();
  97. // Pour board
  98. var $nbtodo;
  99. var $nbtodolate;
  100. var $specimen;
  101. /**
  102. * Constructor
  103. *
  104. * @param DoliDB $db Database handler
  105. * @param int $socid Id third party
  106. * @param int $propalid Id proposal
  107. */
  108. function __construct($db, $socid="", $propalid=0)
  109. {
  110. global $conf,$langs;
  111. $this->db = $db;
  112. $this->socid = $socid;
  113. $this->id = $propalid;
  114. $this->products = array();
  115. $this->remise = 0;
  116. $this->remise_percent = 0;
  117. $this->remise_absolue = 0;
  118. $this->duree_validite=$conf->global->PROPALE_VALIDITY_DURATION;
  119. $langs->load("propal");
  120. $this->labelstatut[0]=(! empty($conf->global->PROPAL_STATUS_DRAFT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFT_LABEL : $langs->trans("PropalStatusDraft"));
  121. $this->labelstatut[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATED_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATED_LABEL : $langs->trans("PropalStatusValidated"));
  122. $this->labelstatut[2]=(! empty($conf->global->PROPAL_STATUS_SIGNED_LABEL) ? $conf->global->PROPAL_STATUS_SIGNED_LABEL : $langs->trans("PropalStatusSigned"));
  123. $this->labelstatut[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNED_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNED_LABEL : $langs->trans("PropalStatusNotSigned"));
  124. $this->labelstatut[4]=(! empty($conf->global->PROPAL_STATUS_BILLED_LABEL) ? $conf->global->PROPAL_STATUS_BILLED_LABEL : $langs->trans("PropalStatusBilled"));
  125. $this->labelstatut_short[0]=(! empty($conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL) ? $conf->global->PROPAL_STATUS_DRAFTSHORT_LABEL : $langs->trans("PropalStatusDraftShort"));
  126. $this->labelstatut_short[1]=(! empty($conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_VALIDATEDSHORT_LABEL : $langs->trans("Opened"));
  127. $this->labelstatut_short[2]=(! empty($conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_SIGNEDSHORT_LABEL : $langs->trans("PropalStatusSignedShort"));
  128. $this->labelstatut_short[3]=(! empty($conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_NOTSIGNEDSHORT_LABEL : $langs->trans("PropalStatusNotSignedShort"));
  129. $this->labelstatut_short[4]=(! empty($conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL) ? $conf->global->PROPAL_STATUS_BILLEDSHORT_LABEL : $langs->trans("PropalStatusBilledShort"));
  130. }
  131. /**
  132. * Add line into array products
  133. * $this->client doit etre charge
  134. *
  135. * @param int $idproduct Product Id to add
  136. * @param int $qty Quantity
  137. * @param int $remise_percent Discount effected on Product
  138. * @return int <0 if KO, >0 if OK
  139. *
  140. * TODO Remplacer les appels a cette fonction par generation objet Ligne
  141. * insere dans tableau $this->products
  142. */
  143. function add_product($idproduct, $qty, $remise_percent=0)
  144. {
  145. global $conf, $mysoc;
  146. if (! $qty) $qty = 1;
  147. dol_syslog("Propal::add_product $idproduct, $qty, $remise_percent");
  148. if ($idproduct > 0)
  149. {
  150. $prod=new Product($this->db);
  151. $prod->fetch($idproduct);
  152. $productdesc = $prod->description;
  153. $tva_tx = get_default_tva($mysoc,$this->client,$prod->id);
  154. // local taxes
  155. $localtax1_tx = get_default_localtax($mysoc,$this->client,1,$prod->tva_tx);
  156. $localtax2_tx = get_default_localtax($mysoc,$this->client,2,$prod->tva_tx);
  157. // multiprix
  158. if($conf->global->PRODUIT_MULTIPRICES && $this->client->price_level)
  159. {
  160. $price = $prod->multiprices[$this->client->price_level];
  161. }
  162. else
  163. {
  164. $price = $prod->price;
  165. }
  166. $line = new PropaleLigne($this->db);
  167. $line->fk_product=$idproduct;
  168. $line->desc=$productdesc;
  169. $line->qty=$qty;
  170. $line->subprice=$price;
  171. $line->remise_percent=$remise_percent;
  172. $line->tva_tx=$tva_tx;
  173. $this->products[]=$line;
  174. }
  175. }
  176. /**
  177. * Adding line of fixed discount in the proposal in DB
  178. *
  179. * @param int $idremise Id of fixed discount
  180. * @return int >0 if OK, <0 if KO
  181. */
  182. function insert_discount($idremise)
  183. {
  184. global $langs;
  185. include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
  186. include_once(DOL_DOCUMENT_ROOT.'/core/class/discount.class.php');
  187. $this->db->begin();
  188. $remise=new DiscountAbsolute($this->db);
  189. $result=$remise->fetch($idremise);
  190. if ($result > 0)
  191. {
  192. if ($remise->fk_facture) // Protection against multiple submission
  193. {
  194. $this->error=$langs->trans("ErrorDiscountAlreadyUsed");
  195. $this->db->rollback();
  196. return -5;
  197. }
  198. $propalligne=new PropaleLigne($this->db);
  199. $propalligne->fk_propal=$this->id;
  200. $propalligne->fk_remise_except=$remise->id;
  201. $propalligne->desc=$remise->description; // Description ligne
  202. $propalligne->tva_tx=$remise->tva_tx;
  203. $propalligne->subprice=-$remise->amount_ht;
  204. $propalligne->fk_product=0; // Id produit predefini
  205. $propalligne->qty=1;
  206. $propalligne->remise=0;
  207. $propalligne->remise_percent=0;
  208. $propalligne->rang=-1;
  209. $propalligne->info_bits=2;
  210. // TODO deprecated
  211. $propalligne->price=-$remise->amount_ht;
  212. $propalligne->total_ht = -$remise->amount_ht;
  213. $propalligne->total_tva = -$remise->amount_tva;
  214. $propalligne->total_ttc = -$remise->amount_ttc;
  215. $result=$propalligne->insert();
  216. if ($result > 0)
  217. {
  218. $result=$this->update_price(1);
  219. if ($result > 0)
  220. {
  221. $this->db->commit();
  222. return 1;
  223. }
  224. else
  225. {
  226. $this->db->rollback();
  227. return -1;
  228. }
  229. }
  230. else
  231. {
  232. $this->error=$propalligne->error;
  233. $this->db->rollback();
  234. return -2;
  235. }
  236. }
  237. else
  238. {
  239. $this->db->rollback();
  240. return -2;
  241. }
  242. }
  243. /**
  244. * Add a proposal line into database (linked to product/service or not)
  245. * Les parametres sont deja cense etre juste et avec valeurs finales a l'appel
  246. * de cette methode. Aussi, pour le taux tva, il doit deja avoir ete defini
  247. * par l'appelant par la methode get_default_tva(societe_vendeuse,societe_acheteuse,'',produit)
  248. * et le desc doit deja avoir la bonne valeur (a l'appelant de gerer le multilangue)
  249. *
  250. * @param int $propalid Id de la propale
  251. * @param string $desc Description de la ligne
  252. * @param double $pu_ht Prix unitaire
  253. * @param double $qty Quantite
  254. * @param double $txtva Taux de tva
  255. * @param double $txlocaltax1 Local tax 1 rate
  256. * @param double $txlocaltax2 Local tax 2 rate
  257. * @param int $fk_product Id du produit/service predefini
  258. * @param double $remise_percent Pourcentage de remise de la ligne
  259. * @param string $price_base_type HT or TTC
  260. * @param dobule $pu_ttc Prix unitaire TTC
  261. * @param int $info_bits Bits de type de lignes
  262. * @param int $type Type of line (product, service)
  263. * @param int $rang Position of line
  264. * @param int $special_code Special code
  265. * @param int $fk_parent_line Id of parent line
  266. * @param int $fk_fournprice Id supplier price
  267. * @param int $pa_ht Buying price without tax
  268. * @return int >0 if OK, <0 if KO
  269. *
  270. * @see add_product
  271. */
  272. function addline($propalid, $desc, $pu_ht, $qty, $txtva, $txlocaltax1=0, $txlocaltax2=0, $fk_product=0, $remise_percent=0, $price_base_type='HT', $pu_ttc=0, $info_bits=0, $type=0, $rang=-1, $special_code=0, $fk_parent_line=0, $fk_fournprice=null, $pa_ht = 0)
  273. {
  274. global $conf;
  275. dol_syslog("Propal::Addline propalid=$propalid, desc=$desc, pu_ht=$pu_ht, qty=$qty, txtva=$txtva, fk_product=$fk_product, remise_except=$remise_percent, price_base_type=$price_base_type, pu_ttc=$pu_ttc, info_bits=$info_bits, type=$type");
  276. include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
  277. // Clean parameters
  278. if (empty($remise_percent)) $remise_percent=0;
  279. if (empty($qty)) $qty=0;
  280. if (empty($info_bits)) $info_bits=0;
  281. if (empty($rang)) $rang=0;
  282. if (empty($fk_parent_line) || $fk_parent_line < 0) $fk_parent_line=0;
  283. $remise_percent=price2num($remise_percent);
  284. $qty=price2num($qty);
  285. $pu_ht=price2num($pu_ht);
  286. $pu_ttc=price2num($pu_ttc);
  287. $txtva=price2num($txtva);
  288. $txlocaltax1=price2num($txlocaltax1);
  289. $txlocaltax2=price2num($txlocaltax2);
  290. $pa_ht=price2num($pa_ht);
  291. if ($price_base_type=='HT')
  292. {
  293. $pu=$pu_ht;
  294. }
  295. else
  296. {
  297. $pu=$pu_ttc;
  298. }
  299. // Check parameters
  300. if ($type < 0) return -1;
  301. if ($this->statut == 0)
  302. {
  303. $this->db->begin();
  304. // Calcul du total TTC et de la TVA pour la ligne a partir de
  305. // qty, pu, remise_percent et txtva
  306. // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
  307. // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
  308. $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits);
  309. $total_ht = $tabprice[0];
  310. $total_tva = $tabprice[1];
  311. $total_ttc = $tabprice[2];
  312. $total_localtax1 = $tabprice[9];
  313. $total_localtax2 = $tabprice[10];
  314. // Rang to use
  315. $rangtouse = $rang;
  316. if ($rangtouse == -1)
  317. {
  318. $rangmax = $this->line_max($fk_parent_line);
  319. $rangtouse = $rangmax + 1;
  320. }
  321. // TODO A virer
  322. // Anciens indicateurs: $price, $remise (a ne plus utiliser)
  323. $price = $pu;
  324. $remise = 0;
  325. if ($remise_percent > 0)
  326. {
  327. $remise = round(($pu * $remise_percent / 100), 2);
  328. $price = $pu - $remise;
  329. }
  330. // Insert line
  331. $this->line=new PropaleLigne($this->db);
  332. $this->line->fk_propal=$propalid;
  333. $this->line->desc=$desc;
  334. $this->line->qty=$qty;
  335. $this->line->tva_tx=$txtva;
  336. $this->line->localtax1_tx=$txlocaltax1;
  337. $this->line->localtax2_tx=$txlocaltax2;
  338. $this->line->fk_product=$fk_product;
  339. $this->line->remise_percent=$remise_percent;
  340. $this->line->subprice=$pu_ht;
  341. $this->line->rang=$rangtouse;
  342. $this->line->info_bits=$info_bits;
  343. $this->line->total_ht=$total_ht;
  344. $this->line->total_tva=$total_tva;
  345. $this->line->total_localtax1=$total_localtax1;
  346. $this->line->total_localtax2=$total_localtax2;
  347. $this->line->total_ttc=$total_ttc;
  348. $this->line->product_type=$type;
  349. $this->line->special_code=$special_code;
  350. $this->line->fk_parent_line=$fk_parent_line;
  351. // infos marge
  352. $this->line->fk_fournprice = $fk_fournprice;
  353. $this->line->pa_ht = $pa_ht;
  354. // Mise en option de la ligne
  355. //if ($conf->global->PROPALE_USE_OPTION_LINE && !$qty) $ligne->special_code=3;
  356. if (empty($qty) && empty($special_code)) $this->line->special_code=3;
  357. // TODO deprecated
  358. $this->line->price=$price;
  359. $this->line->remise=$remise;
  360. $result=$this->line->insert();
  361. if ($result > 0)
  362. {
  363. // Reorder if child line
  364. if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
  365. // Mise a jour informations denormalisees au niveau de la propale meme
  366. $result=$this->update_price(1);
  367. if ($result > 0)
  368. {
  369. $this->db->commit();
  370. return $this->line->rowid;
  371. }
  372. else
  373. {
  374. $this->error=$this->db->error();
  375. dol_syslog("Error sql=$sql, error=".$this->error,LOG_ERR);
  376. $this->db->rollback();
  377. return -1;
  378. }
  379. }
  380. else
  381. {
  382. $this->error=$this->line->error;
  383. $this->db->rollback();
  384. return -2;
  385. }
  386. }
  387. }
  388. /**
  389. * Update a proposal line
  390. *
  391. * @param int $rowid Id de la ligne
  392. * @param double $pu Prix unitaire (HT ou TTC selon price_base_type)
  393. * @param double $qty Quantity
  394. * @param double $remise_percent Remise effectuee sur le produit
  395. * @param double $txtva Taux de TVA
  396. * @param double $txlocaltax1 Local tax 1 rate
  397. * @param double $txlocaltax2 Local tax 2 rate
  398. * @param string $desc Description
  399. * @param double $price_base_type HT ou TTC
  400. * @param int $info_bits Miscellanous informations
  401. * @param int $special_code Set special code ('' = we don't change it)
  402. * @param int $fk_parent_line Id of line parent
  403. * @param int $skip_update_total Skip update total
  404. * @param int $fk_fournprice Id supplier price
  405. * @param int $pa_ht Buying price without tax
  406. * @return int 0 if OK, <0 if KO
  407. */
  408. function updateline($rowid, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $desc='', $price_base_type='HT', $info_bits=0, $special_code=0, $fk_parent_line=0, $skip_update_total=0, $fk_fournprice=null, $pa_ht=0)
  409. {
  410. global $conf,$user,$langs;
  411. dol_syslog(get_class($this)."::updateLine $rowid, $pu, $qty, $remise_percent, $txtva, $desc, $price_base_type, $info_bits");
  412. include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
  413. // Clean parameters
  414. $remise_percent=price2num($remise_percent);
  415. $qty=price2num($qty);
  416. $pu = price2num($pu);
  417. $txtva = price2num($txtva);
  418. $txlocaltax1=price2num($txlocaltax1);
  419. $txlocaltax2=price2num($txlocaltax2);
  420. $pa_ht=price2num($pa_ht);
  421. if (empty($qty) && empty($special_code)) $special_code=3; // Set option tag
  422. if (! empty($qty) && $special_code == 3) $special_code=0; // Remove option tag
  423. if ($this->statut == 0)
  424. {
  425. $this->db->begin();
  426. // Calcul du total TTC et de la TVA pour la ligne a partir de
  427. // qty, pu, remise_percent et txtva
  428. // TRES IMPORTANT: C'est au moment de l'insertion ligne qu'on doit stocker
  429. // la part ht, tva et ttc, et ce au niveau de la ligne qui a son propre taux tva.
  430. $tabprice=calcul_price_total($qty, $pu, $remise_percent, $txtva, $txlocaltax1, $txlocaltax2, 0, $price_base_type, $info_bits);
  431. $total_ht = $tabprice[0];
  432. $total_tva = $tabprice[1];
  433. $total_ttc = $tabprice[2];
  434. $total_localtax1 = $tabprice[9];
  435. $total_localtax2 = $tabprice[10];
  436. // Anciens indicateurs: $price, $remise (a ne plus utiliser)
  437. $price = $pu;
  438. if ($remise_percent > 0)
  439. {
  440. $remise = round(($pu * $remise_percent / 100), 2);
  441. $price = $pu - $remise;
  442. }
  443. // Update line
  444. $this->line=new PropaleLigne($this->db);
  445. // Stock previous line records
  446. $staticline=new PropaleLigne($this->db);
  447. $staticline->fetch($rowid);
  448. $this->line->oldline = $staticline;
  449. // Reorder if fk_parent_line change
  450. if (! empty($fk_parent_line) && ! empty($staticline->fk_parent_line) && $fk_parent_line != $staticline->fk_parent_line)
  451. {
  452. $rangmax = $this->line_max($fk_parent_line);
  453. $this->line->rang = $rangmax + 1;
  454. }
  455. $this->line->rowid = $rowid;
  456. $this->line->desc = $desc;
  457. $this->line->qty = $qty;
  458. $this->line->tva_tx = $txtva;
  459. $this->line->localtax1_tx = $txlocaltax1;
  460. $this->line->localtax2_tx = $txlocaltax2;
  461. $this->line->remise_percent = $remise_percent;
  462. $this->line->subprice = $pu;
  463. $this->line->info_bits = $info_bits;
  464. $this->line->total_ht = $total_ht;
  465. $this->line->total_tva = $total_tva;
  466. $this->line->total_localtax1 = $total_localtax1;
  467. $this->line->total_localtax2 = $total_localtax2;
  468. $this->line->total_ttc = $total_ttc;
  469. $this->line->special_code = $special_code;
  470. $this->line->fk_parent_line = $fk_parent_line;
  471. $this->line->skip_update_total = $skip_update_total;
  472. // infos marge
  473. $this->line->fk_fournprice = $fk_fournprice;
  474. $this->line->pa_ht = $pa_ht;
  475. // TODO deprecated
  476. $this->line->price=$price;
  477. $this->line->remise=$remise;
  478. $result=$this->line->update();
  479. if ($result > 0)
  480. {
  481. // Reorder if child line
  482. if (! empty($fk_parent_line)) $this->line_order(true,'DESC');
  483. $this->update_price(1);
  484. $this->fk_propal = $this->id;
  485. $this->rowid = $rowid;
  486. $this->db->commit();
  487. return $result;
  488. }
  489. else
  490. {
  491. $this->error=$this->db->error();
  492. $this->db->rollback();
  493. dol_syslog("Propal::UpdateLine Error=".$this->error, LOG_ERR);
  494. return -1;
  495. }
  496. }
  497. else
  498. {
  499. dol_syslog("Propal::UpdateLigne Erreur -2 Propal en mode incompatible pour cette action");
  500. return -2;
  501. }
  502. }
  503. /**
  504. * Delete detail line
  505. *
  506. * @param int $lineid Id of line to delete
  507. * @return int >0 if OK, <0 if KO
  508. */
  509. function deleteline($lineid)
  510. {
  511. if ($this->statut == 0)
  512. {
  513. $line=new PropaleLigne($this->db);
  514. // For triggers
  515. $line->fetch($lineid);
  516. if ($line->delete() > 0)
  517. {
  518. $this->update_price(1);
  519. return 1;
  520. }
  521. else
  522. {
  523. return -1;
  524. }
  525. }
  526. else
  527. {
  528. return -2;
  529. }
  530. }
  531. /**
  532. * Create commercial proposal into database
  533. * this->ref can be set or empty. If empty, we will use "(PROVid)"
  534. *
  535. * @param User $user User that create
  536. * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers
  537. * @return int <0 if KO, >=0 if OK
  538. */
  539. function create($user='', $notrigger=0)
  540. {
  541. global $langs,$conf,$mysoc;
  542. $error=0;
  543. $now=dol_now();
  544. // Clean parameters
  545. if (empty($this->date)) $this->date=$this->datep;
  546. $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
  547. if (empty($this->availability_id)) $this->availability_id=0;
  548. if (empty($this->demand_reason_id)) $this->demand_reason_id=0;
  549. dol_syslog(get_class($this)."::create");
  550. // Check parameters
  551. $soc = new Societe($this->db);
  552. $result=$soc->fetch($this->socid);
  553. if ($result < 0)
  554. {
  555. $this->error="Failed to fetch company";
  556. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  557. return -3;
  558. }
  559. if (empty($this->date))
  560. {
  561. $this->error="Date of proposal is required";
  562. dol_syslog(get_class($this)."::create ".$this->error, LOG_ERR);
  563. return -4;
  564. }
  565. if (! empty($this->ref))
  566. {
  567. $result=$this->verifyNumRef(); // Check ref is not yet used
  568. }
  569. $this->db->begin();
  570. $this->fetch_thirdparty();
  571. // Insert into database
  572. $sql = "INSERT INTO ".MAIN_DB_PREFIX."propal (";
  573. $sql.= "fk_soc";
  574. $sql.= ", price";
  575. $sql.= ", remise";
  576. $sql.= ", remise_percent";
  577. $sql.= ", remise_absolue";
  578. $sql.= ", tva";
  579. $sql.= ", total";
  580. $sql.= ", datep";
  581. $sql.= ", datec";
  582. $sql.= ", ref";
  583. $sql.= ", fk_user_author";
  584. $sql.= ", note";
  585. $sql.= ", note_public";
  586. $sql.= ", model_pdf";
  587. $sql.= ", fin_validite";
  588. $sql.= ", fk_cond_reglement";
  589. $sql.= ", fk_mode_reglement";
  590. $sql.= ", ref_client";
  591. $sql.= ", date_livraison";
  592. $sql.= ", fk_availability";
  593. $sql.= ", fk_input_reason";
  594. $sql.= ", fk_projet";
  595. $sql.= ", entity";
  596. $sql.= ") ";
  597. $sql.= " VALUES (";
  598. $sql.= $this->socid;
  599. $sql.= ", 0";
  600. $sql.= ", ".$this->remise;
  601. $sql.= ", ".($this->remise_percent?$this->remise_percent:'null');
  602. $sql.= ", ".($this->remise_absolue?$this->remise_absolue:'null');
  603. $sql.= ", 0";
  604. $sql.= ", 0";
  605. $sql.= ", '".$this->db->idate($this->date)."'";
  606. $sql.= ", '".$this->db->idate($now)."'";
  607. $sql.= ", '(PROV)'";
  608. $sql.= ", ".($user->id > 0 ? "'".$user->id."'":"null");
  609. $sql.= ", '".$this->db->escape($this->note)."'";
  610. $sql.= ", '".$this->db->escape($this->note_public)."'";
  611. $sql.= ", '".$this->modelpdf."'";
  612. $sql.= ", ".($this->fin_validite!=''?"'".$this->db->idate($this->fin_validite)."'":"null");
  613. $sql.= ", ".$this->cond_reglement_id;
  614. $sql.= ", ".$this->mode_reglement_id;
  615. $sql.= ", '".$this->db->escape($this->ref_client)."'";
  616. $sql.= ", ".($this->date_livraison!=''?"'".$this->db->idate($this->date_livraison)."'":"null");
  617. $sql.= ", ".$this->availability_id;
  618. $sql.= ", ".$this->demand_reason_id;
  619. $sql.= ", ".($this->fk_project?$this->fk_project:"null");
  620. $sql.= ", ".$conf->entity;
  621. $sql.= ")";
  622. dol_syslog(get_class($this)."::create sql=".$sql, LOG_DEBUG);
  623. $resql=$this->db->query($sql);
  624. if ($resql)
  625. {
  626. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."propal");
  627. if ($this->id)
  628. {
  629. if (empty($this->ref)) $this->ref='(PROV'.$this->id.')';
  630. $sql = 'UPDATE '.MAIN_DB_PREFIX."propal SET ref='".$this->ref."' WHERE rowid=".$this->id;
  631. dol_syslog(get_class($this)."::create sql=".$sql);
  632. $resql=$this->db->query($sql);
  633. if (! $resql) $error++;
  634. /*
  635. * Insertion du detail des produits dans la base
  636. */
  637. if (! $error)
  638. {
  639. $fk_parent_line=0;
  640. $num=count($this->lines);
  641. for ($i=0;$i<$num;$i++)
  642. {
  643. // Reset fk_parent_line for no child products and special product
  644. if (($this->lines[$i]->product_type != 9 && empty($this->lines[$i]->fk_parent_line)) || $this->lines[$i]->product_type == 9) {
  645. $fk_parent_line = 0;
  646. }
  647. $result = $this->addline(
  648. $this->id,
  649. $this->lines[$i]->desc,
  650. $this->lines[$i]->subprice,
  651. $this->lines[$i]->qty,
  652. $this->lines[$i]->tva_tx,
  653. $this->lines[$i]->localtax1_tx,
  654. $this->lines[$i]->localtax2_tx,
  655. $this->lines[$i]->fk_product,
  656. $this->lines[$i]->remise_percent,
  657. 'HT',
  658. 0,
  659. 0,
  660. $this->lines[$i]->product_type,
  661. $this->lines[$i]->rang,
  662. $this->lines[$i]->special_code,
  663. $fk_parent_line,
  664. $this->lines[$i]->fk_fournprice,
  665. $this->lines[$i]->pa_ht
  666. );
  667. if ($result < 0)
  668. {
  669. $error++;
  670. $this->error=$this->db->error;
  671. dol_print_error($this->db);
  672. break;
  673. }
  674. // Defined the new fk_parent_line
  675. if ($result > 0 && $this->lines[$i]->product_type == 9) {
  676. $fk_parent_line = $result;
  677. }
  678. }
  679. }
  680. // Add linked object
  681. if (! $error && $this->origin && $this->origin_id)
  682. {
  683. $ret = $this->add_object_linked();
  684. if (! $ret) dol_print_error($this->db);
  685. }
  686. // Set delivery address
  687. if (! $error && $this->fk_delivery_address)
  688. {
  689. $sql = "UPDATE ".MAIN_DB_PREFIX."propal";
  690. $sql.= " SET fk_adresse_livraison = ".$this->fk_delivery_address;
  691. $sql.= " WHERE ref = '".$this->ref."'";
  692. $sql.= " AND entity = ".$conf->entity;
  693. $result=$this->db->query($sql);
  694. }
  695. if (! $error)
  696. {
  697. // Mise a jour infos denormalisees
  698. $resql=$this->update_price(1);
  699. if ($resql)
  700. {
  701. if (! $notrigger)
  702. {
  703. // Appel des triggers
  704. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  705. $interface=new Interfaces($this->db);
  706. $result=$interface->run_triggers('PROPAL_CREATE',$this,$user,$langs,$conf);
  707. if ($result < 0) {
  708. $error++; $this->errors=$interface->errors;
  709. }
  710. // Fin appel triggers
  711. }
  712. }
  713. else
  714. {
  715. $error++;
  716. }
  717. }
  718. }
  719. else
  720. {
  721. $error++;
  722. }
  723. if (! $error)
  724. {
  725. $this->db->commit();
  726. dol_syslog(get_class($this)."::create done id=".$this->id);
  727. return $this->id;
  728. }
  729. else
  730. {
  731. $this->error=$this->db->error();
  732. dol_syslog(get_class($this)."::create -2 ".$this->error, LOG_ERR);
  733. $this->db->rollback();
  734. return -2;
  735. }
  736. }
  737. else
  738. {
  739. $this->error=$this->db->error();
  740. dol_syslog(get_class($this)."::create -1 ".$this->error, LOG_ERR);
  741. $this->db->rollback();
  742. return -1;
  743. }
  744. }
  745. /**
  746. * Insert into DB a proposal object completely defined by its data members (ex, results from copy).
  747. *
  748. * @param User $user User that create
  749. * @return int Id of the new object if ok, <0 if ko
  750. * @see create
  751. */
  752. function create_from($user)
  753. {
  754. $this->products=$this->lines;
  755. return $this->create();
  756. }
  757. /**
  758. * Load an object from its id and create a new one in database
  759. *
  760. * @param int $socid Id of thirdparty
  761. * @param HookManager $hookmanager Hook manager instance
  762. * @return int New id of clone
  763. */
  764. function createFromClone($socid=0,$hookmanager=false)
  765. {
  766. global $user,$langs,$conf;
  767. $error=0;
  768. $now=dol_now();
  769. $this->db->begin();
  770. // Load source object
  771. $objFrom = dol_clone($this);
  772. $objsoc=new Societe($this->db);
  773. // Change socid if needed
  774. if (! empty($socid) && $socid != $this->socid)
  775. {
  776. if ($objsoc->fetch($socid) > 0)
  777. {
  778. $this->socid = $objsoc->id;
  779. $this->cond_reglement_id = (! empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
  780. $this->mode_reglement_id = (! empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
  781. $this->fk_project = '';
  782. $this->fk_delivery_address = '';
  783. }
  784. // TODO Change product price if multi-prices
  785. }
  786. else
  787. {
  788. $objsoc->fetch($this->socid);
  789. }
  790. $this->id=0;
  791. $this->statut=0;
  792. if (empty($conf->global->PROPALE_ADDON) || ! is_readable(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php"))
  793. {
  794. $this->error='ErrorSetupNotComplete';
  795. return -1;
  796. }
  797. // Clear fields
  798. $this->user_author = $user->id;
  799. $this->user_valid = '';
  800. $this->date = $now;
  801. $this->datep = $now; // deprecated
  802. $this->fin_validite = $this->date + ($this->duree_validite * 24 * 3600);
  803. $this->ref_client = '';
  804. // Set ref
  805. require_once(DOL_DOCUMENT_ROOT ."/core/modules/propale/".$conf->global->PROPALE_ADDON.".php");
  806. $obj = $conf->global->PROPALE_ADDON;
  807. $modPropale = new $obj;
  808. $this->ref = $modPropale->getNextValue($objsoc,$this);
  809. // Create clone
  810. $result=$this->create($user);
  811. if ($result < 0) $error++;
  812. if (! $error)
  813. {
  814. // Hook of thirdparty module
  815. if (is_object($hookmanager))
  816. {
  817. $parameters=array('objFrom'=>$objFrom);
  818. $action='';
  819. $reshook=$hookmanager->executeHooks('createFrom',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks
  820. if ($reshook < 0) $error++;
  821. }
  822. // Appel des triggers
  823. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  824. $interface=new Interfaces($this->db);
  825. $result=$interface->run_triggers('PROPAL_CLONE',$this,$user,$langs,$conf);
  826. if ($result < 0) {
  827. $error++; $this->errors=$interface->errors;
  828. }
  829. // Fin appel triggers
  830. }
  831. // End
  832. if (! $error)
  833. {
  834. $this->db->commit();
  835. return $this->id;
  836. }
  837. else
  838. {
  839. $this->db->rollback();
  840. return -1;
  841. }
  842. }
  843. /**
  844. * Load a proposal from database and its ligne array
  845. *
  846. * @param int $rowid id of object to load
  847. * @param string $ref Ref of proposal
  848. * @return int >0 if OK, <0 if KO
  849. */
  850. function fetch($rowid,$ref='')
  851. {
  852. global $conf;
  853. $sql = "SELECT p.rowid, p.ref, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc";
  854. $sql.= ", p.total, p.tva, p.localtax1, p.localtax2, p.total_ht";
  855. $sql.= ", p.datec";
  856. $sql.= ", p.date_valid as datev";
  857. $sql.= ", p.datep as dp";
  858. $sql.= ", p.fin_validite as dfv";
  859. $sql.= ", p.date_livraison as date_livraison";
  860. $sql.= ", p.model_pdf, p.ref_client, p.extraparams";
  861. $sql.= ", p.note as note_private, p.note_public";
  862. $sql.= ", p.fk_projet, p.fk_statut";
  863. $sql.= ", p.fk_user_author, p.fk_user_valid, p.fk_user_cloture";
  864. $sql.= ", p.fk_adresse_livraison";
  865. $sql.= ", p.fk_availability";
  866. $sql.= ", p.fk_input_reason";
  867. $sql.= ", p.fk_cond_reglement";
  868. $sql.= ", p.fk_mode_reglement";
  869. $sql.= ", c.label as statut_label";
  870. $sql.= ", ca.code as availability_code, ca.label as availability";
  871. $sql.= ", dr.code as demand_reason_code, dr.label as demand_reason";
  872. $sql.= ", cr.code as cond_reglement_code, cr.libelle as cond_reglement, cr.libelle_facture as cond_reglement_libelle_doc";
  873. $sql.= ", cp.code as mode_reglement_code, cp.libelle as mode_reglement";
  874. $sql.= " FROM ".MAIN_DB_PREFIX."c_propalst as c, ".MAIN_DB_PREFIX."propal as p";
  875. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_mode_reglement = cp.id';
  876. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as cr ON p.fk_cond_reglement = cr.rowid';
  877. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_availability as ca ON p.fk_availability = ca.rowid';
  878. $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid';
  879. $sql.= " WHERE p.fk_statut = c.id";
  880. $sql.= " AND p.entity = ".$conf->entity;
  881. if ($ref) $sql.= " AND p.ref='".$ref."'";
  882. else $sql.= " AND p.rowid=".$rowid;
  883. dol_syslog(get_class($this)."::fetch sql=".$sql, LOG_DEBUG);
  884. $resql=$this->db->query($sql);
  885. if ($resql)
  886. {
  887. if ($this->db->num_rows($resql))
  888. {
  889. $obj = $this->db->fetch_object($resql);
  890. $this->id = $obj->rowid;
  891. $this->ref = $obj->ref;
  892. $this->ref_client = $obj->ref_client;
  893. $this->remise = $obj->remise;
  894. $this->remise_percent = $obj->remise_percent;
  895. $this->remise_absolue = $obj->remise_absolue;
  896. $this->total = $obj->total; // TODO obsolete
  897. $this->total_ht = $obj->total_ht;
  898. $this->total_tva = $obj->tva;
  899. $this->total_localtax1 = $obj->localtax1;
  900. $this->total_localtax2 = $obj->localtax2;
  901. $this->total_ttc = $obj->total;
  902. $this->socid = $obj->fk_soc;
  903. $this->fk_project = $obj->fk_projet;
  904. $this->modelpdf = $obj->model_pdf;
  905. $this->note = $obj->note_private; // TODO obsolete
  906. $this->note_private = $obj->note_private;
  907. $this->note_public = $obj->note_public;
  908. $this->statut = $obj->fk_statut;
  909. $this->statut_libelle = $obj->statut_label;
  910. $this->datec = $this->db->jdate($obj->datec); // TODO obsolete
  911. $this->datev = $this->db->jdate($obj->datev); // TODO obsolete
  912. $this->date_creation = $this->db->jdate($obj->datec); //Creation date
  913. $this->date_validation = $this->db->jdate($obj->datev); //Validation date
  914. $this->date = $this->db->jdate($obj->dp); // Proposal date
  915. $this->datep = $this->db->jdate($obj->dp); // deprecated
  916. $this->fin_validite = $this->db->jdate($obj->dfv);
  917. $this->date_livraison = $this->db->jdate($obj->date_livraison);
  918. $this->availability_id = $obj->fk_availability;
  919. $this->availability_code = $obj->availability_code;
  920. $this->availability = $obj->availability;
  921. $this->demand_reason_id = $obj->fk_input_reason;
  922. $this->demand_reason_code = $obj->demand_reason_code;
  923. $this->demand_reason = $obj->demand_reason;
  924. $this->fk_delivery_address = $obj->fk_adresse_livraison; // TODO obsolete
  925. $this->fk_address = $obj->fk_adresse_livraison;
  926. $this->mode_reglement_id = $obj->fk_mode_reglement;
  927. $this->mode_reglement_code = $obj->mode_reglement_code;
  928. $this->mode_reglement = $obj->mode_reglement;
  929. $this->cond_reglement_id = $obj->fk_cond_reglement;
  930. $this->cond_reglement_code = $obj->cond_reglement_code;
  931. $this->cond_reglement = $obj->cond_reglement;
  932. $this->cond_reglement_doc = $obj->cond_reglement_libelle_doc;
  933. $this->extraparams = (array) json_decode($obj->extraparams, true);
  934. $this->user_author_id = $obj->fk_user_author;
  935. $this->user_valid_id = $obj->fk_user_valid;
  936. $this->user_close_id = $obj->fk_user_cloture;
  937. if ($obj->fk_statut == 0)
  938. {
  939. $this->brouillon = 1;
  940. }
  941. $this->db->free($resql);
  942. $this->lines = array();
  943. /*
  944. * Lignes propales liees a un produit ou non
  945. */
  946. $sql = "SELECT d.rowid, d.fk_propal, d.fk_parent_line, d.description, d.price, d.tva_tx, d.localtax1_tx, d.localtax2_tx, d.qty, d.fk_remise_except, d.remise_percent, d.subprice, d.fk_product,";
  947. $sql.= " d.info_bits, d.total_ht, d.total_tva, d.total_localtax1, d.total_localtax2, d.total_ttc, d.fk_product_fournisseur_price as fk_fournprice, d.buy_price_ht as pa_ht, d.special_code, d.rang, d.product_type,";
  948. $sql.= ' p.ref as product_ref, p.description as product_desc, p.fk_product_type, p.label as product_label';
  949. $sql.= " FROM ".MAIN_DB_PREFIX."propaldet as d";
  950. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON d.fk_product = p.rowid";
  951. $sql.= " WHERE d.fk_propal = ".$this->id;
  952. $sql.= " ORDER by d.rang";
  953. $result = $this->db->query($sql);
  954. if ($result)
  955. {
  956. $num = $this->db->num_rows($result);
  957. $i = 0;
  958. while ($i < $num)
  959. {
  960. $objp = $this->db->fetch_object($result);
  961. $line = new PropaleLigne($this->db);
  962. $line->rowid = $objp->rowid;
  963. $line->fk_propal = $objp->fk_propal;
  964. $line->fk_parent_line = $objp->fk_parent_line;
  965. $line->product_type = $objp->product_type;
  966. $line->desc = $objp->description; // Description ligne
  967. $line->qty = $objp->qty;
  968. $line->tva_tx = $objp->tva_tx;
  969. $line->localtax1_tx = $objp->localtax1_tx;
  970. $line->localtax2_tx = $objp->localtax2_tx;
  971. $line->subprice = $objp->subprice;
  972. $line->fk_remise_except = $objp->fk_remise_except;
  973. $line->remise_percent = $objp->remise_percent;
  974. $line->price = $objp->price; // TODO deprecated
  975. $line->info_bits = $objp->info_bits;
  976. $line->total_ht = $objp->total_ht;
  977. $line->total_tva = $objp->total_tva;
  978. $line->total_localtax1 = $objp->total_localtax1;
  979. $line->total_localtax2 = $objp->total_localtax2;
  980. $line->total_ttc = $objp->total_ttc;
  981. $line->fk_fournprice = $objp->fk_fournprice;
  982. $marginInfos = getMarginInfos($objp->subprice, $objp->remise_percent, $objp->tva_tx, $objp->localtax1_tx, $objp->localtax2_tx, $line->fk_fournprice, $objp->pa_ht);
  983. $line->pa_ht = $marginInfos[0];
  984. $line->marge_tx = $marginInfos[1];
  985. $line->marque_tx = $marginInfos[2];
  986. $line->special_code = $objp->special_code;
  987. $line->rang = $objp->rang;
  988. $line->fk_product = $objp->fk_product;
  989. $line->ref = $objp->product_ref; // TODO deprecated
  990. $line->product_ref = $objp->product_ref;
  991. $line->libelle = $objp->product_label; // TODO deprecated
  992. $line->label = $objp->product_label; // TODO deprecated
  993. $line->product_label = $objp->product_label;
  994. $line->product_desc = $objp->product_desc; // Description produit
  995. $line->fk_product_type = $objp->fk_product_type;
  996. $this->lines[$i] = $line;
  997. //dol_syslog("1 ".$line->fk_product);
  998. //print "xx $i ".$this->lines[$i]->fk_product;
  999. $i++;
  1000. }
  1001. $this->db->free($result);
  1002. }
  1003. else
  1004. {
  1005. $this->error=$this->db->error();
  1006. dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
  1007. return -1;
  1008. }
  1009. return 1;
  1010. }
  1011. $this->error="Record Not Found";
  1012. return 0;
  1013. }
  1014. else
  1015. {
  1016. $this->error=$this->db->error();
  1017. dol_syslog(get_class($this)."::fetch Error ".$this->error, LOG_ERR);
  1018. return -1;
  1019. }
  1020. }
  1021. /**
  1022. * Set status to validated
  1023. *
  1024. * @param User $user Object user that validate
  1025. * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers
  1026. * @return int <0 if KO, >=0 if OK
  1027. */
  1028. function valid($user, $notrigger=0)
  1029. {
  1030. global $conf,$langs;
  1031. $error=0;
  1032. $now=dol_now();
  1033. if ($user->rights->propale->valider)
  1034. {
  1035. $this->db->begin();
  1036. $sql = "UPDATE ".MAIN_DB_PREFIX."propal";
  1037. $sql.= " SET fk_statut = 1, date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id;
  1038. $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0";
  1039. dol_syslog(get_class($this).'::valid sql='.$sql);
  1040. if ($this->db->query($sql))
  1041. {
  1042. if (! $notrigger)
  1043. {
  1044. // Appel des triggers
  1045. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  1046. $interface=new Interfaces($this->db);
  1047. $result=$interface->run_triggers('PROPAL_VALIDATE',$this,$user,$langs,$conf);
  1048. if ($result < 0) {
  1049. $error++; $this->errors=$interface->errors;
  1050. }
  1051. // Fin appel triggers
  1052. }
  1053. if (! $error)
  1054. {
  1055. $this->brouillon=0;
  1056. $this->statut = 1;
  1057. $this->user_valid_id=$user->id;
  1058. $this->datev=$now;
  1059. $this->db->commit();
  1060. return 1;
  1061. }
  1062. else
  1063. {
  1064. $this->db->rollback();
  1065. return -2;
  1066. }
  1067. }
  1068. else
  1069. {
  1070. $this->db->rollback();
  1071. return -1;
  1072. }
  1073. }
  1074. }
  1075. /**
  1076. * Define proposal date
  1077. *
  1078. * @param User $user Object user that modify
  1079. * @param timestamp $date Date
  1080. * @return int <0 if KO, >0 if OK
  1081. */
  1082. function set_date($user, $date)
  1083. {
  1084. if (empty($date))
  1085. {
  1086. $this->error='ErrorBadParameter';
  1087. dol_syslog(get_class($this)."::set_date ".$this->error, LOG_ERR);
  1088. return -1;
  1089. }
  1090. if ($user->rights->propale->creer)
  1091. {
  1092. $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET datep = '".$this->db->idate($date)."'";
  1093. $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0";
  1094. dol_syslog(get_class($this)."::set_date sql=".$sql);
  1095. if ($this->db->query($sql) )
  1096. {
  1097. $this->date = $date;
  1098. $this->datep = $date; // deprecated
  1099. return 1;
  1100. }
  1101. else
  1102. {
  1103. $this->error=$this->db->lasterror();
  1104. dol_syslog(get_class($this)."::set_date ".$this->error, LOG_ERR);
  1105. return -1;
  1106. }
  1107. }
  1108. }
  1109. /**
  1110. * Define end validity date
  1111. *
  1112. * @param User $user Object user that modify
  1113. * @param timestamp $date_fin_validite End of validity date
  1114. * @return int <0 if KO, >0 if OK
  1115. */
  1116. function set_echeance($user, $date_fin_validite)
  1117. {
  1118. if ($user->rights->propale->creer)
  1119. {
  1120. $sql = "UPDATE ".MAIN_DB_PREFIX."propal SET fin_validite = ".($date_fin_validite!=''?"'".$this->db->idate($date_fin_validite)."'":'null');
  1121. $sql.= " WHERE rowid = ".$this->id." AND fk_statut = 0";
  1122. if ($this->db->query($sql) )
  1123. {
  1124. $this->fin_validite = $date_fin_validite;
  1125. return 1;
  1126. }

Large files files are truncated, but you can click here to view the full file