From 35dd492d19ae8076e13512e33f09d1a66d55a46e Mon Sep 17 00:00:00 2001 From: Laurent Destailleur <eldy@destailleur.fr> Date: Thu, 22 Sep 2016 12:53:44 +0200 Subject: [PATCH] NEW Add REST api for commercial proposals --- htdocs/api/index.php | 26 +- .../comm/propal/class/api_proposals.class.php | 504 ++++++++++++++++++ htdocs/comm/propal/class/propal.class.php | 178 ++++--- htdocs/commande/class/api_orders.class.php | 17 +- htdocs/commande/class/commande.class.php | 4 +- 5 files changed, 628 insertions(+), 101 deletions(-) create mode 100644 htdocs/comm/propal/class/api_proposals.class.php diff --git a/htdocs/api/index.php b/htdocs/api/index.php index bfb9fca54b8..549e164abde 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -82,21 +82,27 @@ foreach ($modulesdir as $dir) { if (is_readable($dir.$file) && preg_match("/^mod(.*)\.class\.php$/i",$file,$reg)) { - $module = $part = strtolower($reg[1]); - - if ($module == 'agenda') { - $part = 'comm/action'; + $module = strtolower($reg[1]); + $moduledirforclass = $module; + $moduleforperm = $module; + + if ($module == 'propale') { + $moduledirforclass = 'comm/propal'; + $moduleforperm='propal'; + } + elseif ($module == 'agenda') { + $moduledirforclass = 'comm/action'; } - if ($module == 'categorie') { - $part = 'categories'; + elseif ($module == 'categorie') { + $moduledirforclass = 'categories'; } - if ($module == 'facture') { - $part = 'compta/facture'; + elseif ($module == 'facture') { + $moduledirforclass = 'compta/facture'; } // Defined if module is enabled $enabled=true; - if (empty($conf->$module->enabled)) $enabled=false; + if (empty($conf->$moduleforperm->enabled)) $enabled=false; if ($enabled) { @@ -108,7 +114,7 @@ foreach ($modulesdir as $dir) * @todo : take care of externals module! * @todo : use getElementProperties() function ? */ - $dir_part = DOL_DOCUMENT_ROOT.'/'.$part.'/class/'; + $dir_part = DOL_DOCUMENT_ROOT.'/'.$moduledirforclass.'/class/'; $handle_part=@opendir(dol_osencode($dir_part)); if (is_resource($handle_part)) diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php new file mode 100644 index 00000000000..9a33c4d7cbc --- /dev/null +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -0,0 +1,504 @@ +<?php +/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr> + * Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + use Luracast\Restler\RestException; + + require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; + +/** + * API class for orders + * + * @access protected + * @class DolibarrApiAccess {@requires user,external} + */ +class Proposals extends DolibarrApi +{ + + /** + * @var array $FIELDS Mandatory fields, checked when create and update object + */ + static $FIELDS = array( + 'socid' + ); + + /** + * @var propal $propal {@type propal} + */ + public $propal; + + /** + * Constructor + */ + function __construct() + { + global $db, $conf; + $this->db = $db; + $this->propal = new Propal($this->db); + } + + /** + * Get properties of a commercial proposal object + * + * Return an array with commercial proposal informations + * + * @param int $id ID of commercial proposal + * @return array|mixed data without useless information + * + * @throws RestException + */ + function get($id) + { + if(! DolibarrApiAccess::$user->rights->propal->lire) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $this->propal->fetchObjectLinked(); + return $this->_cleanObjectDatas($this->propal); + } + + /** + * List commercial proposals + * + * Get a list of commercial proposals + * + * @param string $sortfield Sort field + * @param string $sortorder Sort order + * @param int $limit Limit for list + * @param int $page Page number + * @param string $thirdparty_ids Thirdparty ids to filter commercial proposal of. Example: '1' or '1,2,3' {@pattern /^[0-9,]*$/i} + * + * @return array Array of order objects + */ + function index($sortfield = "s.rowid", $sortorder = 'ASC', $limit = 0, $page = 0, $thirdparty_ids = '') { + global $db, $conf; + + $obj_ret = array(); + // case of external user, $thirdpartyid param is ignored and replaced by user's socid + $socids = DolibarrApiAccess::$user->societe_id ? DolibarrApiAccess::$user->societe_id : $thirdparty_ids; + + // If the internal user must only see his customers, force searching by him + if (! DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) $search_sale = DolibarrApiAccess::$user->id; + + $sql = "SELECT s.rowid"; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql .= ", sc.fk_soc, sc.fk_user"; // We need these fields in order to filter by sale (including the case where the user can only see his prospects) + $sql.= " FROM ".MAIN_DB_PREFIX."propal as s"; + + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; // We need this table joined to the select in order to filter by sale + + $sql.= ' WHERE s.entity IN ('.getEntity('propal', 1).')'; + if ((!DolibarrApiAccess::$user->rights->societe->client->voir && !$socids) || $search_sale > 0) $sql.= " AND s.fk_soc = sc.fk_soc"; + if ($socids) $sql.= " AND s.fk_soc IN (".$socids.")"; + if ($search_sale > 0) $sql.= " AND s.rowid = sc.fk_soc"; // Join for the needed table to filter by sale + + // Insert sale filter + if ($search_sale > 0) + { + $sql .= " AND sc.fk_user = ".$search_sale; + } + + $nbtotalofrecords = 0; + if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) + { + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + } + + $sql.= $db->order($sortfield, $sortorder); + if ($limit) { + if ($page < 0) + { + $page = 0; + } + $offset = $limit * $page; + + $sql.= $db->plimit($limit + 1, $offset); + } + + $result = $db->query($sql); + + if ($result) + { + $num = $db->num_rows($result); + while ($i < $num) + { + $obj = $db->fetch_object($result); + $propal_static = new Propal($db); + if($propal_static->fetch($obj->rowid)) { + $obj_ret[] = parent::_cleanObjectDatas($propal_static); + } + $i++; + } + } + else { + throw new RestException(503, 'Error when retrieve propal list'); + } + if( ! count($obj_ret)) { + throw new RestException(404, 'No order found'); + } + return $obj_ret; + } + + /** + * Create commercial proposal object + * + * @param array $request_data Request data + * @return int ID of propal + */ + function post($request_data = NULL) + { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401, "Insuffisant rights"); + } + // Check mandatory fields + $result = $this->_validate($request_data); + + foreach($request_data as $field => $value) { + $this->propal->$field = $value; + } + /*if (isset($request_data["lines"])) { + $lines = array(); + foreach ($request_data["lines"] as $line) { + array_push($lines, (object) $line); + } + $this->propal->lines = $lines; + }*/ + if ($this->propal->create(DolibarrApiAccess::$user) <= 0) { + $errormsg = $this->propal->error; + throw new RestException(500, $errormsg ? $errormsg : "Error while creating order"); + } + + return $this->propal->id; + } + + /** + * Get lines of a commercial proposal + * + * @param int $id Id of commercial proposal + * + * @url GET {id}/lines + * + * @return int + */ + function getLines($id) { + if(! DolibarrApiAccess::$user->rights->propal->lire) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $this->propal->getLinesArray(); + $result = array(); + foreach ($this->propal->lines as $line) { + array_push($result,$this->_cleanObjectDatas($line)); + } + return $result; + } + + /** + * Add a line to given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Commercial proposal line data + * + * @url POST {id}/lines + * + * @return int + */ + function postLine($id, $request_data = NULL) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $request_data = (object) $request_data; + $updateRes = $this->propal->addline( + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + $request_data->fk_product, + $request_data->remise_percent, + $request_data->info_bits, + $request_data->fk_remise_except, + 'HT', + 0, + $request_data->date_start, + $request_data->date_end, + $request_data->product_type, + $request_data->rang, + $request_data->special_code, + $fk_parent_line, + $request_data->fk_fournprice, + $request_data->pa_ht, + $request_data->label, + $request_data->array_options, + $request_data->fk_unit, + $this->element, + $request_data->id + ); + + if ($updateRes > 0) { + return $this->get($id)->line->rowid; + + } + return false; + } + + /** + * Update a line of given commercial proposal + * + * @param int $id Id of commercial proposal to update + * @param int $lineid Id of line to update + * @param array $request_data Commercial proposal line data + * + * @url PUT {id}/lines/{lineid} + * + * @return object + */ + function putLine($id, $lineid, $request_data = NULL) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $request_data = (object) $request_data; + $updateRes = $this->propal->updateline( + $lineid, + $request_data->desc, + $request_data->subprice, + $request_data->qty, + $request_data->remise_percent, + $request_data->tva_tx, + $request_data->localtax1_tx, + $request_data->localtax2_tx, + 'HT', + $request_data->info_bits, + $request_data->date_start, + $request_data->date_end, + $request_data->product_type, + $request_data->fk_parent_line, + 0, + $request_data->fk_fournprice, + $request_data->pa_ht, + $request_data->label, + $request_data->special_code, + $request_data->array_options, + $request_data->fk_unit + ); + + if ($updateRes > 0) { + $result = $this->get($id); + unset($result->line); + return $this->_cleanObjectDatas($result); + } + return false; + } + + /** + * Delete a line of given commercial proposal + * + * + * @param int $id Id of commercial proposal to update + * @param int $lineid Id of line to delete + * + * @url DELETE {id}/lines/{lineid} + * + * @return int + */ + function delLine($id, $lineid) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + $request_data = (object) $request_data; + $updateRes = $this->propal->deleteline($lineid); + if ($updateRes == 1) { + return $this->get($id); + } + return false; + } + + /** + * Update commercial proposal general fields (won't touch lines of commercial proposal) + * + * @param int $id Id of commercial proposal to update + * @param array $request_data Datas + * + * @return int + */ + function put($id, $request_data = NULL) { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + foreach($request_data as $field => $value) { + $this->propal->$field = $value; + } + + if($this->propal->update($id, DolibarrApiAccess::$user,1,'','','update')) + return $this->get($id); + + return false; + } + + /** + * Delete commercial proposal + * + * @param int $id Commercial proposal ID + * + * @return array + */ + function delete($id) + { + if(! DolibarrApiAccess::$user->rights->propal->supprimer) { + throw new RestException(401); + } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + if( ! $this->propal->delete(DolibarrApiAccess::$user)) { + throw new RestException(500, 'Error when delete Commercial Proposal : '.$this->propal->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Commercial Proposal deleted' + ) + ); + + } + + /** + * Validate a commercial proposal + * + * @param int $id Commercial proposal ID + * @param int $notrigger Use {} + * + * @url POST {id}/validate + * + * @return array + * FIXME An error 403 is returned if the request has an empty body. + * Error message: "Forbidden: Content type `text/plain` is not supported." + * Workaround: send this in the body + * { + * "notrigger": 0 + * } + */ + function validate($id, $notrigger=0) + { + if(! DolibarrApiAccess::$user->rights->propal->creer) { + throw new RestException(401); + } + $result = $this->propal->fetch($id); + if( ! $result ) { + throw new RestException(404, 'Commercial Proposal not found'); + } + + if( ! DolibarrApi::_checkAccessToResource('propal',$this->propal->id)) { + throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); + } + + $result = $this->propal->valid(DolibarrApiAccess::$user, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Commercial Proposal: '.$this->propal->error); + } + + return array( + 'success' => array( + 'code' => 200, + 'message' => 'Commercial Proposal validated' + ) + ); + } + + /** + * Validate fields before create or update object + * + * @param array $data Array with data to verify + * @return array + * @throws RestException + */ + function _validate($data) + { + $propal = array(); + foreach (Orders::$FIELDS as $field) { + if (!isset($data[$field])) + throw new RestException(400, "$field field missing"); + $propal[$field] = $data[$field]; + + } + return $propal; + } +} diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index fb24e82f68d..f3eccc2a9be 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1504,8 +1504,8 @@ class Propal extends CommonObject * Set status to validated * * @param User $user Object user that validate - * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers - * @return int <0 if KO, >=0 if OK + * @param int $notrigger 1=Does not execute triggers, 0=execute triggers + * @return int <0 if KO, 0=Nothing done, >=0 if OK */ function valid($user, $notrigger=0) { @@ -1514,98 +1514,110 @@ class Propal extends CommonObject global $conf; $error=0; - $now=dol_now(); - if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) - || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate))) + // Protection + if ($this->statut == self::STATUS_VALIDATED) { - $this->db->begin(); + dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING); + return 0; + } + + if (! ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->creer)) + || (! empty($conf->global->MAIN_USE_ADVANCED_PERMS) && ! empty($user->rights->propal->propal_advance->validate)))) + { + $this->error='ErrorPermissionDenied'; + dol_syslog(get_class($this)."::valid ".$this->error, LOG_ERR); + return -1; + } - // Numbering module definition - $soc = new Societe($this->db); - $soc->fetch($this->socid); + $now=dol_now(); + + $this->db->begin(); - // Define new ref - if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life - { - $num = $this->getNextNumRef($soc); - } - else - { - $num = $this->ref; - } - $this->newref = $num; + // Numbering module definition + $soc = new Societe($this->db); + $soc->fetch($this->socid); - $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; - $sql.= " SET ref = '".$num."',"; - $sql.= " fk_statut = ".self::STATUS_VALIDATED.", date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id; - $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; + // Define new ref + if (! $error && (preg_match('/^[\(]?PROV/i', $this->ref) || empty($this->ref))) // empty should not happened, but when it occurs, the test save life + { + $num = $this->getNextNumRef($soc); + } + else + { + $num = $this->ref; + } + $this->newref = $num; - dol_syslog(get_class($this)."::valid", LOG_DEBUG); - $resql=$this->db->query($sql); - if (! $resql) - { - dol_print_error($this->db); - $error++; - } + $sql = "UPDATE ".MAIN_DB_PREFIX."propal"; + $sql.= " SET ref = '".$num."',"; + $sql.= " fk_statut = ".self::STATUS_VALIDATED.", date_valid='".$this->db->idate($now)."', fk_user_valid=".$user->id; + $sql.= " WHERE rowid = ".$this->id." AND fk_statut = ".self::STATUS_DRAFT; - // Trigger calls - if (! $error && ! $notrigger) - { - // Call trigger - $result=$this->call_trigger('PROPAL_VALIDATE',$user); - if ($result < 0) { $error++; } - // End call triggers - } + dol_syslog(get_class($this)."::valid", LOG_DEBUG); + $resql=$this->db->query($sql); + if (! $resql) + { + dol_print_error($this->db); + $error++; + } - if (! $error) - { - $this->oldref = $this->ref; + // Trigger calls + if (! $error && ! $notrigger) + { + // Call trigger + $result=$this->call_trigger('PROPAL_VALIDATE',$user); + if ($result < 0) { $error++; } + // End call triggers + } - // Rename directory if dir was a temporary ref - if (preg_match('/^[\(]?PROV/i', $this->ref)) - { - // Rename of propal directory ($this->ref = old ref, $num = new ref) - // to not lose the linked files - $oldref = dol_sanitizeFileName($this->ref); - $newref = dol_sanitizeFileName($num); - $dirsource = $conf->propal->dir_output.'/'.$oldref; - $dirdest = $conf->propal->dir_output.'/'.$newref; - - if (file_exists($dirsource)) - { - dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); - if (@rename($dirsource, $dirdest)) - { - dol_syslog("Rename ok"); - // Rename docs starting with $oldref with $newref - $listoffiles=dol_dir_list($conf->propal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); - foreach($listoffiles as $fileentry) - { - $dirsource=$fileentry['name']; - $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); - $dirsource=$fileentry['path'].'/'.$dirsource; - $dirdest=$fileentry['path'].'/'.$dirdest; - @rename($dirsource, $dirdest); - } - } - } - } + if (! $error) + { + $this->oldref = $this->ref; + + // Rename directory if dir was a temporary ref + if (preg_match('/^[\(]?PROV/i', $this->ref)) + { + // Rename of propal directory ($this->ref = old ref, $num = new ref) + // to not lose the linked files + $oldref = dol_sanitizeFileName($this->ref); + $newref = dol_sanitizeFileName($num); + $dirsource = $conf->propal->dir_output.'/'.$oldref; + $dirdest = $conf->propal->dir_output.'/'.$newref; + + if (file_exists($dirsource)) + { + dol_syslog(get_class($this)."::validate rename dir ".$dirsource." into ".$dirdest); + if (@rename($dirsource, $dirdest)) + { + dol_syslog("Rename ok"); + // Rename docs starting with $oldref with $newref + $listoffiles=dol_dir_list($conf->propal->dir_output.'/'.$newref, 'files', 1, '^'.preg_quote($oldref,'/')); + foreach($listoffiles as $fileentry) + { + $dirsource=$fileentry['name']; + $dirdest=preg_replace('/^'.preg_quote($oldref,'/').'/',$newref, $dirsource); + $dirsource=$fileentry['path'].'/'.$dirsource; + $dirdest=$fileentry['path'].'/'.$dirdest; + @rename($dirsource, $dirdest); + } + } + } + } - $this->ref=$num; - $this->brouillon=0; - $this->statut = self::STATUS_VALIDATED; - $this->user_valid_id=$user->id; - $this->datev=$now; + $this->ref=$num; + $this->brouillon=0; + $this->statut = self::STATUS_VALIDATED; + $this->user_valid_id=$user->id; + $this->datev=$now; - $this->db->commit(); - return 1; - } - else - { - $this->db->rollback(); - return -1; - } + $this->db->commit(); + return 1; + } + else + { + $this->db->rollback(); + return -1; } } diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 72d01c33bc8..ad3c17d1187 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -449,10 +449,11 @@ class Orders extends DolibarrApi * Error message: "Forbidden: Content type `text/plain` is not supported." * Workaround: send this in the body * { - * "idwarehouse": 0 + * "idwarehouse": 0, + * "notrigger": 0 * } */ - function validate($id, $idwarehouse=0) + function validate($id, $idwarehouse=0, $notrigger=0) { if(! DolibarrApiAccess::$user->rights->commande->creer) { throw new RestException(401); @@ -466,10 +467,14 @@ class Orders extends DolibarrApi throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login); } - if( ! $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse)) { - throw new RestException(500, 'Error when validate order'); - } - + $result = $this->commande->valid(DolibarrApiAccess::$user, $idwarehouse, $notrigger); + if ($result == 0) { + throw new RestException(500, 'Error nothing done. May be object is already validated'); + } + if ($result < 0) { + throw new RestException(500, 'Error when validating Order: '.$this->commande->error); + } + return array( 'success' => array( 'code' => 200, diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 108fcf90d84..c0d4ab66a81 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -260,7 +260,7 @@ class Commande extends CommonOrder * @param User $user User making status change * @param int $idwarehouse Id of warehouse to use for stock decrease * @param int $notrigger 1=Does not execute triggers, 0= execuete triggers - * @return int <=0 if OK, >0 if KO + * @return int <=0 if OK, 0=Nothing done, >0 if KO */ function valid($user, $idwarehouse=0, $notrigger=0) { @@ -272,7 +272,7 @@ class Commande extends CommonOrder // Protection if ($this->statut == self::STATUS_VALIDATED) { - dol_syslog(get_class($this)."::valid action abandonned: no draft status", LOG_WARNING); + dol_syslog(get_class($this)."::valid action abandonned: already validated", LOG_WARNING); return 0; } -- GitLab