server_order.php 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000
  1. <?php
  2. /* Copyright (C) 2006-2016 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2012 JF FERRY <jfefe@aternatik.fr>
  4. * Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
  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 3 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 <https://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/webservices/server_order.php
  21. * \brief File that is entry point to call Dolibarr WebServices
  22. */
  23. if (!defined('NOCSRFCHECK')) {
  24. define('NOCSRFCHECK', '1'); // Do not check anti CSRF attack test
  25. }
  26. if (!defined('NOTOKENRENEWAL')) {
  27. define('NOTOKENRENEWAL', '1'); // Do not check anti POST attack test
  28. }
  29. if (!defined('NOREQUIREMENU')) {
  30. define('NOREQUIREMENU', '1'); // If there is no need to load and show top and left menu
  31. }
  32. if (!defined('NOREQUIREHTML')) {
  33. define('NOREQUIREHTML', '1'); // If we don't need to load the html.form.class.php
  34. }
  35. if (!defined('NOREQUIREAJAX')) {
  36. define('NOREQUIREAJAX', '1'); // Do not load ajax.lib.php library
  37. }
  38. if (!defined("NOLOGIN")) {
  39. define("NOLOGIN", '1'); // If this page is public (can be called outside logged session)
  40. }
  41. if (!defined("NOSESSION")) {
  42. define("NOSESSION", '1');
  43. }
  44. require '../main.inc.php';
  45. require_once NUSOAP_PATH.'/nusoap.php'; // Include SOAP
  46. require_once DOL_DOCUMENT_ROOT.'/core/lib/ws.lib.php';
  47. require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
  48. require_once DOL_DOCUMENT_ROOT."/commande/class/commande.class.php";
  49. dol_syslog("Call Dolibarr webservices interfaces");
  50. $langs->load("main");
  51. // Enable and test if module web services is enabled
  52. if (empty($conf->global->MAIN_MODULE_WEBSERVICES)) {
  53. $langs->load("admin");
  54. dol_syslog("Call Dolibarr webservices interfaces with module webservices disabled");
  55. print $langs->trans("WarningModuleNotActive", 'WebServices').'.<br><br>';
  56. print $langs->trans("ToActivateModule");
  57. exit;
  58. }
  59. // Create the soap Object
  60. $server = new nusoap_server();
  61. $server->soap_defencoding = 'UTF-8';
  62. $server->decode_utf8 = false;
  63. $ns = 'http://www.dolibarr.org/ns/';
  64. $server->configureWSDL('WebServicesDolibarrOrder', $ns);
  65. $server->wsdl->schemaTargetNamespace = $ns;
  66. // Define WSDL Authentication object
  67. $server->wsdl->addComplexType(
  68. 'authentication',
  69. 'complexType',
  70. 'struct',
  71. 'all',
  72. '',
  73. array(
  74. 'dolibarrkey' => array('name'=>'dolibarrkey', 'type'=>'xsd:string'),
  75. 'sourceapplication' => array('name'=>'sourceapplication', 'type'=>'xsd:string'),
  76. 'login' => array('name'=>'login', 'type'=>'xsd:string'),
  77. 'password' => array('name'=>'password', 'type'=>'xsd:string'),
  78. 'entity' => array('name'=>'entity', 'type'=>'xsd:string')
  79. )
  80. );
  81. // Define WSDL Return object
  82. $server->wsdl->addComplexType(
  83. 'result',
  84. 'complexType',
  85. 'struct',
  86. 'all',
  87. '',
  88. array(
  89. 'result_code' => array('name'=>'result_code', 'type'=>'xsd:string'),
  90. 'result_label' => array('name'=>'result_label', 'type'=>'xsd:string'),
  91. )
  92. );
  93. $line_fields = array(
  94. 'id' => array('name'=>'id', 'type'=>'xsd:string'),
  95. 'type' => array('name'=>'type', 'type'=>'xsd:int'),
  96. 'fk_commande' => array('name'=>'fk_commande', 'type'=>'xsd:int'),
  97. 'fk_parent_line' => array('name'=>'fk_parent_line', 'type'=>'xsd:int'),
  98. 'desc' => array('name'=>'desc', 'type'=>'xsd:string'),
  99. 'qty' => array('name'=>'qty', 'type'=>'xsd:double'),
  100. 'price' => array('name'=>'price', 'type'=>'xsd:double'),
  101. 'unitprice' => array('name'=>'unitprice', 'type'=>'xsd:double'),
  102. 'vat_rate' => array('name'=>'vat_rate', 'type'=>'xsd:double'),
  103. 'remise' => array('name'=>'remise', 'type'=>'xsd:double'),
  104. 'remise_percent' => array('name'=>'remise_percent', 'type'=>'xsd:double'),
  105. 'total_net' => array('name'=>'total_net', 'type'=>'xsd:double'),
  106. 'total_vat' => array('name'=>'total_vat', 'type'=>'xsd:double'),
  107. 'total' => array('name'=>'total', 'type'=>'xsd:double'),
  108. 'date_start' => array('name'=>'date_start', 'type'=>'xsd:date'),
  109. 'date_end' => array('name'=>'date_end', 'type'=>'xsd:date'),
  110. // From product
  111. 'product_id' => array('name'=>'product_id', 'type'=>'xsd:int'),
  112. 'product_ref' => array('name'=>'product_ref', 'type'=>'xsd:string'),
  113. 'product_label' => array('name'=>'product_label', 'type'=>'xsd:string'),
  114. 'product_desc' => array('name'=>'product_desc', 'type'=>'xsd:string')
  115. );
  116. $elementtype = 'commandedet';
  117. //Retrieve all extrafield for thirdsparty
  118. // fetch optionals attributes and labels
  119. $extrafields = new ExtraFields($db);
  120. $extrafields->fetch_name_optionals_label($elementtype, true);
  121. $extrafield_line_array = null;
  122. if (is_array($extrafields) && count($extrafields) > 0) {
  123. $extrafield_line_array = array();
  124. }
  125. if (isset($extrafields->attributes[$elementtype]['label']) && is_array($extrafields->attributes[$elementtype]['label']) && count($extrafields->attributes[$elementtype]['label'])) {
  126. foreach ($extrafields->attributes[$elementtype]['label'] as $key => $label) {
  127. //$value=$object->array_options["options_".$key];
  128. $type = $extrafields->attributes[$elementtype]['type'][$key];
  129. if ($type == 'date' || $type == 'datetime') {
  130. $type = 'xsd:dateTime';
  131. } else {
  132. $type = 'xsd:string';
  133. }
  134. $extrafield_line_array['options_'.$key] = array('name'=>'options_'.$key, 'type'=>$type);
  135. }
  136. }
  137. if (is_array($extrafield_line_array)) {
  138. $line_fields = array_merge($line_fields, $extrafield_line_array);
  139. }
  140. // Define other specific objects
  141. $server->wsdl->addComplexType(
  142. 'line',
  143. 'complexType',
  144. 'struct',
  145. 'all',
  146. '',
  147. $line_fields
  148. );
  149. /*$server->wsdl->addComplexType(
  150. 'LinesArray',
  151. 'complexType',
  152. 'array',
  153. '',
  154. 'SOAP-ENC:Array',
  155. array(),
  156. array(
  157. array(
  158. 'ref'=>'SOAP-ENC:arrayType',
  159. 'wsdl:arrayType'=>'tns:line[]'
  160. )
  161. ),
  162. 'tns:line'
  163. );*/
  164. $server->wsdl->addComplexType(
  165. 'LinesArray2',
  166. 'complexType',
  167. 'array',
  168. 'sequence',
  169. '',
  170. array(
  171. 'line' => array(
  172. 'name' => 'line',
  173. 'type' => 'tns:line',
  174. 'minOccurs' => '0',
  175. 'maxOccurs' => 'unbounded'
  176. )
  177. )
  178. );
  179. $order_fields = array(
  180. 'id' => array('name'=>'id', 'type'=>'xsd:string'),
  181. 'ref' => array('name'=>'ref', 'type'=>'xsd:string'),
  182. 'ref_client' => array('name'=>'ref_client', 'type'=>'xsd:string'),
  183. 'ref_ext' => array('name'=>'ref_ext', 'type'=>'xsd:string'),
  184. 'thirdparty_id' => array('name'=>'thirdparty_id', 'type'=>'xsd:int'),
  185. 'status' => array('name'=>'status', 'type'=>'xsd:int'),
  186. 'billed' => array('name'=>'billed', 'type'=>'xsd:string'),
  187. 'total_net' => array('name'=>'total_net', 'type'=>'xsd:double'),
  188. 'total_vat' => array('name'=>'total_vat', 'type'=>'xsd:double'),
  189. 'total_localtax1' => array('name'=>'total_localtax1', 'type'=>'xsd:double'),
  190. 'total_localtax2' => array('name'=>'total_localtax2', 'type'=>'xsd:double'),
  191. 'total' => array('name'=>'total', 'type'=>'xsd:double'),
  192. 'date' => array('name'=>'date', 'type'=>'xsd:date'),
  193. 'date_creation' => array('name'=>'date_creation', 'type'=>'xsd:dateTime'),
  194. 'date_validation' => array('name'=>'date_validation', 'type'=>'xsd:dateTime'),
  195. 'date_modification' => array('name'=>'date_modification', 'type'=>'xsd:dateTime'),
  196. 'remise' => array('name'=>'remise', 'type'=>'xsd:string'),
  197. 'remise_percent' => array('name'=>'remise_percent', 'type'=>'xsd:string'),
  198. 'remise_absolue' => array('name'=>'remise_absolue', 'type'=>'xsd:string'),
  199. 'source' => array('name'=>'source', 'type'=>'xsd:string'),
  200. 'note_private' => array('name'=>'note_private', 'type'=>'xsd:string'),
  201. 'note_public' => array('name'=>'note_public', 'type'=>'xsd:string'),
  202. 'project_id' => array('name'=>'project_id', 'type'=>'xsd:string'),
  203. 'mode_reglement_id' => array('name'=>'mode_reglement_id', 'type'=>'xsd:string'),
  204. 'mode_reglement_code' => array('name'=>'mode_reglement_code', 'type'=>'xsd:string'),
  205. 'mode_reglement' => array('name'=>'mode_reglement', 'type'=>'xsd:string'),
  206. 'cond_reglement_id' => array('name'=>'cond_reglement_id', 'type'=>'xsd:string'),
  207. 'cond_reglement_code' => array('name'=>'cond_reglement_code', 'type'=>'xsd:string'),
  208. 'cond_reglement' => array('name'=>'cond_reglement', 'type'=>'xsd:string'),
  209. 'cond_reglement_doc' => array('name'=>'cond_reglement_doc', 'type'=>'xsd:string'),
  210. 'date_livraison' => array('name'=>'date_livraison', 'type'=>'xsd:date'),
  211. 'demand_reason_id' => array('name'=>'demand_reason_id', 'type'=>'xsd:string'),
  212. 'lines' => array('name'=>'lines', 'type'=>'tns:LinesArray2')
  213. );
  214. $elementtype = 'commande';
  215. //Retrieve all extrafield for thirdsparty
  216. // fetch optionals attributes and labels
  217. $extrafields = new ExtraFields($db);
  218. $extrafields->fetch_name_optionals_label($elementtype, true);
  219. $extrafield_array = null;
  220. if (is_array($extrafields) && count($extrafields) > 0) {
  221. $extrafield_array = array();
  222. }
  223. if (isset($extrafields->attributes[$elementtype]['label']) && is_array($extrafields->attributes[$elementtype]['label']) && count($extrafields->attributes[$elementtype]['label'])) {
  224. foreach ($extrafields->attributes[$elementtype]['label'] as $key => $label) {
  225. //$value=$object->array_options["options_".$key];
  226. $type = $extrafields->attributes[$elementtype]['type'][$key];
  227. if ($type == 'date' || $type == 'datetime') {
  228. $type = 'xsd:dateTime';
  229. } else {
  230. $type = 'xsd:string';
  231. }
  232. $extrafield_array['options_'.$key] = array('name'=>'options_'.$key, 'type'=>$type);
  233. }
  234. }
  235. if (is_array($extrafield_array)) {
  236. $order_fields = array_merge($order_fields, $extrafield_array);
  237. }
  238. $server->wsdl->addComplexType(
  239. 'order',
  240. 'complexType',
  241. 'struct',
  242. 'all',
  243. '',
  244. $order_fields
  245. );
  246. /*
  247. $server->wsdl->addComplexType(
  248. 'OrdersArray',
  249. 'complexType',
  250. 'array',
  251. '',
  252. 'SOAP-ENC:Array',
  253. array(),
  254. array(
  255. array(
  256. 'ref'=>'SOAP-ENC:arrayType',
  257. 'wsdl:arrayType'=>'tns:order[]'
  258. )
  259. ),
  260. 'tns:order'
  261. );*/
  262. $server->wsdl->addComplexType(
  263. 'OrdersArray2',
  264. 'complexType',
  265. 'array',
  266. 'sequence',
  267. '',
  268. array(
  269. 'order' => array(
  270. 'name' => 'order',
  271. 'type' => 'tns:order',
  272. 'minOccurs' => '0',
  273. 'maxOccurs' => 'unbounded'
  274. )
  275. )
  276. );
  277. // 5 styles: RPC/encoded, RPC/literal, Document/encoded (not WS-I compliant), Document/literal, Document/literal wrapped
  278. // Style merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model.
  279. // http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
  280. $styledoc = 'rpc'; // rpc/document (document is an extend into SOAP 1.0 to support unstructured messages)
  281. $styleuse = 'encoded'; // encoded/literal/literal wrapped
  282. // Better choice is document/literal wrapped but literal wrapped not supported by nusoap.
  283. // Register WSDL
  284. $server->register(
  285. 'getOrder',
  286. array('authentication'=>'tns:authentication', 'id'=>'xsd:string', 'ref'=>'xsd:string', 'ref_ext'=>'xsd:string'), // Entry values
  287. array('result'=>'tns:result', 'order'=>'tns:order'), // Exit values
  288. $ns,
  289. $ns.'#getOrder',
  290. $styledoc,
  291. $styleuse,
  292. 'WS to get a particular invoice'
  293. );
  294. $server->register(
  295. 'getOrdersForThirdParty',
  296. array('authentication'=>'tns:authentication', 'idthirdparty'=>'xsd:string'), // Entry values
  297. array('result'=>'tns:result', 'orders'=>'tns:OrdersArray2'), // Exit values
  298. $ns,
  299. $ns.'#getOrdersForThirdParty',
  300. $styledoc,
  301. $styleuse,
  302. 'WS to get all orders of a third party'
  303. );
  304. $server->register(
  305. 'createOrder',
  306. array('authentication'=>'tns:authentication', 'order'=>'tns:order'), // Entry values
  307. array('result'=>'tns:result', 'id'=>'xsd:string', 'ref'=>'xsd:string'), // Exit values
  308. $ns,
  309. $ns.'#createOrder',
  310. $styledoc,
  311. $styleuse,
  312. 'WS to create an order'
  313. );
  314. $server->register(
  315. 'updateOrder',
  316. array('authentication'=>'tns:authentication', 'order'=>'tns:order'), // Entry values
  317. array('result'=>'tns:result', 'id'=>'xsd:string', 'ref'=>'xsd:string', 'ref_ext'=>'xsd:string'), // Exit values
  318. $ns,
  319. $ns.'#updateOrder',
  320. $styledoc,
  321. $styleuse,
  322. 'WS to update an order'
  323. );
  324. $server->register(
  325. 'validOrder',
  326. array('authentication'=>'tns:authentication', 'id'=>'xsd:string', 'id_warehouse'=>'xsd:string'), // Entry values
  327. array('result'=>'tns:result'), // Exit values
  328. $ns,
  329. $ns.'#validOrder',
  330. $styledoc,
  331. $styleuse,
  332. 'WS to valid an order'
  333. );
  334. /**
  335. * Get order from id, ref or ref_ext.
  336. *
  337. * @param array $authentication Array of authentication information
  338. * @param int $id Id
  339. * @param string $ref Ref
  340. * @param string $ref_ext Ref_ext
  341. * @return array Array result
  342. */
  343. function getOrder($authentication, $id = '', $ref = '', $ref_ext = '')
  344. {
  345. global $db, $conf;
  346. dol_syslog("Function: getOrder login=".$authentication['login']." id=".$id." ref=".$ref." ref_ext=".$ref_ext);
  347. if ($authentication['entity']) {
  348. $conf->entity = $authentication['entity'];
  349. }
  350. // Init and check authentication
  351. $objectresp = array();
  352. $errorcode = ''; $errorlabel = '';
  353. $error = 0;
  354. $socid = 0;
  355. $fuser = check_authentication($authentication, $error, $errorcode, $errorlabel);
  356. if ($fuser->socid) {
  357. $socid = $fuser->socid;
  358. }
  359. // Check parameters
  360. if (!$error && (($id && $ref) || ($id && $ref_ext) || ($ref && $ref_ext))) {
  361. $error++;
  362. $errorcode = 'BAD_PARAMETERS'; $errorlabel = "Parameter id, ref and ref_ext can't be both provided. You must choose one or other but not both.";
  363. }
  364. if (!$error) {
  365. $fuser->getrights();
  366. if ($fuser->rights->commande->lire) {
  367. $order = new Commande($db);
  368. $result = $order->fetch($id, $ref, $ref_ext);
  369. if ($result > 0) {
  370. // Security for external user
  371. if ($socid && $socid != $order->socid) {
  372. $error++;
  373. $errorcode = 'PERMISSION_DENIED'; $errorlabel = 'User does not have permission for this request';
  374. }
  375. if (!$error) {
  376. $linesresp = array();
  377. $i = 0;
  378. foreach ($order->lines as $line) {
  379. //var_dump($line); exit;
  380. $linesresp[] = array(
  381. 'id'=>$line->rowid,
  382. 'fk_commande'=>$line->fk_commande,
  383. 'fk_parent_line'=>$line->fk_parent_line,
  384. 'desc'=>$line->desc,
  385. 'qty'=>$line->qty,
  386. 'price'=>$line->price,
  387. 'unitprice'=>$line->subprice,
  388. 'vat_rate'=>$line->tva_tx,
  389. 'remise'=>$line->remise,
  390. 'remise_percent'=>$line->remise_percent,
  391. 'product_id'=>$line->fk_product,
  392. 'product_type'=>$line->product_type,
  393. 'total_net'=>$line->total_ht,
  394. 'total_vat'=>$line->total_tva,
  395. 'total'=>$line->total_ttc,
  396. 'date_start'=>$line->date_start,
  397. 'date_end'=>$line->date_end,
  398. 'product_ref'=>$line->product_ref,
  399. 'product_label'=>$line->product_label,
  400. 'product_desc'=>$line->product_desc
  401. );
  402. $i++;
  403. }
  404. // Create order
  405. $objectresp = array(
  406. 'result'=>array('result_code'=>'OK', 'result_label'=>''),
  407. 'order'=>array(
  408. 'id' => $order->id,
  409. 'ref' => $order->ref,
  410. 'ref_client' => $order->ref_client,
  411. 'ref_ext' => $order->ref_ext,
  412. 'thirdparty_id' => $order->socid,
  413. 'status' => $order->statut,
  414. 'total_net' => $order->total_ht,
  415. 'total_vat' => $order->total_tva,
  416. 'total_localtax1' => $order->total_localtax1,
  417. 'total_localtax2' => $order->total_localtax2,
  418. 'total' => $order->total_ttc,
  419. 'project_id' => $order->fk_project,
  420. 'date' => $order->date ?dol_print_date($order->date, 'dayrfc') : '',
  421. 'date_creation' => $order->date_creation ?dol_print_date($order->date_creation, 'dayhourrfc') : '',
  422. 'date_validation' => $order->date_validation ?dol_print_date($order->date_creation, 'dayhourrfc') : '',
  423. 'date_modification' => $order->date_modification ?dol_print_date($order->date_modification, 'dayhourrfc') : '',
  424. 'remise' => $order->remise,
  425. 'remise_percent' => $order->remise_percent,
  426. 'remise_absolue' => $order->remise_absolue,
  427. 'source' => $order->source,
  428. 'billed' => $order->billed,
  429. 'note_private' => $order->note_private,
  430. 'note_public' => $order->note_public,
  431. 'cond_reglement_id' => $order->cond_reglement_id,
  432. 'cond_reglement_code' => $order->cond_reglement_code,
  433. 'cond_reglement' => $order->cond_reglement,
  434. 'mode_reglement_id' => $order->mode_reglement_id,
  435. 'mode_reglement_code' => $order->mode_reglement_code,
  436. 'mode_reglement' => $order->mode_reglement,
  437. 'date_livraison' => $order->delivery_date,
  438. 'demand_reason_id' => $order->demand_reason_id,
  439. 'demand_reason_code' => $order->demand_reason_code,
  440. 'lines' => $linesresp
  441. ));
  442. }
  443. } else {
  444. $error++;
  445. $errorcode = 'NOT_FOUND';
  446. $errorlabel = 'Object not found for id='.$id.' nor ref='.$ref.' nor ref_ext='.$ref_ext;
  447. }
  448. } else {
  449. $error++;
  450. $errorcode = 'PERMISSION_DENIED';
  451. $errorlabel = 'User does not have permission for this request';
  452. }
  453. }
  454. if ($error) {
  455. $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
  456. }
  457. return $objectresp;
  458. }
  459. /**
  460. * Get list of orders for third party
  461. *
  462. * @param array $authentication Array of authentication information
  463. * @param int $idthirdparty Id of thirdparty
  464. * @return array Array result
  465. */
  466. function getOrdersForThirdParty($authentication, $idthirdparty)
  467. {
  468. global $db, $conf;
  469. dol_syslog("Function: getOrdersForThirdParty login=".$authentication['login']." idthirdparty=".$idthirdparty);
  470. if ($authentication['entity']) {
  471. $conf->entity = $authentication['entity'];
  472. }
  473. // Init and check authentication
  474. $objectresp = array();
  475. $errorcode = ''; $errorlabel = '';
  476. $error = 0;
  477. $fuser = check_authentication($authentication, $error, $errorcode, $errorlabel);
  478. if ($fuser->socid) {
  479. $socid = $fuser->socid;
  480. }
  481. // Check parameters
  482. if (!$error && empty($idthirdparty)) {
  483. $error++;
  484. $errorcode = 'BAD_PARAMETERS'; $errorlabel = 'Parameter id is not provided';
  485. }
  486. if (!$error) {
  487. $linesorders = array();
  488. $sql = 'SELECT c.rowid as orderid';
  489. $sql .= ' FROM '.MAIN_DB_PREFIX.'commande as c';
  490. $sql .= " WHERE c.entity = ".$conf->entity;
  491. if ($idthirdparty != 'all') {
  492. $sql .= " AND c.fk_soc = ".((int) $idthirdparty);
  493. }
  494. $resql = $db->query($sql);
  495. if ($resql) {
  496. $num = $db->num_rows($resql);
  497. $i = 0;
  498. while ($i < $num) {
  499. // En attendant remplissage par boucle
  500. $obj = $db->fetch_object($resql);
  501. $order = new Commande($db);
  502. $order->fetch($obj->orderid);
  503. // Sécurité pour utilisateur externe
  504. if ($socid && ($socid != $order->socid)) {
  505. $error++;
  506. $errorcode = 'PERMISSION_DENIED';
  507. $errorlabel = $order->socid.' User does not have permission for this request';
  508. }
  509. if (!$error) {
  510. // Define lines of invoice
  511. $linesresp = array();
  512. foreach ($order->lines as $line) {
  513. $linesresp[] = array(
  514. 'id'=>$line->rowid,
  515. 'type'=>$line->product_type,
  516. 'fk_commande'=>$line->fk_commande,
  517. 'fk_parent_line'=>$line->fk_parent_line,
  518. 'desc'=>$line->desc,
  519. 'qty'=>$line->qty,
  520. 'price'=>$line->price,
  521. 'unitprice'=>$line->subprice,
  522. 'tva_tx'=>$line->tva_tx,
  523. 'remise'=>$line->remise,
  524. 'remise_percent'=>$line->remise_percent,
  525. 'total_net'=>$line->total_ht,
  526. 'total_vat'=>$line->total_tva,
  527. 'total'=>$line->total_ttc,
  528. 'date_start'=>$line->date_start,
  529. 'date_end'=>$line->date_end,
  530. 'product_id'=>$line->fk_product,
  531. 'product_ref'=>$line->product_ref,
  532. 'product_label'=>$line->product_label,
  533. 'product_desc'=>$line->product_desc
  534. );
  535. }
  536. // Now define invoice
  537. $linesorders[] = array(
  538. 'id' => $order->id,
  539. 'ref' => $order->ref,
  540. 'ref_client' => $order->ref_client,
  541. 'ref_ext' => $order->ref_ext,
  542. 'socid' => $order->socid,
  543. 'status' => $order->statut,
  544. 'total_net' => $order->total_ht,
  545. 'total_vat' => $order->total_tva,
  546. 'total_localtax1' => $order->total_localtax1,
  547. 'total_localtax2' => $order->total_localtax2,
  548. 'total' => $order->total_ttc,
  549. 'project_id' => $order->fk_project,
  550. 'date' => $order->date_commande ?dol_print_date($order->date_commande, 'dayrfc') : '',
  551. 'remise' => $order->remise,
  552. 'remise_percent' => $order->remise_percent,
  553. 'remise_absolue' => $order->remise_absolue,
  554. 'source' => $order->source,
  555. 'billed' => $order->billed,
  556. 'note_private' => $order->note_private,
  557. 'note_public' => $order->note_public,
  558. 'cond_reglement_id' => $order->cond_reglement_id,
  559. 'cond_reglement' => $order->cond_reglement,
  560. 'cond_reglement_doc' => $order->cond_reglement_doc,
  561. 'cond_reglement_code' => $order->cond_reglement_code,
  562. 'mode_reglement_id' => $order->mode_reglement_id,
  563. 'mode_reglement' => $order->mode_reglement,
  564. 'mode_reglement_code' => $order->mode_reglement_code,
  565. 'date_livraison' => $order->delivery_date,
  566. 'demand_reason_id' => $order->demand_reason_id,
  567. 'demand_reason_code' => $order->demand_reason_code,
  568. 'lines' => $linesresp
  569. );
  570. }
  571. $i++;
  572. }
  573. $objectresp = array(
  574. 'result'=>array('result_code'=>'OK', 'result_label'=>''),
  575. 'orders'=>$linesorders
  576. );
  577. } else {
  578. $error++;
  579. $errorcode = $db->lasterrno(); $errorlabel = $db->lasterror();
  580. }
  581. }
  582. if ($error) {
  583. $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
  584. }
  585. return $objectresp;
  586. }
  587. /**
  588. * Create order
  589. *
  590. * @param array $authentication Array of authentication information
  591. * @param array $order Order info
  592. * @return array array of new order
  593. */
  594. function createOrder($authentication, $order)
  595. {
  596. global $db, $conf, $langs;
  597. include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
  598. $now = dol_now();
  599. dol_syslog("Function: createOrder login=".$authentication['login']." socid :".$order['socid']);
  600. if ($authentication['entity']) {
  601. $conf->entity = $authentication['entity'];
  602. }
  603. // Init and check authentication
  604. $objectresp = array();
  605. $errorcode = '';
  606. $errorlabel = '';
  607. $error = 0;
  608. $fuser = check_authentication($authentication, $error, $errorcode, $errorlabel);
  609. // Check parameters
  610. if (!$error) {
  611. $newobject = new Commande($db);
  612. $newobject->socid = $order['thirdparty_id'];
  613. $newobject->type = $order['type'];
  614. $newobject->ref_ext = $order['ref_ext'];
  615. $newobject->date = dol_stringtotime($order['date'], 'dayrfc');
  616. $newobject->date_lim_reglement = dol_stringtotime($order['date_due'], 'dayrfc');
  617. $newobject->note_private = $order['note_private'];
  618. $newobject->note_public = $order['note_public'];
  619. $newobject->statut = Commande::STATUS_DRAFT; // We start with status draft
  620. $newobject->billed = $order['billed'];
  621. $newobject->fk_project = $order['project_id'];
  622. $newobject->cond_reglement_id = $order['cond_reglement_id'];
  623. $newobject->demand_reason_id = $order['demand_reason_id'];
  624. $newobject->date_creation = $now;
  625. $elementtype = 'commande';
  626. // Retrieve all extrafield for order
  627. // fetch optionals attributes and labels
  628. $extrafields = new ExtraFields($db);
  629. $extrafields->fetch_name_optionals_label($elementtype, true);
  630. if (isset($extrafields->attributes[$elementtype]['label']) && is_array($extrafields->attributes[$elementtype]['label']) && count($extrafields->attributes[$elementtype]['label'])) {
  631. foreach ($extrafields->attributes[$elementtype]['label'] as $key => $label) {
  632. $key = 'options_'.$key;
  633. $newobject->array_options[$key] = $order[$key];
  634. }
  635. }
  636. // Trick because nusoap does not store data with same structure if there is one or several lines
  637. $arrayoflines = array();
  638. if (isset($order['lines']['line'][0])) {
  639. $arrayoflines = $order['lines']['line'];
  640. } else {
  641. $arrayoflines = $order['lines'];
  642. }
  643. foreach ($arrayoflines as $key => $line) {
  644. // $key can be 'line' or '0','1',...
  645. $newline = new OrderLine($db);
  646. $newline->type = $line['type'];
  647. $newline->desc = $line['desc'];
  648. $newline->fk_product = $line['product_id'];
  649. $newline->tva_tx = $line['vat_rate'];
  650. $newline->qty = $line['qty'];
  651. $newline->price = $line['price'];
  652. $newline->subprice = $line['unitprice'];
  653. $newline->total_ht = $line['total_net'];
  654. $newline->total_tva = $line['total_vat'];
  655. $newline->total_ttc = $line['total'];
  656. $newline->date_start = $line['date_start'];
  657. $newline->date_end = $line['date_end'];
  658. $elementtype = 'commandedet';
  659. // Retrieve all extrafield for lines
  660. // fetch optionals attributes and labels
  661. $extrafields = new ExtraFields($db);
  662. $extrafields->fetch_name_optionals_label($elementtype, true);
  663. if (isset($extrafields->attributes[$elementtype]['label']) && is_array($extrafields->attributes[$elementtype]['label']) && count($extrafields->attributes[$elementtype]['label'])) {
  664. foreach ($extrafields->attributes[$elementtype]['label'] as $tmpkey => $tmplabel) {
  665. $tmpkey = 'options_'.$tmpkey;
  666. $newline->array_options[$tmpkey] = $line[$tmpkey];
  667. }
  668. }
  669. $newobject->lines[] = $newline;
  670. }
  671. $db->begin();
  672. dol_syslog("Webservice server_order:: order creation start", LOG_DEBUG);
  673. $result = $newobject->create($fuser);
  674. dol_syslog('Webservice server_order:: order creation done with $result='.$result, LOG_DEBUG);
  675. if ($result < 0) {
  676. dol_syslog("Webservice server_order:: order creation failed", LOG_ERR);
  677. $error++;
  678. }
  679. if ($order['status'] == 1) { // We want order to have status validated
  680. dol_syslog("Webservice server_order:: order validation start", LOG_DEBUG);
  681. $result = $newobject->valid($fuser);
  682. if ($result < 0) {
  683. dol_syslog("Webservice server_order:: order validation failed", LOG_ERR);
  684. $error++;
  685. }
  686. }
  687. if ($result >= 0) {
  688. dol_syslog("Webservice server_order:: order creation & validation succeeded, commit", LOG_DEBUG);
  689. $db->commit();
  690. $objectresp = array('result'=>array('result_code'=>'OK', 'result_label'=>''), 'id'=>$newobject->id, 'ref'=>$newobject->ref);
  691. } else {
  692. dol_syslog("Webservice server_order:: order creation or validation failed, rollback", LOG_ERR);
  693. $db->rollback();
  694. $error++;
  695. $errorcode = 'KO';
  696. $errorlabel = $newobject->error;
  697. }
  698. }
  699. if ($error) {
  700. $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
  701. }
  702. return $objectresp;
  703. }
  704. /**
  705. * Valid an order
  706. *
  707. * @param array $authentication Array of authentication information
  708. * @param int $id Id of order to validate
  709. * @param int $id_warehouse Id of warehouse to use for stock decrease
  710. * @return array Array result
  711. */
  712. function validOrder($authentication, $id = '', $id_warehouse = 0)
  713. {
  714. global $db, $conf, $langs;
  715. dol_syslog("Function: validOrder login=".$authentication['login']." id=".$id." id_warehouse=".$id_warehouse);
  716. // Init and check authentication
  717. $objectresp = array();
  718. $errorcode = '';
  719. $errorlabel = '';
  720. $error = 0;
  721. if ($authentication['entity']) {
  722. $conf->entity = $authentication['entity'];
  723. }
  724. $fuser = check_authentication($authentication, $error, $errorcode, $errorlabel);
  725. if (!$error) {
  726. $fuser->getrights();
  727. if ($fuser->rights->commande->lire) {
  728. $order = new Commande($db);
  729. $result = $order->fetch($id);
  730. $order->fetch_thirdparty();
  731. $db->begin();
  732. if ($result > 0) {
  733. $result = $order->valid($fuser, $id_warehouse);
  734. if ($result >= 0) {
  735. // Define output language
  736. $outputlangs = $langs;
  737. $order->generateDocument($order->model_pdf, $outputlangs);
  738. } else {
  739. $db->rollback();
  740. $error++;
  741. $errorcode = 'KO';
  742. $errorlabel = $order->error;
  743. }
  744. } else {
  745. $db->rollback();
  746. $error++;
  747. $errorcode = 'KO';
  748. $errorlabel = $order->error;
  749. }
  750. } else {
  751. $db->rollback();
  752. $error++;
  753. $errorcode = 'KO';
  754. $errorlabel = $order->error;
  755. }
  756. }
  757. if ($error) {
  758. $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
  759. } else {
  760. $db->commit();
  761. $objectresp = array('result'=>array('result_code'=>'OK', 'result_label'=>''));
  762. }
  763. return $objectresp;
  764. }
  765. /**
  766. * Update an order
  767. *
  768. * @param array $authentication Array of authentication information
  769. * @param array $order Order info
  770. * @return array Array result
  771. */
  772. function updateOrder($authentication, $order)
  773. {
  774. global $db, $conf, $langs;
  775. dol_syslog("Function: updateOrder login=".$authentication['login']);
  776. if ($authentication['entity']) {
  777. $conf->entity = $authentication['entity'];
  778. }
  779. // Init and check authentication
  780. $objectresp = array();
  781. $errorcode = ''; $errorlabel = '';
  782. $error = 0;
  783. $fuser = check_authentication($authentication, $error, $errorcode, $errorlabel);
  784. // Check parameters
  785. if (empty($order['id']) && empty($order['ref']) && empty($order['ref_ext'])) {
  786. $error++; $errorcode = 'KO'; $errorlabel = "Order id or ref or ref_ext is mandatory.";
  787. }
  788. if (!$error) {
  789. $objectfound = false;
  790. include_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  791. $object = new Commande($db);
  792. $result = $object->fetch($order['id'], (empty($order['id']) ? $order['ref'] : ''), (empty($order['id']) && empty($order['ref']) ? $order['ref_ext'] : ''));
  793. if (!empty($object->id)) {
  794. $objectfound = true;
  795. $db->begin();
  796. if (isset($order['status'])) {
  797. if ($order['status'] == -1) {
  798. $result = $object->cancel($fuser);
  799. }
  800. if ($order['status'] == 1) {
  801. $result = $object->valid($fuser);
  802. if ($result >= 0) {
  803. // Define output language
  804. $outputlangs = $langs;
  805. $object->generateDocument($order->model_pdf, $outputlangs);
  806. }
  807. }
  808. if ($order['status'] == 0) {
  809. $result = $object->set_reopen($fuser);
  810. }
  811. if ($order['status'] == 3) {
  812. $result = $object->cloture($fuser);
  813. }
  814. }
  815. if (isset($order['billed'])) {
  816. if ($order['billed']) {
  817. $result = $object->classifyBilled($fuser);
  818. }
  819. if (!$order['billed']) {
  820. $result = $object->classifyUnBilled($fuser);
  821. }
  822. }
  823. $elementtype = 'commande';
  824. //Retrieve all extrafield for object
  825. // fetch optionals attributes and labels
  826. $extrafields = new ExtraFields($db);
  827. $extrafields->fetch_name_optionals_label($elementtype, true);
  828. if (isset($extrafields->attributes[$elementtype]['label']) && is_array($extrafields->attributes[$elementtype]['label']) && count($extrafields->attributes[$elementtype]['label'])) {
  829. foreach ($extrafields->attributes[$elementtype]['label'] as $key => $label) {
  830. $key = 'options_'.$key;
  831. if (isset($order[$key])) {
  832. $result = $object->setValueFrom($key, $order[$key], 'commande_extrafields');
  833. }
  834. }
  835. }
  836. if ($result <= 0) {
  837. $error++;
  838. }
  839. }
  840. if ((!$error) && ($objectfound)) {
  841. $db->commit();
  842. $objectresp = array(
  843. 'result'=>array('result_code'=>'OK', 'result_label'=>''),
  844. 'id'=>$object->id,
  845. 'ref'=>$object->ref,
  846. 'ref_ext'=>$object->ref_ext
  847. );
  848. } elseif ($objectfound) {
  849. $db->rollback();
  850. $error++;
  851. $errorcode = 'KO';
  852. $errorlabel = $object->error;
  853. } else {
  854. $error++;
  855. $errorcode = 'NOT_FOUND';
  856. $errorlabel = 'Order id='.$order['id'].' ref='.$order['ref'].' ref_ext='.$order['ref_ext'].' cannot be found';
  857. }
  858. }
  859. if ($error) {
  860. $objectresp = array('result'=>array('result_code' => $errorcode, 'result_label' => $errorlabel));
  861. }
  862. return $objectresp;
  863. }
  864. // Return the results.
  865. $server->service(file_get_contents("php://input"));