PageRenderTime 56ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/htdocs/core/class/commonobject.class.php

https://github.com/asterix14/dolibarr
PHP | 2229 lines | 1480 code | 255 blank | 494 comment | 373 complexity | 0bdd5c46c5b395c414fdef903b574e28 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) 2006-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr>
  4. * Copyright (C) 2010-2011 Juanjo Menent <jmenent@2byte.es>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/core/class/commonobject.class.php
  21. * \ingroup core
  22. * \brief File of parent class of all other business classes (invoices, contracts, proposals, orders, ...)
  23. */
  24. /**
  25. * \class CommonObject
  26. * \brief Parent class of all other business classes (invoices, contracts, proposals, orders, ...)
  27. */
  28. abstract class CommonObject
  29. {
  30. protected $db;
  31. public $error;
  32. public $errors;
  33. public $canvas; // Contains canvas name if it is
  34. // No constructor as it is an abstract class
  35. /**
  36. * Check if ref is used.
  37. *
  38. * @return int <0 if KO, 0 if not found, >0 if found
  39. */
  40. function verifyNumRef()
  41. {
  42. global $conf;
  43. $sql = "SELECT rowid";
  44. $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element;
  45. $sql.= " WHERE ref = '".$this->ref."'";
  46. $sql.= " AND entity = ".$conf->entity;
  47. dol_syslog(get_class($this)."::verifyNumRef sql=".$sql, LOG_DEBUG);
  48. $resql = $this->db->query($sql);
  49. if ($resql)
  50. {
  51. $num = $this->db->num_rows($resql);
  52. return $num;
  53. }
  54. else
  55. {
  56. $this->error=$this->db->lasterror();
  57. dol_syslog(get_class($this)."::verifyNumRef ".$this->error, LOG_ERR);
  58. return -1;
  59. }
  60. }
  61. /**
  62. * Add a link between element $this->element and a contact
  63. *
  64. * @param fk_socpeople Id of contact to link
  65. * @param type_contact Type of contact (code or id)
  66. * @param source external=Contact extern (llx_socpeople), internal=Contact intern (llx_user)
  67. * @param notrigger Disable all triggers
  68. * @return int <0 if KO, >0 if OK
  69. */
  70. function add_contact($fk_socpeople, $type_contact, $source='external',$notrigger=0)
  71. {
  72. global $user,$conf,$langs;
  73. dol_syslog(get_class($this)."::add_contact $fk_socpeople, $type_contact, $source");
  74. // Check parameters
  75. if ($fk_socpeople <= 0)
  76. {
  77. $this->error=$langs->trans("ErrorWrongValueForParameter","1");
  78. dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR);
  79. return -1;
  80. }
  81. if (! $type_contact)
  82. {
  83. $this->error=$langs->trans("ErrorWrongValueForParameter","2");
  84. dol_syslog(get_class($this)."::add_contact ".$this->error,LOG_ERR);
  85. return -2;
  86. }
  87. $id_type_contact=0;
  88. if (is_numeric($type_contact))
  89. {
  90. $id_type_contact=$type_contact;
  91. }
  92. else
  93. {
  94. // On recherche id type_contact
  95. $sql = "SELECT tc.rowid";
  96. $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc";
  97. $sql.= " WHERE element='".$this->element."'";
  98. $sql.= " AND source='".$source."'";
  99. $sql.= " AND code='".$type_contact."' AND active=1";
  100. $resql=$this->db->query($sql);
  101. if ($resql)
  102. {
  103. $obj = $this->db->fetch_object($resql);
  104. $id_type_contact=$obj->rowid;
  105. }
  106. }
  107. $datecreate = dol_now();
  108. // Insertion dans la base
  109. $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_contact";
  110. $sql.= " (element_id, fk_socpeople, datecreate, statut, fk_c_type_contact) ";
  111. $sql.= " VALUES (".$this->id.", ".$fk_socpeople." , " ;
  112. $sql.= $this->db->idate($datecreate);
  113. $sql.= ", 4, '". $id_type_contact . "' ";
  114. $sql.= ")";
  115. dol_syslog(get_class($this)."::add_contact sql=".$sql);
  116. $resql=$this->db->query($sql);
  117. if ($resql)
  118. {
  119. if (! $notrigger)
  120. {
  121. // Call triggers
  122. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  123. $interface=new Interfaces($this->db);
  124. $result=$interface->run_triggers(strtoupper($this->element).'_ADD_CONTACT',$this,$user,$langs,$conf);
  125. if ($result < 0) {
  126. $error++; $this->errors=$interface->errors;
  127. }
  128. // End call triggers
  129. }
  130. return 1;
  131. }
  132. else
  133. {
  134. if ($this->db->errno() == 'DB_ERROR_RECORD_ALREADY_EXISTS')
  135. {
  136. $this->error=$this->db->errno();
  137. return -2;
  138. }
  139. else
  140. {
  141. $this->error=$this->db->error();
  142. dol_syslog($this->error,LOG_ERR);
  143. return -1;
  144. }
  145. }
  146. }
  147. /**
  148. * Update a link to contact line
  149. *
  150. * @param rowid Id of line contact-element
  151. * @param statut New status of link
  152. * @param type_contact_id Id of contact type (not modified if 0)
  153. * @return int <0 if KO, >= 0 if OK
  154. */
  155. function update_contact($rowid, $statut, $type_contact_id=0)
  156. {
  157. // Insertion dans la base
  158. $sql = "UPDATE ".MAIN_DB_PREFIX."element_contact set";
  159. $sql.= " statut = ".$statut;
  160. if ($type_contact_id) $sql.= ", fk_c_type_contact = '".$type_contact_id ."'";
  161. $sql.= " where rowid = ".$rowid;
  162. $resql=$this->db->query($sql);
  163. if ($resql)
  164. {
  165. return 0;
  166. }
  167. else
  168. {
  169. $this->error=$this->db->lasterror();
  170. return -1;
  171. }
  172. }
  173. /**
  174. * Delete a link to contact line
  175. *
  176. * @param rowid Id of contact link line to delete
  177. * @param notrigger Disable all triggers
  178. * @return int >0 if OK, <0 if KO
  179. */
  180. function delete_contact($rowid, $notrigger=0)
  181. {
  182. global $user,$langs,$conf;
  183. $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
  184. $sql.= " WHERE rowid =".$rowid;
  185. dol_syslog(get_class($this)."::delete_contact sql=".$sql);
  186. if ($this->db->query($sql))
  187. {
  188. if (! $notrigger)
  189. {
  190. // Call triggers
  191. include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
  192. $interface=new Interfaces($this->db);
  193. $result=$interface->run_triggers(strtoupper($this->element).'_DELETE_CONTACT',$this,$user,$langs,$conf);
  194. if ($result < 0) {
  195. $error++; $this->errors=$interface->errors;
  196. }
  197. // End call triggers
  198. }
  199. return 1;
  200. }
  201. else
  202. {
  203. $this->error=$this->db->lasterror();
  204. dol_syslog(get_class($this)."::delete_contact error=".$this->error, LOG_ERR);
  205. return -1;
  206. }
  207. }
  208. /**
  209. * Delete all links between an object $this and all its contacts
  210. *
  211. * @return int >0 if OK, <0 if KO
  212. */
  213. function delete_linked_contact()
  214. {
  215. $temp = array();
  216. $typeContact = $this->liste_type_contact('');
  217. foreach($typeContact as $key => $value)
  218. {
  219. array_push($temp,$key);
  220. }
  221. $listId = implode(",", $temp);
  222. $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_contact";
  223. $sql.= " WHERE element_id =".$this->id;
  224. $sql.= " AND fk_c_type_contact IN (".$listId.")";
  225. dol_syslog(get_class($this)."::delete_linked_contact sql=".$sql);
  226. if ($this->db->query($sql))
  227. {
  228. return 1;
  229. }
  230. else
  231. {
  232. $this->error=$this->db->lasterror();
  233. dol_syslog(get_class($this)."::delete_linked_contact error=".$this->error, LOG_ERR);
  234. return -1;
  235. }
  236. }
  237. /**
  238. * Get array of all contacts for an object
  239. *
  240. * @param int $statut Status of lines to get (-1=all)
  241. * @param string $source Source of contact: external or thirdparty (llx_socpeople) or internal (llx_user)
  242. * @param int $list 0:Return array contains all properties, 1:Return array contains just id
  243. * @return array Array of contacts
  244. */
  245. function liste_contact($statut=-1,$source='external',$list=0)
  246. {
  247. global $langs;
  248. $tab=array();
  249. $sql = "SELECT ec.rowid, ec.statut, ec.fk_socpeople as id";
  250. if ($source == 'internal') $sql.=", '-1' as socid";
  251. if ($source == 'external' || $source == 'thirdparty') $sql.=", t.fk_soc as socid";
  252. $sql.= ", t.civilite as civility, t.name as lastname, t.firstname, t.email";
  253. $sql.= ", tc.source, tc.element, tc.code, tc.libelle";
  254. $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact tc";
  255. $sql.= ", ".MAIN_DB_PREFIX."element_contact ec";
  256. if ($source == 'internal') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."user t on ec.fk_socpeople = t.rowid";
  257. if ($source == 'external'|| $source == 'thirdparty') $sql.=" LEFT JOIN ".MAIN_DB_PREFIX."socpeople t on ec.fk_socpeople = t.rowid";
  258. $sql.= " WHERE ec.element_id =".$this->id;
  259. $sql.= " AND ec.fk_c_type_contact=tc.rowid";
  260. $sql.= " AND tc.element='".$this->element."'";
  261. if ($source == 'internal') $sql.= " AND tc.source = 'internal'";
  262. if ($source == 'external' || $source == 'thirdparty') $sql.= " AND tc.source = 'external'";
  263. $sql.= " AND tc.active=1";
  264. if ($statut >= 0) $sql.= " AND ec.statut = '".$statut."'";
  265. $sql.=" ORDER BY t.name ASC";
  266. dol_syslog(get_class($this)."::liste_contact sql=".$sql);
  267. $resql=$this->db->query($sql);
  268. if ($resql)
  269. {
  270. $num=$this->db->num_rows($resql);
  271. $i=0;
  272. while ($i < $num)
  273. {
  274. $obj = $this->db->fetch_object($resql);
  275. if (! $list)
  276. {
  277. $transkey="TypeContact_".$obj->element."_".$obj->source."_".$obj->code;
  278. $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle);
  279. $tab[$i]=array('source'=>$obj->source,'socid'=>$obj->socid,'id'=>$obj->id,
  280. 'nom'=>$obj->lastname, // For backward compatibility
  281. 'civility'=>$obj->civility, 'lastname'=>$obj->lastname, 'firstname'=>$obj->firstname, 'email'=>$obj->email,
  282. 'rowid'=>$obj->rowid,'code'=>$obj->code,'libelle'=>$libelle_type,'status'=>$obj->statut);
  283. }
  284. else
  285. {
  286. $tab[$i]=$obj->id;
  287. }
  288. $i++;
  289. }
  290. return $tab;
  291. }
  292. else
  293. {
  294. $this->error=$this->db->error();
  295. dol_print_error($this->db);
  296. return -1;
  297. }
  298. }
  299. /**
  300. * Update status of a contact linked to object
  301. *
  302. * @param $rowid Id of link between object and contact
  303. * @return int <0 if KO, >=0 if OK
  304. */
  305. function swapContactStatus($rowid)
  306. {
  307. $sql = "SELECT ec.datecreate, ec.statut, ec.fk_socpeople, ec.fk_c_type_contact,";
  308. $sql.= " tc.code, tc.libelle";
  309. //$sql.= ", s.fk_soc";
  310. $sql.= " FROM (".MAIN_DB_PREFIX."element_contact as ec, ".MAIN_DB_PREFIX."c_type_contact as tc)";
  311. //$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as s ON ec.fk_socpeople=s.rowid"; // Si contact de type external, alors il est lie a une societe
  312. $sql.= " WHERE ec.rowid =".$rowid;
  313. $sql.= " AND ec.fk_c_type_contact=tc.rowid";
  314. $sql.= " AND tc.element = '".$this->element."'";
  315. dol_syslog(get_class($object)."::swapContactStatus sql=".$sql);
  316. $resql=$this->db->query($sql);
  317. if ($resql)
  318. {
  319. $obj = $this->db->fetch_object($resql);
  320. $newstatut = ($obj->statut == 4) ? 5 : 4;
  321. $result = $this->update_contact($rowid, $newstatut);
  322. $this->db->free($resql);
  323. return $result;
  324. }
  325. else
  326. {
  327. $this->error=$this->db->error();
  328. dol_print_error($this->db);
  329. return -1;
  330. }
  331. }
  332. /**
  333. * Return array with list of possible values for type of contacts
  334. *
  335. * @param source internal, external or all if not defined
  336. * @param order Sort order by : code or rowid
  337. * @param option 0=Return array id->label, 1=Return array code->label
  338. * @return array Array list of type of contacts (id->label if option=0, code->label if option=1)
  339. */
  340. function liste_type_contact($source='internal', $order='code', $option=0)
  341. {
  342. global $langs;
  343. $tab = array();
  344. $sql = "SELECT DISTINCT tc.rowid, tc.code, tc.libelle";
  345. $sql.= " FROM ".MAIN_DB_PREFIX."c_type_contact as tc";
  346. $sql.= " WHERE tc.element='".$this->element."'";
  347. if (! empty($source)) $sql.= " AND tc.source='".$source."'";
  348. $sql.= " ORDER by tc.".$order;
  349. //print "sql=".$sql;
  350. $resql=$this->db->query($sql);
  351. if ($resql)
  352. {
  353. $num=$this->db->num_rows($resql);
  354. $i=0;
  355. while ($i < $num)
  356. {
  357. $obj = $this->db->fetch_object($resql);
  358. $transkey="TypeContact_".$this->element."_".$source."_".$obj->code;
  359. $libelle_type=($langs->trans($transkey)!=$transkey ? $langs->trans($transkey) : $obj->libelle);
  360. if (empty($option)) $tab[$obj->rowid]=$libelle_type;
  361. else $tab[$obj->code]=$libelle_type;
  362. $i++;
  363. }
  364. return $tab;
  365. }
  366. else
  367. {
  368. $this->error=$this->db->lasterror();
  369. //dol_print_error($this->db);
  370. return null;
  371. }
  372. }
  373. /**
  374. * Return id of contacts for a source and a contact code.
  375. * Example: contact client de facturation ('external', 'BILLING')
  376. * Example: contact client de livraison ('external', 'SHIPPING')
  377. * Example: contact interne suivi paiement ('internal', 'SALESREPFOLL')
  378. *
  379. * @param source 'external' or 'internal'
  380. * @param code 'BILLING', 'SHIPPING', 'SALESREPFOLL', ...
  381. * @param status limited to a certain status
  382. * @return array List of id for such contacts
  383. */
  384. function getIdContact($source,$code,$status=0)
  385. {
  386. global $conf;
  387. $result=array();
  388. $i=0;
  389. $sql = "SELECT ec.fk_socpeople";
  390. $sql.= " FROM ".MAIN_DB_PREFIX."element_contact as ec,";
  391. if ($source == 'internal') $sql.= " ".MAIN_DB_PREFIX."user as c,";
  392. if ($source == 'external') $sql.= " ".MAIN_DB_PREFIX."socpeople as c,";
  393. $sql.= " ".MAIN_DB_PREFIX."c_type_contact as tc";
  394. $sql.= " WHERE ec.element_id = ".$this->id;
  395. $sql.= " AND ec.fk_socpeople = c.rowid";
  396. $sql.= " AND c.entity IN (0,".$conf->entity.")";
  397. $sql.= " AND ec.fk_c_type_contact = tc.rowid";
  398. $sql.= " AND tc.element = '".$this->element."'";
  399. $sql.= " AND tc.source = '".$source."'";
  400. $sql.= " AND tc.code = '".$code."'";
  401. $sql.= " AND tc.active = 1";
  402. if ($status) $sql.= " AND ec.statut = ".$status;
  403. dol_syslog(get_class($this)."::getIdContact sql=".$sql);
  404. $resql=$this->db->query($sql);
  405. if ($resql)
  406. {
  407. while ($obj = $this->db->fetch_object($resql))
  408. {
  409. $result[$i]=$obj->fk_socpeople;
  410. $i++;
  411. }
  412. }
  413. else
  414. {
  415. $this->error=$this->db->error();
  416. dol_syslog(get_class($this)."::getIdContact ".$this->error, LOG_ERR);
  417. return null;
  418. }
  419. return $result;
  420. }
  421. /**
  422. * Charge le contact d'id $id dans this->contact
  423. *
  424. * @param contactid Id du contact
  425. * @return int <0 if KO, >0 if OK
  426. */
  427. function fetch_contact($contactid)
  428. {
  429. require_once(DOL_DOCUMENT_ROOT."/contact/class/contact.class.php");
  430. $contact = new Contact($this->db);
  431. $result=$contact->fetch($contactid);
  432. $this->contact = $contact;
  433. return $result;
  434. }
  435. /**
  436. * Load the third party of object from id $this->socid into this->thirdpary
  437. *
  438. * @return int <0 if KO, >0 if OK
  439. */
  440. function fetch_thirdparty()
  441. {
  442. global $conf;
  443. if (empty($this->socid)) return 0;
  444. $thirdparty = new Societe($this->db);
  445. $result=$thirdparty->fetch($this->socid);
  446. $this->client = $thirdparty; // deprecated
  447. $this->thirdparty = $thirdparty;
  448. // Use first price level if level not defined for third party
  449. if ($conf->global->PRODUIT_MULTIPRICES && empty($this->thirdparty->price_level))
  450. {
  451. $this->client->price_level=1; // deprecated
  452. $this->thirdparty->price_level=1;
  453. }
  454. return $result;
  455. }
  456. /**
  457. * Charge le projet d'id $this->fk_project dans this->projet
  458. *
  459. * @return int <0 if KO, >=0 if OK
  460. */
  461. function fetch_projet()
  462. {
  463. if (empty($this->fk_project)) return 0;
  464. $project = new Project($this->db);
  465. $result = $project->fetch($this->fk_project);
  466. $this->projet = $project;
  467. return $result;
  468. }
  469. /**
  470. * Charge le user d'id userid dans this->user
  471. *
  472. * @param userid Id du contact
  473. * @return int <0 if KO, >0 if OK
  474. */
  475. function fetch_user($userid)
  476. {
  477. $user = new User($this->db);
  478. $result=$user->fetch($userid);
  479. $this->user = $user;
  480. return $result;
  481. }
  482. /**
  483. * Load delivery adresse id into $this->fk_address
  484. *
  485. * @param fk_address Id of address
  486. * @return int <0 if KO, >0 if OK
  487. */
  488. function fetch_address($fk_address)
  489. {
  490. $object = new Societe($this->db);
  491. $result=$object->fetch_address($fk_address);
  492. $this->deliveryaddress = $object; // TODO obsolete
  493. $this->adresse = $object; // TODO obsolete
  494. $this->address = $object;
  495. return $result;
  496. }
  497. /**
  498. * Read linked origin object
  499. */
  500. function fetch_origin()
  501. {
  502. // TODO uniformise code
  503. if ($this->origin == 'shipping') $this->origin = 'expedition';
  504. if ($this->origin == 'delivery') $this->origin = 'livraison';
  505. $object = $this->origin;
  506. $classname = ucfirst($object);
  507. $this->$object = new $classname($this->db);
  508. $this->$object->fetch($this->origin_id);
  509. }
  510. /**
  511. * Load object from specific field
  512. *
  513. * @param table Table element or element line
  514. * @param field Field selected
  515. * @param key Import key
  516. * @return int <0 if KO, >0 if OK
  517. */
  518. function fetchObjectFrom($table,$field,$key)
  519. {
  520. global $conf;
  521. $result=false;
  522. $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX.$table;
  523. $sql.= " WHERE ".$field." = '".$key."'";
  524. $sql.= " AND entity = ".$conf->entity;
  525. $resql = $this->db->query($sql);
  526. if ($resql)
  527. {
  528. $row = $this->db->fetch_row($resql);
  529. $result = $this->fetch($row[0]);
  530. }
  531. return $result;
  532. }
  533. /**
  534. * Load value from specific field
  535. *
  536. * @param string $table Table of element or element line
  537. * @param int $id Element id
  538. * @param string $field Field selected
  539. * @return int <0 if KO, >0 if OK
  540. */
  541. function getValueFrom($table, $id, $field)
  542. {
  543. $result=false;
  544. $sql = "SELECT ".$field." FROM ".MAIN_DB_PREFIX.$table;
  545. $sql.= " WHERE rowid = ".$id;
  546. $resql = $this->db->query($sql);
  547. if ($resql)
  548. {
  549. $row = $this->db->fetch_row($resql);
  550. $result = $row[0];
  551. }
  552. return $result;
  553. }
  554. /**
  555. * Update a specific field from an object
  556. *
  557. * @param string $field Field to update
  558. * @param mixte $value New value
  559. * @param string $table To force other table element or element line
  560. * @param int $id To force other object id
  561. * @param string $format Data format ('text' by default, 'date')
  562. * @return int <0 if KO, >0 if OK
  563. */
  564. function setValueFrom($field, $value, $table='', $id='', $format='text')
  565. {
  566. global $conf;
  567. if (empty($table)) $table=$this->table_element;
  568. if (empty($id)) $id=$this->id;
  569. $this->db->begin();
  570. $sql = "UPDATE ".MAIN_DB_PREFIX.$table." SET ";
  571. if ($format == 'text') $sql.= $field." = '".$this->db->escape($value)."'";
  572. else if ($format == 'date') $sql.= $field." = '".$this->db->idate($value)."'";
  573. $sql.= " WHERE rowid = ".$id;
  574. dol_syslog(get_class($this)."::setValueFrom sql=".$sql, LOG_DEBUG);
  575. $resql = $this->db->query($sql);
  576. if ($resql)
  577. {
  578. $this->db->commit();
  579. return 1;
  580. }
  581. else
  582. {
  583. $this->error=$this->db->lasterror();
  584. $this->db->rollback();
  585. return -1;
  586. }
  587. }
  588. /**
  589. * Load properties id_previous and id_next
  590. *
  591. * @param filter Optional filter
  592. * @param fieldid Name of field to use for the select MAX and MIN
  593. * @return int <0 if KO, >0 if OK
  594. */
  595. function load_previous_next_ref($filter='',$fieldid)
  596. {
  597. global $conf, $user;
  598. if (! $this->table_element)
  599. {
  600. dol_print_error('',get_class($this)."::load_previous_next_ref was called on objet with property table_element not defined", LOG_ERR);
  601. return -1;
  602. }
  603. // this->ismultientitymanaged contains
  604. // 0=No test on entity, 1=Test with field entity, 2=Test with link by societe
  605. $alias = 's';
  606. if ($this->element == 'societe') $alias = 'te';
  607. $sql = "SELECT MAX(te.".$fieldid.")";
  608. $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as te";
  609. if ($this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && empty($user->rights->societe->client->voir))) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity
  610. if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc";
  611. $sql.= " WHERE te.".$fieldid." < '".$this->db->escape($this->ref)."'";
  612. if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id;
  613. if (! empty($filter)) $sql.=" AND ".$filter;
  614. if ($this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity
  615. if ($this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN (0,'.(! empty($conf->entities[$this->element]) ? $conf->entities[$this->element] : $conf->entity).')';
  616. //print $sql."<br>";
  617. $result = $this->db->query($sql);
  618. if (! $result)
  619. {
  620. $this->error=$this->db->error();
  621. return -1;
  622. }
  623. $row = $this->db->fetch_row($result);
  624. $this->ref_previous = $row[0];
  625. $sql = "SELECT MIN(te.".$fieldid.")";
  626. $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as te";
  627. if ($this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ", ".MAIN_DB_PREFIX."societe as s"; // If we need to link to societe to limit select to entity
  628. if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe_commerciaux as sc ON ".$alias.".rowid = sc.fk_soc";
  629. $sql.= " WHERE te.".$fieldid." > '".$this->db->escape($this->ref)."'";
  630. if (empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir) $sql.= " AND sc.fk_user = " .$user->id;
  631. if (! empty($filter)) $sql.=" AND ".$filter;
  632. if ($this->ismultientitymanaged == 2 || ($this->element != 'societe' && empty($this->isnolinkedbythird) && !$user->rights->societe->client->voir)) $sql.= ' AND te.fk_soc = s.rowid'; // If we need to link to societe to limit select to entity
  633. if ($this->ismultientitymanaged == 1) $sql.= ' AND te.entity IN (0,'.(! empty($conf->entities[$this->element]) ? $conf->entities[$this->element] : $conf->entity).')';
  634. // Rem: Bug in some mysql version: SELECT MIN(rowid) FROM llx_socpeople WHERE rowid > 1 when one row in database with rowid=1, returns 1 instead of null
  635. //print $sql."<br>";
  636. $result = $this->db->query($sql);
  637. if (! $result)
  638. {
  639. $this->error=$this->db->error();
  640. return -2;
  641. }
  642. $row = $this->db->fetch_row($result);
  643. $this->ref_next = $row[0];
  644. return 1;
  645. }
  646. /**
  647. * Return list of id of contacts of project
  648. *
  649. * @param source Source of contact: external (llx_socpeople) or internal (llx_user) or thirdparty (llx_societe)
  650. * @return array Array of id of contacts (if source=external or internal)
  651. * Array of id of third parties with at least one contact on project (if source=thirdparty)
  652. */
  653. function getListContactId($source='external')
  654. {
  655. $contactAlreadySelected = array();
  656. $tab = $this->liste_contact(-1,$source);
  657. $num=count($tab);
  658. $i = 0;
  659. while ($i < $num)
  660. {
  661. if ($source == 'thirdparty') $contactAlreadySelected[$i] = $tab[$i]['socid'];
  662. else $contactAlreadySelected[$i] = $tab[$i]['id'];
  663. $i++;
  664. }
  665. return $contactAlreadySelected;
  666. }
  667. /**
  668. * Link element with a project
  669. *
  670. * @param int $projectid Project id to link element to
  671. * @return int <0 if KO, >0 if OK
  672. */
  673. function setProject($projectid)
  674. {
  675. if (! $this->table_element)
  676. {
  677. dol_syslog(get_class($this)."::setProject was called on objet with property table_element not defined",LOG_ERR);
  678. return -1;
  679. }
  680. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  681. if ($projectid) $sql.= ' SET fk_projet = '.$projectid;
  682. else $sql.= ' SET fk_projet = NULL';
  683. $sql.= ' WHERE rowid = '.$this->id;
  684. dol_syslog(get_class($this)."::setProject sql=".$sql);
  685. if ($this->db->query($sql))
  686. {
  687. $this->fk_project = $projectid;
  688. return 1;
  689. }
  690. else
  691. {
  692. dol_print_error($this->db);
  693. return -1;
  694. }
  695. }
  696. /**
  697. * Set last model used by doc generator
  698. *
  699. * @param user User object that make change
  700. * @param modelpdf Modele name
  701. * @return int <0 if KO, >0 if OK
  702. */
  703. function setDocModel($user, $modelpdf)
  704. {
  705. if (! $this->table_element)
  706. {
  707. dol_syslog(get_class($this)."::setDocModel was called on objet with property table_element not defined",LOG_ERR);
  708. return -1;
  709. }
  710. $newmodelpdf=dol_trunc($modelpdf,255);
  711. $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element;
  712. $sql.= " SET model_pdf = '".$this->db->escape($newmodelpdf)."'";
  713. $sql.= " WHERE rowid = ".$this->id;
  714. // if ($this->element == 'facture') $sql.= " AND fk_statut < 2";
  715. // if ($this->element == 'propal') $sql.= " AND fk_statut = 0";
  716. dol_syslog(get_class($this)."::setDocModel sql=".$sql);
  717. $resql=$this->db->query($sql);
  718. if ($resql)
  719. {
  720. $this->modelpdf=$modelpdf;
  721. return 1;
  722. }
  723. else
  724. {
  725. dol_print_error($this->db);
  726. return 0;
  727. }
  728. }
  729. /**
  730. * Stocke un numero de rang pour toutes les lignes de detail d'un element qui n'en ont pas.
  731. *
  732. * @param boolean $renum true to renum all already ordered lines, false to renum only not already ordered lines.
  733. * @param string $rowidorder ASC or DESC
  734. */
  735. function line_order($renum=false, $rowidorder='ASC')
  736. {
  737. if (! $this->table_element_line)
  738. {
  739. dol_syslog(get_class($this)."::line_order was called on objet with property table_element_line not defined",LOG_ERR);
  740. return -1;
  741. }
  742. if (! $this->fk_element)
  743. {
  744. dol_syslog(get_class($this)."::line_order was called on objet with property fk_element not defined",LOG_ERR);
  745. return -1;
  746. }
  747. $sql = 'SELECT count(rowid) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  748. $sql.= ' WHERE '.$this->fk_element.'='.$this->id;
  749. if (! $renum) $sql.= ' AND rang = 0';
  750. if ($renum) $sql.= ' AND rang <> 0';
  751. dol_syslog(get_class($this)."::line_order sql=".$sql, LOG_DEBUG);
  752. $resql = $this->db->query($sql);
  753. if ($resql)
  754. {
  755. $row = $this->db->fetch_row($resql);
  756. $nl = $row[0];
  757. }
  758. if ($nl > 0)
  759. {
  760. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  761. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  762. $sql.= ' ORDER BY rang ASC, rowid '.$rowidorder;
  763. dol_syslog(get_class($this)."::line_order sql=".$sql, LOG_DEBUG);
  764. $resql = $this->db->query($sql);
  765. if ($resql)
  766. {
  767. $num = $this->db->num_rows($resql);
  768. $i = 0;
  769. while ($i < $num)
  770. {
  771. $row = $this->db->fetch_row($resql);
  772. $this->updateRangOfLine($row[0], ($i+1));
  773. $i++;
  774. }
  775. }
  776. }
  777. }
  778. /**
  779. * Update a line to have a lower rank
  780. *
  781. * @param int $rowid
  782. */
  783. function line_up($rowid)
  784. {
  785. $this->line_order();
  786. // Get rang of line
  787. $rang = $this->getRangOfLine($rowid);
  788. // Update position of line
  789. $this->updateLineUp($rowid, $rang);
  790. }
  791. /**
  792. * Update a line to have a higher rank
  793. *
  794. * @param int $rowid
  795. */
  796. function line_down($rowid)
  797. {
  798. $this->line_order();
  799. // Get rang of line
  800. $rang = $this->getRangOfLine($rowid);
  801. // Get max value for rang
  802. $max = $this->line_max();
  803. // Update position of line
  804. $this->updateLineDown($rowid, $rang, $max);
  805. }
  806. /**
  807. * Update position of line (rang)
  808. *
  809. * @param int $rowid
  810. * @param int $rang
  811. */
  812. function updateRangOfLine($rowid,$rang)
  813. {
  814. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang;
  815. $sql.= ' WHERE rowid = '.$rowid;
  816. dol_syslog(get_class($this)."::updateRangOfLine sql=".$sql, LOG_DEBUG);
  817. if (! $this->db->query($sql))
  818. {
  819. dol_print_error($this->db);
  820. }
  821. }
  822. /**
  823. * Update position of line with ajax (rang)
  824. *
  825. * @param int $roworder
  826. */
  827. function line_ajaxorder($roworder)
  828. {
  829. $rows = explode(',',$roworder);
  830. $num = count($rows);
  831. for ($i = 0 ; $i < $num ; $i++)
  832. {
  833. $this->updateRangOfLine($rows[$i], ($i+1));
  834. }
  835. }
  836. /**
  837. * Update position of line up (rang)
  838. *
  839. * @param int $rowid
  840. * @param int $rang
  841. */
  842. function updateLineUp($rowid,$rang)
  843. {
  844. if ($rang > 1 )
  845. {
  846. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang ;
  847. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  848. $sql.= ' AND rang = '.($rang - 1);
  849. if ($this->db->query($sql) )
  850. {
  851. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang - 1);
  852. $sql.= ' WHERE rowid = '.$rowid;
  853. if (! $this->db->query($sql) )
  854. {
  855. dol_print_error($this->db);
  856. }
  857. }
  858. else
  859. {
  860. dol_print_error($this->db);
  861. }
  862. }
  863. }
  864. /**
  865. * Update position of line down (rang)
  866. *
  867. * @param int $rowid
  868. * @param int $rang
  869. * @param int $max
  870. */
  871. function updateLineDown($rowid,$rang,$max)
  872. {
  873. if ($rang < $max)
  874. {
  875. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.$rang;
  876. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  877. $sql.= ' AND rang = '.($rang+1);
  878. if ($this->db->query($sql) )
  879. {
  880. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element_line.' SET rang = '.($rang+1);
  881. $sql.= ' WHERE rowid = '.$rowid;
  882. if (! $this->db->query($sql) )
  883. {
  884. dol_print_error($this->db);
  885. }
  886. }
  887. else
  888. {
  889. dol_print_error($this->db);
  890. }
  891. }
  892. }
  893. /**
  894. * Get position of line (rang)
  895. *
  896. * @param int $rowid Id of line
  897. * @return int Value of rang in table of lines
  898. */
  899. function getRangOfLine($rowid)
  900. {
  901. $sql = 'SELECT rang FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  902. $sql.= ' WHERE rowid ='.$rowid;
  903. dol_syslog(get_class($this)."::getRangOfLine sql=".$sql, LOG_DEBUG);
  904. $resql = $this->db->query($sql);
  905. if ($resql)
  906. {
  907. $row = $this->db->fetch_row($resql);
  908. return $row[0];
  909. }
  910. }
  911. /**
  912. * Get rowid of the line relative to its position
  913. *
  914. * @param int $rang Rang value
  915. * @return int Rowid of the line
  916. */
  917. function getIdOfLine($rang)
  918. {
  919. $sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  920. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  921. $sql.= ' AND rang = '.$rang;
  922. $resql = $this->db->query($sql);
  923. if ($resql)
  924. {
  925. $row = $this->db->fetch_row($resql);
  926. return $row[0];
  927. }
  928. }
  929. /**
  930. * Get max value used for position of line (rang)
  931. *
  932. * @param int $fk_parent_line Parent line id
  933. * @return int Max value of rang in table of lines
  934. */
  935. function line_max($fk_parent_line=0)
  936. {
  937. // Search the last rang with fk_parent_line
  938. if ($fk_parent_line)
  939. {
  940. $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  941. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  942. $sql.= ' AND fk_parent_line = '.$fk_parent_line;
  943. dol_syslog(get_class($this)."::line_max sql=".$sql, LOG_DEBUG);
  944. $resql = $this->db->query($sql);
  945. if ($resql)
  946. {
  947. $row = $this->db->fetch_row($resql);
  948. if (! empty($row[0]))
  949. {
  950. return $row[0];
  951. }
  952. else
  953. {
  954. return $this->getRangOfLine($fk_parent_line);
  955. }
  956. }
  957. }
  958. // If not, search the last rang of element
  959. else
  960. {
  961. $sql = 'SELECT max(rang) FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  962. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  963. dol_syslog(get_class($this)."::line_max sql=".$sql, LOG_DEBUG);
  964. $resql = $this->db->query($sql);
  965. if ($resql)
  966. {
  967. $row = $this->db->fetch_row($resql);
  968. return $row[0];
  969. }
  970. }
  971. }
  972. /**
  973. * Update private note of element
  974. *
  975. * @param string $ref_ext Update field ref_ext
  976. * @return int <0 if KO, >0 if OK
  977. */
  978. function update_ref_ext($ref_ext)
  979. {
  980. if (! $this->table_element)
  981. {
  982. dol_syslog(get_class($this)."::update_ref_ext was called on objet with property table_element not defined", LOG_ERR);
  983. return -1;
  984. }
  985. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  986. $sql.= " SET ref_ext = '".$this->db->escape($ref_ext)."'";
  987. $sql.= " WHERE ".(isset($this->table_rowid)?$this->table_rowid:'rowid')." = ". $this->id;
  988. dol_syslog(get_class($this)."::update_ref_ext sql=".$sql, LOG_DEBUG);
  989. if ($this->db->query($sql))
  990. {
  991. $this->ref_ext = $ref_ext;
  992. return 1;
  993. }
  994. else
  995. {
  996. $this->error=$this->db->error();
  997. dol_syslog(get_class($this)."::update_ref_ext error=".$this->error, LOG_ERR);
  998. return -1;
  999. }
  1000. }
  1001. /**
  1002. * Update private note of element
  1003. *
  1004. * @param string $note New value for note
  1005. * @return int <0 if KO, >0 if OK
  1006. */
  1007. function update_note($note)
  1008. {
  1009. if (! $this->table_element)
  1010. {
  1011. dol_syslog(get_class($this)."::update_note was called on objet with property table_element not defined", LOG_ERR);
  1012. return -1;
  1013. }
  1014. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  1015. // TODO uniformize fields note_private
  1016. if ($this->table_element == 'fichinter' || $this->table_element == 'projet' || $this->table_element == 'projet_task')
  1017. {
  1018. $sql.= " SET note_private = '".$this->db->escape($note)."'";
  1019. }
  1020. else
  1021. {
  1022. $sql.= " SET note = '".$this->db->escape($note)."'";
  1023. }
  1024. $sql.= " WHERE rowid =". $this->id;
  1025. dol_syslog(get_class($this)."::update_note sql=".$sql, LOG_DEBUG);
  1026. if ($this->db->query($sql))
  1027. {
  1028. $this->note = $note;
  1029. return 1;
  1030. }
  1031. else
  1032. {
  1033. $this->error=$this->db->error();
  1034. dol_syslog(get_class($this)."::update_note error=".$this->error, LOG_ERR);
  1035. return -1;
  1036. }
  1037. }
  1038. /**
  1039. * Update public note of element
  1040. *
  1041. * @param string $note_public New value for note
  1042. * @return int <0 if KO, >0 if OK
  1043. */
  1044. function update_note_public($note_public)
  1045. {
  1046. if (! $this->table_element)
  1047. {
  1048. dol_syslog(get_class($this)."::update_note_public was called on objet with property table_element not defined",LOG_ERR);
  1049. return -1;
  1050. }
  1051. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
  1052. $sql.= " SET note_public = '".$this->db->escape($note_public)."'";
  1053. $sql.= " WHERE rowid =". $this->id;
  1054. dol_syslog(get_class($this)."::update_note_public sql=".$sql);
  1055. if ($this->db->query($sql))
  1056. {
  1057. $this->note_public = $note_public;
  1058. return 1;
  1059. }
  1060. else
  1061. {
  1062. $this->error=$this->db->error();
  1063. return -1;
  1064. }
  1065. }
  1066. /**
  1067. * Update total_ht, total_ttc and total_vat for an object (sum of lines)
  1068. *
  1069. * @param int $exclspec Exclude special product (product_type=9)
  1070. * @param int $roundingadjust -1=Use default method (MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND or 0), 0=Use total of rounding, 1=Use rounding of total
  1071. * @return int <0 if KO, >0 if OK
  1072. */
  1073. function update_price($exclspec=0,$roundingadjust=-1)
  1074. {
  1075. include_once(DOL_DOCUMENT_ROOT.'/core/lib/price.lib.php');
  1076. if ($roundingadjust < 0 && isset($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)) $roundingadjust=$conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND;
  1077. if ($roundingadjust < 0) $roundingadjust=0;
  1078. $err=0;
  1079. // Define constants to find lines to sum
  1080. $fieldtva='total_tva';
  1081. $fieldlocaltax1='total_localtax1';
  1082. $fieldlocaltax2='total_localtax2';
  1083. if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='tva';
  1084. $sql = 'SELECT qty, total_ht, '.$fieldtva.' as total_tva, '.$fieldlocaltax1.' as total_localtax1, '.$fieldlocaltax2.' as total_localtax2, total_ttc,';
  1085. $sql.= ' tva_tx as vatrate';
  1086. $sql.= ' FROM '.MAIN_DB_PREFIX.$this->table_element_line;
  1087. $sql.= ' WHERE '.$this->fk_element.' = '.$this->id;
  1088. if ($exclspec) $sql.= ' AND product_type <> 9';
  1089. dol_syslog(get_class($this)."::update_price sql=".$sql);
  1090. $resql = $this->db->query($sql);
  1091. if ($resql)
  1092. {
  1093. $this->total_ht = 0;
  1094. $this->total_tva = 0;
  1095. $this->total_localtax1 = 0;
  1096. $this->total_localtax2 = 0;
  1097. $this->total_ttc = 0;
  1098. $vatrates = array();
  1099. $vatrates_alllines = array();
  1100. $num = $this->db->num_rows($resql);
  1101. $i = 0;
  1102. while ($i < $num)
  1103. {
  1104. $obj = $this->db->fetch_object($resql);
  1105. $this->total_ht += $obj->total_ht;
  1106. $this->total_tva += $obj->total_tva;
  1107. $this->total_localtax1 += $obj->total_localtax1;
  1108. $this->total_localtax2 += $obj->total_localtax2;
  1109. $this->total_ttc += $obj->total_ttc;
  1110. // Define vatrates with totals for each line and for all lines
  1111. $vatrates[$this->vatrate][]=array(
  1112. 'total_ht' =>$obj->total_ht,
  1113. 'total_tva' =>$obj->total_tva,
  1114. 'total_ttc' =>$obj->total_ttc,
  1115. 'total_localtax1'=>$obj->total_localtax1,
  1116. 'total_localtax2'=>$obj->total_localtax2
  1117. );
  1118. if (! isset($vatrates_alllines[$this->vatrate]['total_ht'])) $vatrates_alllines[$this->vatrate]['total_ht']=0;
  1119. if (! isset($vatrates_alllines[$this->vatrate]['total_tva'])) $vatrates_alllines[$this->vatrate]['total_tva']=0;
  1120. if (! isset($vatrates_alllines[$this->vatrate]['total_localtax1'])) $vatrates_alllines[$this->vatrate]['total_localtax1']=0;
  1121. if (! isset($vatrates_alllines[$this->vatrate]['total_localtax2'])) $vatrates_alllines[$this->vatrate]['total_localtax2']=0;
  1122. if (! isset($vatrates_alllines[$this->vatrate]['total_ttc'])) $vatrates_alllines[$this->vatrate]['total_ttc']=0;
  1123. $vatrates_alllines[$this->vatrate]['total_ht'] +=$obj->total_ht;
  1124. $vatrates_alllines[$this->vatrate]['total_tva'] +=$obj->total_tva;
  1125. $vatrates_alllines[$this->vatrate]['total_localtax1']+=$obj->total_localtax1;
  1126. $vatrates_alllines[$this->vatrate]['total_localtax2']+=$obj->total_localtax2;
  1127. $vatrates_alllines[$this->vatrate]['total_ttc'] +=$obj->total_ttc;
  1128. $i++;
  1129. }
  1130. $this->db->free($resql);
  1131. // TODO
  1132. if ($roundingadjust)
  1133. {
  1134. // For each vatrate, calculate if two method of calculation differs
  1135. // If it differs
  1136. if (1==2)
  1137. {
  1138. // Adjust a line and update it
  1139. }
  1140. }
  1141. // Now update global field total_ht, total_ttc and tva
  1142. $fieldht='total_ht';
  1143. $fieldtva='tva';
  1144. $fieldlocaltax1='localtax1';
  1145. $fieldlocaltax2='localtax2';
  1146. $fieldttc='total_ttc';
  1147. if ($this->element == 'facture' || $this->element == 'facturerec') $fieldht='total';
  1148. if ($this->element == 'facture_fourn' || $this->element == 'invoice_supplier') $fieldtva='total_tva';
  1149. if ($this->element == 'propal') $fieldttc='total';
  1150. $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element.' SET';
  1151. $sql .= " ".$fieldht."='".price2num($this->total_ht)."',";
  1152. $sql .= " ".$fieldtva."='".price2num($this->total_tva)."',";
  1153. $sql .= " ".$fieldlocaltax1."='".price2num($this->total_localtax1)."',";
  1154. $sql .= " ".$fieldlocaltax2."='".price2num($this->total_localtax2)."',";
  1155. $sql .= " ".$fieldttc."='".price2num($this->total_ttc)."'";
  1156. $sql .= ' WHERE rowid = '.$this->id;
  1157. //print "xx".$sql;
  1158. dol_syslog(get_class($this)."::update_price sql=".$sql);
  1159. $resql=$this->db->query($sql);
  1160. if ($resql)
  1161. {
  1162. return 1;
  1163. }
  1164. else
  1165. {
  1166. $this->error=$this->db->error();
  1167. dol_syslog(get_class($this)."::update_price error=".$this->error,LOG_ERR);
  1168. return -1;
  1169. }
  1170. }
  1171. else
  1172. {
  1173. $this->error=$this->db->error();
  1174. dol_syslog(get_class($this)."::update_price error=".$this->error,LOG_ERR);
  1175. return -1;
  1176. }
  1177. }
  1178. /**
  1179. * Add objects linked in llx_element_element.
  1180. *
  1181. * @return int <=0 if KO, >0 if OK
  1182. */
  1183. function add_object_linked()
  1184. {
  1185. $this->db->begin();
  1186. $sql = "INSERT INTO ".MAIN_DB_PREFIX."element_element (";
  1187. $sql.= "fk_source";
  1188. $sql.= ", sourcetype";
  1189. $sql.= ", fk_target";
  1190. $sql.= ", targettype";
  1191. $sql.= ") VALUES (";
  1192. $sql.= $this->origin_id;
  1193. $sql.= ", '".$this->origin."'";
  1194. $sql.= ", ".$this->id;
  1195. $sql.= ", '".$this->element."'";
  1196. $sql.= ")";
  1197. dol_syslog(get_class($this)."::add_object_linked sql=".$sql, LOG_DEBUG);
  1198. if ($this->db->query($sql))
  1199. {
  1200. $this->db->commit();
  1201. return 1;
  1202. }
  1203. else
  1204. {
  1205. $this->error=$this->db->lasterror();
  1206. $this->db->rollback();
  1207. return 0;
  1208. }
  1209. }
  1210. /**
  1211. * Fetch array of objects linked to current object. Links are loaded into this->linked_object array.
  1212. *
  1213. * @param int $sourceid Object source id
  1214. * @param string $sourcetype Object source type
  1215. * @param int $targetid Object target id
  1216. * @param string $targettype Object target type
  1217. * @param string $clause OR, AND clause
  1218. * @return void
  1219. */
  1220. function fetchObjectLinked($sourceid='',$sourcetype='',$targetid='',$targettype='',$clause='OR')
  1221. {
  1222. global $conf;
  1223. $this->linkedObjectsIds=array();
  1224. $this->linkedObjects=array();
  1225. $justsource=false;
  1226. $justtarget=false;
  1227. if (! empty($sourceid) && ! empty($sourcetype) && empty($targetid) && empty($targettype)) $justsource=true;
  1228. if (empty($sourceid) && empty($sourcetype) && ! empty($targetid) && ! empty($targettype)) $justtarget=true;
  1229. $sourceid = (! empty($sourceid) ? $sourceid : $this->id );
  1230. $targetid = (! empty($targetid) ? $targetid : $this->id );
  1231. $sourcetype = (! empty($sourcetype) ? $sourcetype : (! empty($this->origin) ? $this->origin : $this->element ) );
  1232. $targettype = (! empty($targettype) ? $targettype : $this->element );
  1233. // Links beetween objects are stored in this table
  1234. $sql = 'SELECT fk_source, sourcetype, fk_target, targettype';
  1235. $sql.= ' FROM '.MAIN_DB_PREFIX.'element_element';
  1236. $sql.= " WHERE ";
  1237. if ($justsource || $justtarget)
  1238. {
  1239. if ($justsource) $sql.= "fk_source = '".$sourceid."' AND sourcetype = '".$sourcetype."'";
  1240. if ($justtarget) $sql.= "fk_target = '".$targetid."' AND targettype = '".$targettype."'";
  1241. }
  1242. else
  1243. {
  1244. $sql.= "(fk_source = '".$sourceid."' AND sourcetype = '".$sourcetype."')";
  1245. $sql.= " ".$clause." (fk_target = '".$targetid."' AND targettype = '".$targettype."')";
  1246. }
  1247. //print $sql;
  1248. dol_syslog(get_class($this)."::fetchObjectLink sql=".$sql);
  1249. $resql = $this->db->query($sql);
  1250. if ($resql)
  1251. {
  1252. $num = $this->db->num_rows($resql);
  1253. $i = 0;
  1254. while ($i < $num)
  1255. {
  1256. $obj = $this->db->fetch_object($resql);
  1257. if ($obj->fk_source == $sourceid)
  1258. {
  1259. $this->linkedObjectsIds[$obj->targettype][]=$obj->fk_target;
  1260. }
  1261. if ($obj->fk_target == $targetid)
  1262. {
  1263. $this->linkedObjectsIds[$obj->sourcetype][]=$obj->fk_source;
  1264. }
  1265. $i++;
  1266. }
  1267. if (! empty($this->linkedObjectsIds))
  1268. {
  1269. foreach($this->linkedObjectsIds as $objecttype => $objectids)
  1270. {
  1271. // Parse element/subelement (ex: project_task)
  1272. $module = $element = $subelement = $objecttype;
  1273. if (preg_match('/^([^_]+)_([^_]+)/i',$objecttype,$regs))
  1274. {
  1275. $module = $element = $regs[1];
  1276. $subelement = $regs[2];
  1277. }
  1278. $classpath = $element.'/class';
  1279. // To work with non standard path
  1280. if ($objecttype == 'facture') {
  1281. $classpath = 'compta/facture/class';
  1282. }
  1283. else if ($objecttype == 'propal') {
  1284. $classpath = 'comm/propal/class';

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