PageRenderTime 58ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/expedition/class/expedition.class.php

https://gitlab.com/ziyahan/dolibarr
PHP | 1181 lines | 868 code | 147 blank | 166 comment | 136 complexity | 3d47a5272e6a7cecbb98b9d3d539ed95 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-3.0, LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2003-2008 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr>
  4. * Copyright (C) 2007 Franky Van Liedekerke <franky.van.liedekerke@telenet.be>
  5. * Copyright (C) 2006-2008 Laurent Destailleur <eldy@users.sourceforge.net>
  6. * Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. */
  21. /**
  22. * \file htdocs/expedition/class/expedition.class.php
  23. * \ingroup expedition
  24. * \brief Fichier de la classe de gestion des expeditions
  25. * \version $Id$
  26. */
  27. require_once(DOL_DOCUMENT_ROOT."/core/class/commonobject.class.php");
  28. if ($conf->propal->enabled) require_once(DOL_DOCUMENT_ROOT."/comm/propal/class/propal.class.php");
  29. if ($conf->commande->enabled) require_once(DOL_DOCUMENT_ROOT."/commande/class/commande.class.php");
  30. /**
  31. * \class Expedition
  32. * \brief Class to manage shippings
  33. */
  34. class Expedition extends CommonObject
  35. {
  36. var $db;
  37. var $error;
  38. var $element="shipping";
  39. var $fk_element="fk_expedition";
  40. var $table_element="expedition";
  41. var $id;
  42. var $socid;
  43. var $ref_customer;
  44. var $ref_ext;
  45. var $ref_int;
  46. var $brouillon;
  47. var $entrepot_id;
  48. var $modelpdf;
  49. var $origin;
  50. var $origin_id;
  51. var $lines=array();
  52. var $expedition_method_id; // TODO deprecated
  53. var $shipping_method_id;
  54. var $tracking_number;
  55. var $tracking_url;
  56. var $statut;
  57. var $trueWeight;
  58. var $weight_units;
  59. var $trueWidth;
  60. var $width_units;
  61. var $trueHeight;
  62. var $height_units;
  63. var $trueDepth;
  64. var $depth_units;
  65. // A denormalized value
  66. var $trueSize;
  67. var $date_delivery; // Date delivery planed
  68. var $date_expedition; // Date delivery real
  69. var $date_creation;
  70. var $date_valid;
  71. /**
  72. * Initialisation
  73. */
  74. function Expedition($DB)
  75. {
  76. $this->db = $DB;
  77. $this->lines = array();
  78. $this->products = array();
  79. // List of long language codes for status
  80. $this->statuts[-1] = 'StatusSendingCanceled';
  81. $this->statuts[0] = 'StatusSendingDraft';
  82. $this->statuts[1] = 'StatusSendingValidated';
  83. }
  84. /**
  85. * Return next contract ref
  86. * @param soc objet society
  87. * @return string free reference for contract
  88. */
  89. function getNextNumRef($soc)
  90. {
  91. global $db, $langs, $conf;
  92. $langs->load("sendings");
  93. $dir = DOL_DOCUMENT_ROOT . "/includes/modules/expedition";
  94. if (empty($conf->global->EXPEDITION_ADDON_NUMBER))
  95. {
  96. $conf->global->EXPEDITION_ADDON_NUMBER='mod_expedition_safor';
  97. }
  98. $file = $conf->global->EXPEDITION_ADDON_NUMBER.".php";
  99. // Chargement de la classe de numerotation
  100. $classname = $conf->global->EXPEDITION_ADDON_NUMBER;
  101. $result=include_once($dir.'/'.$file);
  102. if ($result)
  103. {
  104. $obj = new $classname();
  105. $numref = "";
  106. $numref = $obj->getNextValue($soc,$this);
  107. if ( $numref != "")
  108. {
  109. return $numref;
  110. }
  111. else
  112. {
  113. dol_print_error($db,"Expedition::getNextNumRef ".$obj->error);
  114. return "";
  115. }
  116. }
  117. else
  118. {
  119. print $langs->trans("Error")." ".$langs->trans("Error_EXPEDITION_ADDON_NUMBER_NotDefined");
  120. return "";
  121. }
  122. }
  123. /**
  124. * \brief Cree expedition en base
  125. * \param user Objet du user qui cree
  126. * \return int <0 si erreur, id expedition creee si ok
  127. */
  128. function create($user)
  129. {
  130. global $conf, $langs;
  131. require_once DOL_DOCUMENT_ROOT ."/product/stock/class/mouvementstock.class.php";
  132. $error = 0;
  133. // Clean parameters
  134. $this->brouillon = 1;
  135. $this->tracking_number = dol_sanitizeFileName($this->tracking_number);
  136. $this->user = $user;
  137. $this->db->begin();
  138. $sql = "INSERT INTO ".MAIN_DB_PREFIX."expedition (";
  139. $sql.= "ref";
  140. $sql.= ", entity";
  141. $sql.= ", ref_customer";
  142. $sql.= ", ref_int";
  143. $sql.= ", date_creation";
  144. $sql.= ", fk_user_author";
  145. $sql.= ", date_expedition";
  146. $sql.= ", date_delivery";
  147. $sql.= ", fk_soc";
  148. $sql.= ", fk_address";
  149. $sql.= ", fk_expedition_methode";
  150. $sql.= ", tracking_number";
  151. $sql.= ", weight";
  152. $sql.= ", size";
  153. $sql.= ", width";
  154. $sql.= ", height";
  155. $sql.= ", weight_units";
  156. $sql.= ", size_units";
  157. $sql.= ") VALUES (";
  158. $sql.= "'(PROV)'";
  159. $sql.= ", ".$conf->entity;
  160. $sql.= ", ".($this->ref_customer?"'".$this->ref_customer."'":"null");
  161. $sql.= ", ".($this->ref_int?"'".$this->ref_int."'":"null");
  162. $sql.= ", '".$this->db->idate(gmmktime())."'";
  163. $sql.= ", ".$user->id;
  164. $sql.= ", ".($this->date_expedition>0?"'".$this->db->idate($this->date_expedition)."'":"null");
  165. $sql.= ", ".($this->date_delivery>0?"'".$this->db->idate($this->date_delivery)."'":"null");
  166. $sql.= ", ".$this->socid;
  167. $sql.= ", ".($this->fk_delivery_address>0?$this->fk_delivery_address:"null");
  168. $sql.= ", ".($this->expedition_method_id>0?$this->expedition_method_id:"null");
  169. $sql.= ", '".$this->db->escape($this->tracking_number)."'";
  170. $sql.= ", ".$this->weight;
  171. $sql.= ", ".$this->sizeS; // TODO Should use this->trueDepth
  172. $sql.= ", ".$this->sizeW; // TODO Should use this->trueWidth
  173. $sql.= ", ".$this->sizeH; // TODO Should use this->trueHeight
  174. $sql.= ", ".$this->weight_units;
  175. $sql.= ", ".$this->size_units;
  176. $sql.= ")";
  177. $resql=$this->db->query($sql);
  178. if ($resql)
  179. {
  180. $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX."expedition");
  181. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
  182. $sql.= " SET ref = '(PROV".$this->id.")'";
  183. $sql.= " WHERE rowid = ".$this->id;
  184. dol_syslog("Expedition::create sql=".$sql, LOG_DEBUG);
  185. if ($this->db->query($sql))
  186. {
  187. // Insertion des lignes
  188. for ($i = 0 ; $i < sizeof($this->lines) ; $i++)
  189. {
  190. if (! $this->create_line($this->lines[$i]->entrepot_id, $this->lines[$i]->origin_line_id, $this->lines[$i]->qty) > 0)
  191. {
  192. $error++;
  193. }
  194. }
  195. if (! $error && $this->id && $this->origin_id)
  196. {
  197. $ret = $this->add_object_linked();
  198. if (!$ret)
  199. {
  200. $error++;
  201. }
  202. // TODO uniformiser les statuts
  203. $ret = $this->setStatut(2,$this->origin_id,$this->origin);
  204. if (! $ret)
  205. {
  206. $error++;
  207. }
  208. }
  209. if (! $error)
  210. {
  211. // Appel des triggers
  212. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  213. $interface=new Interfaces($this->db);
  214. $result=$interface->run_triggers('SHIPPING_CREATE',$this,$user,$langs,$conf);
  215. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  216. // Fin appel triggers
  217. $this->db->commit();
  218. return $this->id;
  219. }
  220. else
  221. {
  222. $error++;
  223. $this->error=$this->db->lasterror()." - sql=$sql";
  224. $this->db->rollback();
  225. return -3;
  226. }
  227. }
  228. else
  229. {
  230. $error++;
  231. $this->error=$this->db->lasterror()." - sql=$sql";
  232. $this->db->rollback();
  233. return -2;
  234. }
  235. }
  236. else
  237. {
  238. $error++;
  239. $this->error=$this->db->error()." - sql=$sql";
  240. $this->db->rollback();
  241. return -1;
  242. }
  243. }
  244. /**
  245. *
  246. *
  247. */
  248. function create_line($entrepot_id, $origin_line_id, $qty)
  249. {
  250. $error = 0;
  251. $sql = "INSERT INTO ".MAIN_DB_PREFIX."expeditiondet (";
  252. $sql.= "fk_expedition";
  253. $sql.= ", fk_entrepot";
  254. $sql.= ", fk_origin_line";
  255. $sql.= ", qty";
  256. $sql.= ") VALUES (";
  257. $sql.= $this->id;
  258. $sql.= ", ".($entrepot_id?$entrepot_id:'null');
  259. $sql.= ", ".$origin_line_id;
  260. $sql.= ", ".$qty;
  261. $sql.= ")";
  262. if (! $this->db->query($sql))
  263. {
  264. $error++;
  265. }
  266. if (! $error) return 1;
  267. else return -1;
  268. }
  269. /**
  270. * Get object and lines from database
  271. * @param id Id of object to load
  272. * @param ref Ref of object
  273. * @param ref_ext External reference of object
  274. * @param ref_int Internal reference of other object
  275. * @return int >0 if OK, <0 if KO
  276. */
  277. function fetch($id, $ref='', $ref_ext='', $ref_int='')
  278. {
  279. global $conf;
  280. // Check parameters
  281. if (empty($id) && empty($ref) && empty($ref_ext) && empty($ref_int)) return -1;
  282. $sql = "SELECT e.rowid, e.ref, e.fk_soc as socid, e.date_creation, e.ref_customer, e.ref_ext, e.ref_int, e.fk_user_author, e.fk_statut";
  283. $sql.= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height";
  284. $sql.= ", e.date_expedition as date_expedition, e.model_pdf, e.fk_address, e.date_delivery";
  285. $sql.= ", e.fk_expedition_methode, e.tracking_number";
  286. $sql.= ", el.fk_source as origin_id, el.sourcetype as origin";
  287. $sql.= " FROM ".MAIN_DB_PREFIX."expedition as e";
  288. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."element_element as el ON el.fk_target = e.rowid AND el.targettype = '".$this->element."'";
  289. $sql.= " WHERE e.entity = ".$conf->entity;
  290. if ($id) $sql.= " AND e.rowid=".$id;
  291. if ($ref) $sql.= " AND e.ref='".$this->db->escape($ref)."'";
  292. if ($ref_ext) $sql.= " AND e.ref_ext='".$this->db->escape($ref_ext)."'";
  293. if ($ref_int) $sql.= " AND e.ref_int='".$this->db->escape($ref_int)."'";
  294. dol_syslog("Expedition::fetch sql=".$sql);
  295. $result = $this->db->query($sql) ;
  296. if ($result)
  297. {
  298. if ($this->db->num_rows($result))
  299. {
  300. $obj = $this->db->fetch_object($result);
  301. $this->id = $obj->rowid;
  302. $this->ref = $obj->ref;
  303. $this->socid = $obj->socid;
  304. $this->ref_customer = $obj->ref_customer;
  305. $this->ref_ext = $obj->ref_ext;
  306. $this->ref_int = $obj->ref_int;
  307. $this->statut = $obj->fk_statut;
  308. $this->user_author_id = $obj->fk_user_author;
  309. $this->date_creation = $this->db->jdate($obj->date_creation);
  310. $this->date = $this->db->jdate($obj->date_expedition); // TODO obsolete
  311. $this->date_expedition = $this->db->jdate($obj->date_expedition); // TODO obsolete
  312. $this->date_shipping = $this->db->jdate($obj->date_expedition); // Date real
  313. $this->date_delivery = $this->db->jdate($obj->date_delivery); // Date planed
  314. $this->fk_delivery_address = $obj->fk_address;
  315. $this->modelpdf = $obj->model_pdf;
  316. $this->expedition_method_id = $obj->fk_expedition_methode; // TODO deprecated
  317. $this->shipping_method_id = $obj->fk_expedition_methode;
  318. $this->tracking_number = $obj->tracking_number;
  319. $this->origin = ($obj->origin?$obj->origin:'commande'); // For compatibility
  320. $this->origin_id = $obj->origin_id;
  321. $this->trueWeight = $obj->weight;
  322. $this->weight_units = $obj->weight_units;
  323. $this->trueWidth = $obj->width;
  324. $this->width_units = $obj->size_units;
  325. $this->trueHeight = $obj->height;
  326. $this->height_units = $obj->size_units;
  327. $this->trueDepth = $obj->size;
  328. $this->depth_units = $obj->size_units;
  329. // A denormalized value
  330. $this->trueSize = $obj->size."x".$obj->width."x".$obj->height;
  331. $this->size_units = $obj->size_units;
  332. $this->db->free($result);
  333. if ($this->statut == 0) $this->brouillon = 1;
  334. $file = $conf->expedition->dir_output . "/" .get_exdir($expedition->id,2) . "/" . $this->id.".pdf";
  335. $this->pdf_filename = $file;
  336. // Tracking url
  337. $this->GetUrlTrackingStatus($obj->tracking_number);
  338. /*
  339. * Lines
  340. */
  341. $result=$this->fetch_lines();
  342. if ($result < 0)
  343. {
  344. return -3;
  345. }
  346. return 1;
  347. }
  348. else
  349. {
  350. dol_syslog('Expedition::Fetch Error rowid='.$rowid.' numrows=0 sql='.$sql);
  351. $this->error='Delivery with id '.$rowid.' not found sql='.$sql;
  352. return -2;
  353. }
  354. }
  355. else
  356. {
  357. dol_syslog('Expedition::Fetch Error rowid='.$rowid.' Erreur dans fetch de l\'expedition');
  358. $this->error=$this->db->error();
  359. return -1;
  360. }
  361. }
  362. /**
  363. * Validate object and update stock if option enabled
  364. * @param user Object user that validate
  365. * @return int
  366. */
  367. function valid($user)
  368. {
  369. global $conf, $langs;
  370. require_once(DOL_DOCUMENT_ROOT."/lib/files.lib.php");
  371. dol_syslog("Expedition::valid");
  372. // Protection
  373. if ($this->statut)
  374. {
  375. dol_syslog("Expedition::valid no draft status", LOG_WARNING);
  376. return 0;
  377. }
  378. if (! $user->rights->expedition->valider)
  379. {
  380. $this->error='Permission denied';
  381. dol_syslog("Expedition::valid ".$this->error, LOG_ERR);
  382. return -1;
  383. }
  384. $this->db->begin();
  385. $error = 0;
  386. // Define new ref
  387. $soc = new Societe($this->db);
  388. $soc->fetch($this->socid);
  389. // Class of company linked to order
  390. $result=$soc->set_as_client();
  391. // Define new ref
  392. if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref)))
  393. {
  394. $numref = $this->getNextNumRef($soc);
  395. }
  396. else
  397. {
  398. $numref = "EXP".$this->id;
  399. }
  400. $now=dol_now();
  401. // Validate
  402. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET";
  403. $sql.= " ref='".$numref."'";
  404. $sql.= ", fk_statut = 1";
  405. $sql.= ", date_valid = '".$this->db->idate($now)."'";
  406. $sql.= ", fk_user_valid = ".$user->id;
  407. $sql.= " WHERE rowid = ".$this->id;
  408. dol_syslog("Expedition::valid update expedition sql=".$sql);
  409. $resql=$this->db->query($sql);
  410. if (! $resql)
  411. {
  412. dol_syslog("Expedition::valid Echec update - 10 - sql=".$sql, LOG_ERR);
  413. $this->error=$this->db->lasterror();
  414. $error++;
  415. }
  416. // If stock increment is done on sending (recommanded choice)
  417. if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT)
  418. {
  419. require_once DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php";
  420. $langs->load("agenda");
  421. // Loop on each product line to add a stock movement
  422. // TODO possibilite d'expedier a partir d'une propale ou autre origine
  423. $sql = "SELECT cd.fk_product, cd.subprice, ed.qty, ed.fk_entrepot";
  424. $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd";
  425. $sql.= ", ".MAIN_DB_PREFIX."expeditiondet as ed";
  426. $sql.= " WHERE ed.fk_expedition = ".$this->id;
  427. $sql.= " AND cd.rowid = ed.fk_origin_line";
  428. dol_syslog("Expedition::valid select details sql=".$sql);
  429. $resql=$this->db->query($sql);
  430. if ($resql)
  431. {
  432. $num = $this->db->num_rows($resql);
  433. $i=0;
  434. while($i < $num)
  435. {
  436. dol_syslog("Expedition::valid movement index ".$i);
  437. $obj = $this->db->fetch_object($resql);
  438. //var_dump($this->lines[$i]);
  439. $mouvS = new MouvementStock($this->db);
  440. // We decrement stock of product (and sub-products)
  441. // We use warehouse selected for each line
  442. $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice);
  443. if ($result < 0) { $error++; break; }
  444. $i++;
  445. }
  446. }
  447. else
  448. {
  449. $this->db->rollback();
  450. $this->error=$this->db->error();
  451. dol_syslog("Expedition::valid ".$this->error, LOG_ERR);
  452. return -2;
  453. }
  454. }
  455. if (! $error)
  456. {
  457. // On efface le repertoire de pdf provisoire
  458. $expeditionref = dol_sanitizeFileName($this->ref);
  459. if ($conf->expedition->dir_output)
  460. {
  461. $dir = $conf->expedition->dir_output . "/" . $expeditionref;
  462. $file = $dir . "/" . $expeditionref . ".pdf";
  463. if (file_exists($file))
  464. {
  465. if (!dol_delete_file($file))
  466. {
  467. $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
  468. }
  469. }
  470. if (file_exists($dir))
  471. {
  472. if (!dol_delete_dir($dir))
  473. {
  474. $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
  475. }
  476. }
  477. }
  478. }
  479. // Set new ref and current status
  480. if (! $error)
  481. {
  482. $this->ref = $numref;
  483. $this->statut = 1;
  484. }
  485. if (! $error)
  486. {
  487. // Appel des triggers
  488. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  489. $interface=new Interfaces($this->db);
  490. $result=$interface->run_triggers('SHIPPING_VALIDATE',$this,$user,$langs,$conf);
  491. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  492. // Fin appel triggers
  493. }
  494. if (! $error)
  495. {
  496. $this->db->commit();
  497. return 1;
  498. }
  499. else
  500. {
  501. foreach($this->errors as $errmsg)
  502. {
  503. dol_syslog(get_class($this)."::valid ".$errmsg, LOG_ERR);
  504. $this->error.=($this->error?', '.$errmsg:$errmsg);
  505. }
  506. $this->db->rollback();
  507. return -1*$error;
  508. }
  509. }
  510. /**
  511. * \brief Cree un bon de livraison a partir de l'expedition
  512. * \param user Utilisateur
  513. * \return int <0 si ko, >=0 si ok
  514. */
  515. function create_delivery($user)
  516. {
  517. global $conf;
  518. if ($conf->livraison_bon->enabled)
  519. {
  520. if ($this->statut == 1)
  521. {
  522. // Expedition validee
  523. include_once(DOL_DOCUMENT_ROOT."/livraison/class/livraison.class.php");
  524. $delivery = new Livraison($this->db);
  525. $result=$delivery->create_from_sending($user, $this->id);
  526. if ($result > 0)
  527. {
  528. return $result;
  529. }
  530. else
  531. {
  532. $this->error=$delivery->error;
  533. return $result;
  534. }
  535. }
  536. else return 0;
  537. }
  538. else return 0;
  539. }
  540. /**
  541. * Ajoute une ligne
  542. *
  543. */
  544. function addline( $entrepot_id, $id, $qty )
  545. {
  546. $num = sizeof($this->lines);
  547. $line = new ExpeditionLigne($this->db);
  548. $line->entrepot_id = $entrepot_id;
  549. $line->origin_line_id = $id;
  550. $line->qty = $qty;
  551. $this->lines[$num] = $line;
  552. }
  553. /**
  554. *
  555. *
  556. */
  557. function deleteline($lineid)
  558. {
  559. if ($this->statut == 0)
  560. {
  561. $sql = "DELETE FROM ".MAIN_DB_PREFIX."commandedet";
  562. $sql.= " WHERE rowid = ".$lineid;
  563. if ($this->db->query($sql) )
  564. {
  565. $this->update_price();
  566. return 1;
  567. }
  568. else
  569. {
  570. return 0;
  571. }
  572. }
  573. }
  574. /**
  575. * \brief Update database
  576. * \param user User that modify
  577. * \param notrigger 0=launch triggers after, 1=disable triggers
  578. * \return int <0 if KO, >0 if OK
  579. */
  580. function update($user=0, $notrigger=0)
  581. {
  582. global $conf, $langs;
  583. $error=0;
  584. // Clean parameters
  585. if (isset($this->ref)) $this->ref=trim($this->ref);
  586. if (isset($this->entity)) $this->entity=trim($this->entity);
  587. if (isset($this->ref_customer)) $this->ref_customer=trim($this->ref_customer);
  588. if (isset($this->socid)) $this->socid=trim($this->socid);
  589. if (isset($this->fk_user_author)) $this->fk_user_author=trim($this->fk_user_author);
  590. if (isset($this->fk_user_valid)) $this->fk_user_valid=trim($this->fk_user_valid);
  591. if (isset($this->fk_adresse_livraison)) $this->fk_adresse_livraison=trim($this->fk_adresse_livraison);
  592. if (isset($this->expedition_method_id)) $this->expedition_method_id=trim($this->expedition_method_id);
  593. if (isset($this->tracking_number)) $this->tracking_number=trim($this->tracking_number);
  594. if (isset($this->statut)) $this->statut=trim($this->statut);
  595. if (isset($this->trueDepth)) $this->trueDepth=trim($this->trueDepth);
  596. if (isset($this->trueWidth)) $this->trueWidth=trim($this->trueWidth);
  597. if (isset($this->trueHeight)) $this->trueHeight=trim($this->trueHeight);
  598. if (isset($this->size_units)) $this->size_units=trim($this->size_units);
  599. if (isset($this->weight_units)) $this->weight_units=trim($this->weight_units);
  600. if (isset($this->trueWeight)) $this->weight=trim($this->trueWeight);
  601. if (isset($this->note)) $this->note=trim($this->note);
  602. if (isset($this->model_pdf)) $this->model_pdf=trim($this->model_pdf);
  603. // Check parameters
  604. // Put here code to add control on parameters values
  605. // Update request
  606. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition SET";
  607. $sql.= " tms=".(dol_strlen($this->tms)!=0 ? "'".$this->db->idate($this->tms)."'" : 'null').",";
  608. $sql.= " ref=".(isset($this->ref)?"'".$this->db->escape($this->ref)."'":"null").",";
  609. $sql.= " ref_customer=".(isset($this->ref_customer)?"'".$this->db->escape($this->ref_customer)."'":"null").",";
  610. $sql.= " fk_soc=".(isset($this->socid)?$this->socid:"null").",";
  611. $sql.= " date_creation=".(dol_strlen($this->date_creation)!=0 ? "'".$this->db->idate($this->date_creation)."'" : 'null').",";
  612. $sql.= " fk_user_author=".(isset($this->fk_user_author)?$this->fk_user_author:"null").",";
  613. $sql.= " date_valid=".(dol_strlen($this->date_valid)!=0 ? "'".$this->db->idate($this->date_valid)."'" : 'null').",";
  614. $sql.= " fk_user_valid=".(isset($this->fk_user_valid)?$this->fk_user_valid:"null").",";
  615. $sql.= " date_expedition=".(dol_strlen($this->date_expedition)!=0 ? "'".$this->db->idate($this->date_expedition)."'" : 'null').",";
  616. $sql.= " date_delivery=".(dol_strlen($this->date_delivery)!=0 ? "'".$this->db->idate($this->date_delivery)."'" : 'null').",";
  617. $sql.= " fk_address=".(isset($this->fk_adresse_livraison)?$this->fk_adresse_livraison:"null").",";
  618. $sql.= " fk_expedition_methode=".((isset($this->expedition_method_id) && $this->expedition_method_id > 0)?$this->expedition_method_id:"null").",";
  619. $sql.= " tracking_number=".(isset($this->tracking_number)?"'".$this->db->escape($this->tracking_number)."'":"null").",";
  620. $sql.= " fk_statut=".(isset($this->statut)?$this->statut:"null").",";
  621. $sql.= " height=".(isset($this->trueHeight)?$this->trueHeight:"null").",";
  622. $sql.= " width=".(isset($this->trueWidth)?$this->trueWidth:"null").",";
  623. $sql.= " size_units=".(isset($this->size_units)?$this->size_units:"null").",";
  624. $sql.= " size=".(isset($this->trueDepth)?$this->trueDepth:"null").",";
  625. $sql.= " weight_units=".(isset($this->weight_units)?$this->weight_units:"null").",";
  626. $sql.= " weight=".(isset($this->trueWeight)?$this->trueWeight:"null").",";
  627. $sql.= " note=".(isset($this->note)?"'".$this->db->escape($this->note)."'":"null").",";
  628. $sql.= " model_pdf=".(isset($this->model_pdf)?"'".$this->db->escape($this->model_pdf)."'":"null").",";
  629. $sql.= " entity=".$conf->entity;
  630. $sql.= " WHERE rowid=".$this->id;
  631. $this->db->begin();
  632. dol_syslog(get_class($this)."::update sql=".$sql, LOG_DEBUG);
  633. $resql = $this->db->query($sql);
  634. if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
  635. if (! $error)
  636. {
  637. if (! $notrigger)
  638. {
  639. // Call triggers
  640. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  641. $interface=new Interfaces($this->db);
  642. $result=$interface->run_triggers('SHIPPING_MODIFY',$this,$user,$langs,$conf);
  643. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  644. // End call triggers
  645. }
  646. }
  647. // Commit or rollback
  648. if ($error)
  649. {
  650. foreach($this->errors as $errmsg)
  651. {
  652. dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
  653. $this->error.=($this->error?', '.$errmsg:$errmsg);
  654. }
  655. $this->db->rollback();
  656. return -1*$error;
  657. }
  658. else
  659. {
  660. $this->db->commit();
  661. return 1;
  662. }
  663. }
  664. /**
  665. * Delete shipping
  666. */
  667. function delete()
  668. {
  669. global $conf, $langs, $user;
  670. require_once(DOL_DOCUMENT_ROOT."/lib/files.lib.php");
  671. $this->db->begin();
  672. $sql = "DELETE FROM ".MAIN_DB_PREFIX."expeditiondet";
  673. $sql.= " WHERE fk_expedition = ".$this->id;
  674. if ( $this->db->query($sql) )
  675. {
  676. $sql = "DELETE FROM ".MAIN_DB_PREFIX."element_element";
  677. $sql.= " WHERE fk_target = ".$this->id;
  678. $sql.= " AND targettype = '".$this->element."'";
  679. if ( $this->db->query($sql) )
  680. {
  681. $sql = "DELETE FROM ".MAIN_DB_PREFIX."expedition";
  682. $sql.= " WHERE rowid = ".$this->id;
  683. if ( $this->db->query($sql) )
  684. {
  685. $this->db->commit();
  686. // On efface le repertoire de pdf provisoire
  687. $expref = dol_sanitizeFileName($this->ref);
  688. if ($conf->expedition->dir_output)
  689. {
  690. $dir = $conf->expedition->dir_output . "/" . $expref ;
  691. $file = $conf->expedition->dir_output . "/" . $expref . "/" . $expref . ".pdf";
  692. if (file_exists($file))
  693. {
  694. if (!dol_delete_file($file))
  695. {
  696. $this->error=$langs->trans("ErrorCanNotDeleteFile",$file);
  697. return 0;
  698. }
  699. }
  700. if (file_exists($dir))
  701. {
  702. if (!dol_delete_dir($dir))
  703. {
  704. $this->error=$langs->trans("ErrorCanNotDeleteDir",$dir);
  705. return 0;
  706. }
  707. }
  708. }
  709. // Call triggers
  710. include_once(DOL_DOCUMENT_ROOT."/core/class/interfaces.class.php");
  711. $interface=new Interfaces($this->db);
  712. $result=$interface->run_triggers('SHIPPING_DELETE',$this,$user,$langs,$conf);
  713. if ($result < 0) { $error++; $this->errors=$interface->errors; }
  714. // End call triggers
  715. // TODO il faut incrementer le stock si on supprime une expedition validee
  716. return 1;
  717. }
  718. else
  719. {
  720. $this->error=$this->db->lasterror()." - sql=$sql";
  721. $this->db->rollback();
  722. return -3;
  723. }
  724. }
  725. else
  726. {
  727. $this->error=$this->db->lasterror()." - sql=$sql";
  728. $this->db->rollback();
  729. return -2;
  730. }
  731. }
  732. else
  733. {
  734. $this->error=$this->db->lasterror()." - sql=$sql";
  735. $this->db->rollback();
  736. return -1;
  737. }
  738. }
  739. /**
  740. *
  741. *
  742. */
  743. function fetch_lines()
  744. {
  745. // TODO: recuperer les champs du document associe a part
  746. $sql = "SELECT cd.rowid, cd.fk_product, cd.description, cd.qty as qty_asked";
  747. $sql.= ", ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot";
  748. $sql.= ", p.ref as product_ref, p.fk_product_type, p.label, p.weight, p.weight_units, p.volume, p.volume_units";
  749. $sql.= " FROM (".MAIN_DB_PREFIX."expeditiondet as ed,";
  750. $sql.= " ".MAIN_DB_PREFIX."commandedet as cd)";
  751. $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product";
  752. $sql.= " WHERE ed.fk_expedition = ".$this->id;
  753. $sql.= " AND ed.fk_origin_line = cd.rowid";
  754. dol_syslog("Expedition::fetch_lines sql=".$sql);
  755. $resql = $this->db->query($sql);
  756. if ($resql)
  757. {
  758. $num = $this->db->num_rows($resql);
  759. $i = 0;
  760. while ($i < $num)
  761. {
  762. $line = new ExpeditionLigne($this->db);
  763. $obj = $this->db->fetch_object($resql);
  764. $line->fk_origin_line = $obj->fk_origin_line;
  765. $line->origin_line_id = $obj->fk_origin_line; // TODO deprecated
  766. $line->entrepot_id = $obj->fk_entrepot;
  767. $line->fk_product = $obj->fk_product;
  768. $line->fk_product_type = $obj->fk_product_type;
  769. $line->ref = $obj->product_ref; // TODO deprecated
  770. $line->product_ref = $obj->product_ref;
  771. $line->label = $obj->label;
  772. $line->libelle = $obj->label; // TODO deprecated
  773. $line->description = $obj->description;
  774. $line->qty_asked = $obj->qty_asked;
  775. $line->qty_shipped = $obj->qty_shipped;
  776. $line->weight = $obj->weight;
  777. $line->weight_units = $obj->weight_units;
  778. $line->volume = $obj->volume;
  779. $line->volume_units = $obj->volume_units;
  780. $this->lines[$i] = $line;
  781. $i++;
  782. }
  783. $this->db->free($resql);
  784. return 1;
  785. }
  786. else
  787. {
  788. $this->error=$this->db->error();
  789. dol_syslog('Expedition::fetch_lines: Error '.$this->error, LOG_ERR);
  790. return -3;
  791. }
  792. }
  793. /**
  794. * \brief Renvoie nom clicable (avec eventuellement le picto)
  795. * \param withpicto 0=Pas de picto, 1=Inclut le picto dans le lien, 2=Picto seul
  796. * \return string Chaine avec URL
  797. */
  798. function getNomUrl($withpicto=0,$option=0,$max=0,$short=0)
  799. {
  800. global $langs;
  801. $result='';
  802. $url = DOL_URL_ROOT.'/expedition/fiche.php?id='.$this->id;
  803. if ($short) return $url;
  804. $linkstart = '<a href="'.$url.'">';
  805. $linkend='</a>';
  806. $picto='sending';
  807. $label=$langs->trans("ShowSending").': '.$this->ref;
  808. if ($withpicto) $result.=($linkstart.img_object($label,$picto).$linkend);
  809. if ($withpicto && $withpicto != 2) $result.=' ';
  810. $result.=$linkstart.$this->ref.$linkend;
  811. return $result;
  812. }
  813. /**
  814. * \brief Retourne le libelle du statut d'une expedition
  815. * \return string Libelle
  816. */
  817. function getLibStatut($mode=0)
  818. {
  819. return $this->LibStatut($this->statut,$mode);
  820. }
  821. /**
  822. * \brief Return label of a status
  823. * \param statut Id statut
  824. * \param mode 0=Long label, 1=Short label, 2=Picto + Short label, 3=Picto, 4=Picto + Long label, 5=Short label + Picto
  825. * \return string Label of status
  826. */
  827. function LibStatut($statut,$mode)
  828. {
  829. global $langs;
  830. if ($mode==0)
  831. {
  832. if ($statut==0) return $langs->trans($this->statuts[$statut]);
  833. if ($statut==1) return $langs->trans($this->statuts[$statut]);
  834. }
  835. if ($mode==1)
  836. {
  837. if ($statut==0) return $langs->trans('StatusSendingDraftShort');
  838. if ($statut==1) return $langs->trans('StatusSendingValidatedShort');
  839. }
  840. if ($mode == 3)
  841. {
  842. if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0');
  843. if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4');
  844. }
  845. if ($mode == 4)
  846. {
  847. if ($statut==0) return img_picto($langs->trans($this->statuts[$statut]),'statut0').' '.$langs->trans($this->statuts[$statut]);
  848. if ($statut==1) return img_picto($langs->trans($this->statuts[$statut]),'statut4').' '.$langs->trans($this->statuts[$statut]);
  849. }
  850. if ($mode == 5)
  851. {
  852. if ($statut==0) return $langs->trans('StatusSendingDraftShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut0');
  853. if ($statut==1) return $langs->trans('StatusSendingValidatedShort').' '.img_picto($langs->trans($this->statuts[$statut]),'statut4');
  854. }
  855. }
  856. /**
  857. * \brief Initialise la facture avec valeurs fictives aleatoire
  858. * Sert a generer une facture pour l'aperu des modeles ou dem
  859. */
  860. function initAsSpecimen()
  861. {
  862. global $user,$langs,$conf;
  863. dol_syslog("Expedition::initAsSpecimen");
  864. // Charge tableau des produits prodids
  865. $prodids = array();
  866. $sql = "SELECT rowid";
  867. $sql.= " FROM ".MAIN_DB_PREFIX."product";
  868. $sql.= " WHERE entity = ".$conf->entity;
  869. $resql = $this->db->query($sql);
  870. if ($resql)
  871. {
  872. $num_prods = $this->db->num_rows($resql);
  873. $i = 0;
  874. while ($i < $num_prods)
  875. {
  876. $i++;
  877. $row = $this->db->fetch_row($resql);
  878. $prodids[$i] = $row[0];
  879. }
  880. }
  881. $order=new Commande($this->db);
  882. $order->initAsSpecimen();
  883. // Initialise parametres
  884. $this->id=0;
  885. $this->ref = 'SPECIMEN';
  886. $this->specimen=1;
  887. $this->statut = 1;
  888. if ($conf->livraison_bon->enabled)
  889. {
  890. $this->livraison_id = 0;
  891. }
  892. $this->date = time();
  893. $this->entrepot_id = 0;
  894. $this->fk_delivery_address = 0;
  895. $this->socid = 1;
  896. $this->commande_id = 0;
  897. $this->commande = $order;
  898. $this->origin_id = 1;
  899. $this->origin = 'commande';
  900. $nbp = 5;
  901. $xnbp = 0;
  902. while ($xnbp < $nbp)
  903. {
  904. $line=new ExpeditionLigne($this->db);
  905. $line->desc=$langs->trans("Description")." ".$xnbp;
  906. $line->libelle=$langs->trans("Description")." ".$xnbp;
  907. $line->qty=10;
  908. $line->qty_asked=5;
  909. $line->qty_shipped=4;
  910. $line->fk_product=$this->commande->lines[$xnbp]->fk_product;
  911. $this->lines[]=$line;
  912. $xnbp++;
  913. }
  914. }
  915. /**
  916. * \brief Set the planned delivery date
  917. * \param user Objet utilisateur qui modifie
  918. * \param date_livraison Date de livraison
  919. * \return int <0 si ko, >0 si ok
  920. */
  921. function set_date_livraison($user, $date_livraison)
  922. {
  923. if ($user->rights->expedition->creer)
  924. {
  925. $sql = "UPDATE ".MAIN_DB_PREFIX."expedition";
  926. $sql.= " SET date_delivery = ".($date_livraison ? "'".$this->db->idate($date_livraison)."'" : 'null');
  927. $sql.= " WHERE rowid = ".$this->id;
  928. dol_syslog("Expedition::set_date_livraison sql=".$sql,LOG_DEBUG);
  929. $resql=$this->db->query($sql);
  930. if ($resql)
  931. {
  932. $this->date_delivery = $date_livraison;
  933. return 1;
  934. }
  935. else
  936. {
  937. $this->error=$this->db->error();
  938. dol_syslog("Commande::set_date_livraison ".$this->error,LOG_ERR);
  939. return -1;
  940. }
  941. }
  942. else
  943. {
  944. return -2;
  945. }
  946. }
  947. /**
  948. * \brief Fetch deliveries method and return an array. Load array this->meths(rowid=>label).
  949. */
  950. function fetch_delivery_methods()
  951. {
  952. global $langs;
  953. $meths = array();
  954. $sql = "SELECT em.rowid, em.code, em.libelle";
  955. $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
  956. $sql.= " WHERE em.active = 1";
  957. $sql.= " ORDER BY em.libelle ASC";
  958. $resql = $this->db->query($sql);
  959. if ($resql)
  960. {
  961. while ($obj = $this->db->fetch_object($resql))
  962. {
  963. $label=$langs->trans('SendingMethod'.$obj->code);
  964. $this->meths[$obj->rowid] = ($label != 'SendingMethod'.$obj->code?$label:$obj->libelle);
  965. }
  966. }
  967. }
  968. /**
  969. * Get tracking url status
  970. */
  971. function GetUrlTrackingStatus($value='')
  972. {
  973. $code='';
  974. if (! empty($this->expedition_method_id))
  975. {
  976. $sql = "SELECT em.code";
  977. $sql.= " FROM ".MAIN_DB_PREFIX."c_shipment_mode as em";
  978. $sql.= " WHERE em.rowid = ".$this->expedition_method_id;
  979. $resql = $this->db->query($sql);
  980. if ($resql)
  981. {
  982. if ($obj = $this->db->fetch_object($resql))
  983. {
  984. $code = $obj->code;
  985. }
  986. }
  987. }
  988. if ($code)
  989. {
  990. $classname = "methode_expedition_".strtolower($code);
  991. $url='';
  992. if (file_exists(DOL_DOCUMENT_ROOT."/includes/modules/expedition/methode_expedition_".strtolower($code).".modules.php") && ! empty($this->tracking_number))
  993. {
  994. require_once(DOL_DOCUMENT_ROOT."/includes/modules/expedition/methode_expedition_".strtolower($code).".modules.php");
  995. $shipmethod = new $classname();
  996. $url = $shipmethod->provider_url_status($this->tracking_number);
  997. }
  998. if ($url)
  999. {
  1000. $this->tracking_url = sprintf('<a target="_blank" href="%s">'.($value?$value:'url').'</a>',$url,$url);
  1001. }
  1002. else
  1003. {
  1004. $this->tracking_url = $value;
  1005. }
  1006. }
  1007. else
  1008. {
  1009. $this->tracking_url = $value;
  1010. }
  1011. }
  1012. }
  1013. /**
  1014. * \class ExpeditionLigne
  1015. * \brief Classe de gestion des lignes de bons d'expedition
  1016. */
  1017. class ExpeditionLigne
  1018. {
  1019. var $db;
  1020. // From llx_expeditiondet
  1021. var $qty;
  1022. var $qty_shipped;
  1023. var $fk_product;
  1024. // From llx_commandedet or llx_propaldet
  1025. var $qty_asked;
  1026. var $libelle; // Label produit
  1027. var $product_desc; // Description produit
  1028. var $ref;
  1029. function ExpeditionLigne($DB)
  1030. {
  1031. $this->db=$DB;
  1032. }
  1033. }
  1034. ?>