dolibarr 19.0.3
interface_20_modWorkflow_WorkflowManager.class.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2010 Regis Houssin <regis.houssin@inodbox.com>
3 * Copyright (C) 2011-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2014 Marcos GarcĂ­a <marcosgdf@gmail.com>
5 * Copyright (C) 2022 Ferran Marcet <fmarcet@2byte.es>
6 * Copyright (C) 2023 Alexandre Janniaux <alexandre.janniaux@gmail.com>
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 3 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 <https://www.gnu.org/licenses/>.
20 */
21
28require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
29
30
36{
42 public function __construct($db)
43 {
44 $this->db = $db;
45
46 $this->name = preg_replace('/^Interface/i', '', get_class($this));
47 $this->family = "core";
48 $this->description = "Triggers of this module allows to manage workflows";
49 // 'development', 'experimental', 'dolibarr' or version
50 $this->version = self::VERSION_DOLIBARR;
51 $this->picto = 'technic';
52 }
53
65 public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
66 {
67 if (empty($conf->workflow) || empty($conf->workflow->enabled)) {
68 return 0; // Module not active, we do nothing
69 }
70
71 $ret = 0;
72
73 // Proposals to order
74 if ($action == 'PROPAL_CLOSE_SIGNED') {
75 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
76 if (isModEnabled('commande') && getDolGlobalString('WORKFLOW_PROPAL_AUTOCREATE_ORDER')) {
77 $object->fetchObjectLinked();
78 if (!empty($object->linkedObjectsIds['commande'])) {
79 if (empty($object->context['closedfromonlinesignature'])) {
80 $langs->load("orders");
81 setEventMessages($langs->trans("OrderExists"), null, 'warnings');
82 }
83 return $ret;
84 }
85
86 include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
87 $newobject = new Commande($this->db);
88
89 $newobject->context['createfrompropal'] = 'createfrompropal';
90 $newobject->context['origin'] = $object->element;
91 $newobject->context['origin_id'] = $object->id;
92
93 $ret = $newobject->createFromProposal($object, $user);
94 if ($ret < 0) {
95 $this->setErrorsFromObject($newobject);
96 }
97
98 $object->clearObjectLinkedCache();
99
100 return $ret;
101 }
102 }
103
104 // Order to invoice
105 if ($action == 'ORDER_CLOSE') {
106 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
107 if (isModEnabled('facture') && getDolGlobalString('WORKFLOW_ORDER_AUTOCREATE_INVOICE')) {
108 include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
109 $newobject = new Facture($this->db);
110
111 $newobject->context['createfromorder'] = 'createfromorder';
112 $newobject->context['origin'] = $object->element;
113 $newobject->context['origin_id'] = $object->id;
114
115 $ret = $newobject->createFromOrder($object, $user);
116 if ($ret < 0) {
117 $this->setErrorsFromObject($newobject);
118 } else {
119 if (empty($object->fk_account) && !empty($object->thirdparty->fk_account) && !getDolGlobalInt('BANK_ASK_PAYMENT_BANK_DURING_ORDER')) {
120 $res = $newobject->setBankAccount($object->thirdparty->fk_account, true, $user);
121 if ($ret < 0) {
122 $this->setErrorsFromObject($newobject);
123 }
124 }
125 }
126
127 $object->clearObjectLinkedCache();
128
129 return $ret;
130 }
131 }
132
133 // Order classify billed proposal
134 if ($action == 'ORDER_CLASSIFY_BILLED') {
135 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
136 if (isModEnabled("propal") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL')) {
137 $object->fetchObjectLinked('', 'propal', $object->id, $object->element);
138 if (!empty($object->linkedObjects)) {
139 $totalonlinkedelements = 0;
140 foreach ($object->linkedObjects['propal'] as $element) {
141 if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) {
142 $totalonlinkedelements += $element->total_ht;
143 }
144 }
145 dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
146 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
147 foreach ($object->linkedObjects['propal'] as $element) {
148 $ret = $element->classifyBilled($user);
149 }
150 }
151 }
152 return $ret;
153 }
154 }
155
156 // classify billed order & billed propososal
157 if ($action == 'BILL_VALIDATE') {
158 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
159
160 // First classify billed the order to allow the proposal classify process
161 if (isModEnabled('commande') && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER')) {
162 $object->fetchObjectLinked('', 'commande', $object->id, $object->element);
163 if (!empty($object->linkedObjects)) {
164 $totalonlinkedelements = 0;
165 foreach ($object->linkedObjects['commande'] as $element) {
166 if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) {
167 $totalonlinkedelements += $element->total_ht;
168 }
169 }
170 dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
171 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
172 foreach ($object->linkedObjects['commande'] as $element) {
173 $ret = $element->classifyBilled($user);
174 }
175 }
176 }
177 }
178
179 // Second classify billed the proposal.
180 if (isModEnabled("propal") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL')) {
181 $object->fetchObjectLinked('', 'propal', $object->id, $object->element);
182 if (!empty($object->linkedObjects)) {
183 $totalonlinkedelements = 0;
184 foreach ($object->linkedObjects['propal'] as $element) {
185 if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) {
186 $totalonlinkedelements += $element->total_ht;
187 }
188 }
189 dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
190 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
191 foreach ($object->linkedObjects['propal'] as $element) {
192 $ret = $element->classifyBilled($user);
193 }
194 }
195 }
196 }
197
198 // Set shipment to "Closed" if WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE is set (deprecated, has been replaced with WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE instead))
199 if (isModEnabled("expedition") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE')) {
200 $object->fetchObjectLinked('', 'shipping', $object->id, $object->element);
201 if (!empty($object->linkedObjects)) {
202 $totalonlinkedelements = 0;
203 foreach ($object->linkedObjects['shipping'] as $element) {
204 if ($element->statut == Expedition::STATUS_VALIDATED) {
205 $totalonlinkedelements += $element->total_ht;
206 }
207 }
208 dol_syslog("Amount of linked shipment = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
209 if ($totalonlinkedelements == $object->total_ht) {
210 foreach ($object->linkedObjects['shipping'] as $element) {
211 $ret = $element->setClosed();
212 if ($ret < 0) {
213 return $ret;
214 }
215 }
216 }
217 }
218 }
219
220 if (isModEnabled("expedition") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE')) {
221 $object->fetchObjectLinked('', 'shipping', $object->id, $object->element);
222 if (!empty($object->linkedObjects)) {
223 $totalonlinkedelements = 0;
224 foreach ($object->linkedObjects['shipping'] as $element) {
225 if ($element->statut == Expedition::STATUS_VALIDATED || $element->statut == Expedition::STATUS_CLOSED) {
226 $totalonlinkedelements += $element->total_ht;
227 }
228 }
229 dol_syslog("Amount of linked shipment = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
230 if ($totalonlinkedelements == $object->total_ht) {
231 foreach ($object->linkedObjects['shipping'] as $element) {
232 $ret = $element->setBilled();
233 if ($ret < 0) {
234 return $ret;
235 }
236 }
237 }
238 }
239 }
240
241 return $ret;
242 }
243
244 // classify billed order & billed proposal
245 if ($action == 'BILL_SUPPLIER_VALIDATE') {
246 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
247
248 // Firstly, we set to purchase order to "Billed" if WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER is set.
249 // After we will set proposals
250 if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && getDolGlobalString('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER')) {
251 $object->fetchObjectLinked('', 'order_supplier', $object->id, $object->element);
252 if (!empty($object->linkedObjects)) {
253 $totalonlinkedelements = 0;
254 foreach ($object->linkedObjects['order_supplier'] as $element) {
256 $totalonlinkedelements += $element->total_ht;
257 }
258 }
259 dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
260 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
261 foreach ($object->linkedObjects['order_supplier'] as $element) {
262 $ret = $element->classifyBilled($user);
263 if ($ret < 0) {
264 return $ret;
265 }
266 }
267 }
268 }
269 }
270
271 // Secondly, we set to linked Proposal to "Billed" if WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL is set.
272 if (isModEnabled('supplier_proposal') && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL')) {
273 $object->fetchObjectLinked('', 'supplier_proposal', $object->id, $object->element);
274 if (!empty($object->linkedObjects)) {
275 $totalonlinkedelements = 0;
276 foreach ($object->linkedObjects['supplier_proposal'] as $element) {
277 if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_CLOSE) {
278 $totalonlinkedelements += $element->total_ht;
279 }
280 }
281 dol_syslog("Amount of linked supplier proposals = ".$totalonlinkedelements.", of supplier invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
282 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
283 foreach ($object->linkedObjects['supplier_proposal'] as $element) {
284 $ret = $element->classifyBilled($user);
285 if ($ret < 0) {
286 return $ret;
287 }
288 }
289 }
290 }
291 }
292
293 // Set reception to "Closed" if WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE is set (deprecated, WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE instead))
294 /*
295 if (isModEnabled("reception") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE)) {
296 $object->fetchObjectLinked('', 'reception', $object->id, $object->element);
297 if (!empty($object->linkedObjects)) {
298 $totalonlinkedelements = 0;
299 foreach ($object->linkedObjects['reception'] as $element) {
300 if ($element->statut == Reception::STATUS_VALIDATED || $element->statut == Reception::STATUS_CLOSED) {
301 $totalonlinkedelements += $element->total_ht;
302 }
303 }
304 dol_syslog("Amount of linked reception = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
305 if ($totalonlinkedelements == $object->total_ht) {
306 foreach ($object->linkedObjects['reception'] as $element) {
307 $ret = $element->setClosed();
308 if ($ret < 0) {
309 return $ret;
310 }
311 }
312 }
313 }
314 }
315 */
316
317 // Then set reception to "Billed" if WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE is set
318 if (isModEnabled("reception") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE')) {
319 $object->fetchObjectLinked('', 'reception', $object->id, $object->element);
320 if (!empty($object->linkedObjects)) {
321 $totalonlinkedelements = 0;
322 foreach ($object->linkedObjects['reception'] as $element) {
323 if ($element->statut == Reception::STATUS_VALIDATED || $element->statut == Reception::STATUS_CLOSED) {
324 $totalonlinkedelements += $element->total_ht;
325 }
326 }
327 dol_syslog("Amount of linked reception = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
328 if ($totalonlinkedelements == $object->total_ht) {
329 foreach ($object->linkedObjects['reception'] as $element) {
330 $ret = $element->setBilled();
331 if ($ret < 0) {
332 return $ret;
333 }
334 }
335 }
336 }
337 }
338
339 return $ret;
340 }
341
342 // Invoice classify billed order
343 if ($action == 'BILL_PAYED') {
344 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
345
346 if (isModEnabled('commande') && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER')) {
347 $object->fetchObjectLinked('', 'commande', $object->id, $object->element);
348 if (!empty($object->linkedObjects)) {
349 $totalonlinkedelements = 0;
350 foreach ($object->linkedObjects['commande'] as $element) {
351 if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) {
352 $totalonlinkedelements += $element->total_ht;
353 }
354 }
355 dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht));
356 if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
357 foreach ($object->linkedObjects['commande'] as $element) {
358 $ret = $element->classifyBilled($user);
359 }
360 }
361 }
362 return $ret;
363 }
364 }
365
366 // If we validate or close a shipment
367 if (($action == 'SHIPPING_VALIDATE') || ($action == 'SHIPPING_CLOSED')) {
368 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
369
370 if (isModEnabled('commande') && isModEnabled("expedition") && !empty($conf->workflow->enabled) &&
371 (
372 (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING') && ($action == 'SHIPPING_VALIDATE')) ||
373 (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED') && ($action == 'SHIPPING_CLOSED'))
374 )
375 ) {
376 $qtyshipped = array();
377 $qtyordred = array();
378 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
379
380 // Find all shipments on order origin
381 $order = new Commande($this->db);
382 $ret = $order->fetch($object->origin_id);
383 if ($ret < 0) {
384 $this->setErrorsFromObject($order);
385 return $ret;
386 }
387 $ret = $order->fetchObjectLinked($order->id, 'commande', null, 'shipping');
388 if ($ret < 0) {
389 $this->setErrorsFromObject($order);
390 return $ret;
391 }
392 //Build array of quantity shipped by product for an order
393 if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) {
394 foreach ($order->linkedObjects as $type => $shipping_array) {
395 if ($type != 'shipping' || !is_array($shipping_array) || count($shipping_array) == 0) {
396 continue;
397 }
399 foreach ($shipping_array as $shipping) {
400 if ($shipping->status <= 0 || !is_array($shipping->lines) || count($shipping->lines) == 0) {
401 continue;
402 }
403
404 foreach ($shipping->lines as $shippingline) {
405 $qtyshipped[$shippingline->fk_product] += $shippingline->qty;
406 }
407 }
408 }
409 }
410
411 //Build array of quantity ordered to be shipped
412 if (is_array($order->lines) && count($order->lines) > 0) {
413 foreach ($order->lines as $orderline) {
414 // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors
415 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') && $orderline->product_type > 0) {
416 continue;
417 }
418 $qtyordred[$orderline->fk_product] += $orderline->qty;
419 }
420 }
421 //dol_syslog(var_export($qtyordred,true),LOG_DEBUG);
422 //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG);
423 //Compare array
424 $diff_array = array_diff_assoc($qtyordred, $qtyshipped);
425 if (count($diff_array) == 0) {
426 //No diff => mean everythings is shipped
427 $ret = $order->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin, 'ORDER_CLOSE');
428 if ($ret < 0) {
429 $this->setErrorsFromObject($order);
430 return $ret;
431 }
432 }
433 }
434 }
435
436 // If we validate or close a shipment
437 if (($action == 'RECEPTION_VALIDATE') || ($action == 'RECEPTION_CLOSED')) {
438 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
439
440 if ((isModEnabled("fournisseur") || isModEnabled("supplier_order")) && isModEnabled("reception") && !empty($conf->workflow->enabled) &&
441 (
442 (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION') && ($action == 'RECEPTION_VALIDATE')) ||
443 (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED') && ($action == 'RECEPTION_CLOSED'))
444 )
445 ) {
446 $qtyshipped = array();
447 $qtyordred = array();
448 require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
449
450 // Find all reception on purchase order origin
451 $order = new CommandeFournisseur($this->db);
452 $ret = $order->fetch($object->origin_id);
453 if ($ret < 0) {
454 $this->setErrorsFromObject($order);
455 return $ret;
456 }
457 $ret = $order->fetchObjectLinked($order->id, $order->element, null, 'reception');
458 if ($ret < 0) {
459 $this->setErrorsFromObject($order);
460 return $ret;
461 }
462 //Build array of quantity received by product for a purchase order
463 if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) {
464 foreach ($order->linkedObjects as $type => $shipping_array) {
465 if ($type != 'reception' || !is_array($shipping_array) || count($shipping_array) == 0) {
466 continue;
467 }
468
469 foreach ($shipping_array as $shipping) {
470 if (!is_array($shipping->lines) || count($shipping->lines) == 0) {
471 continue;
472 }
473
474 foreach ($shipping->lines as $shippingline) {
475 $qtyshipped[$shippingline->fk_product] += $shippingline->qty;
476 }
477 }
478 }
479 }
480
481 //Build array of quantity ordered to be received
482 if (is_array($order->lines) && count($order->lines) > 0) {
483 foreach ($order->lines as $orderline) {
484 // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors
485 if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') && $orderline->product_type > 0) {
486 continue;
487 }
488 $qtyordred[$orderline->fk_product] += $orderline->qty;
489 }
490 }
491 //dol_syslog(var_export($qtyordred,true),LOG_DEBUG);
492 //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG);
493 //Compare array
494 $diff_array = array_diff_assoc($qtyordred, $qtyshipped);
495 if (count($diff_array) == 0) {
496 //No diff => mean everythings is received
497 $ret = $order->setStatut(CommandeFournisseur::STATUS_RECEIVED_COMPLETELY, null, null, 'SUPPLIER_ORDER_CLOSE');
498 if ($ret < 0) {
499 $this->setErrorsFromObject($order);
500 return $ret;
501 }
502 }
503 }
504 }
505
506 if ($action == 'TICKET_CREATE') {
507 dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
508 // Auto link ticket to contract
509 if (isModEnabled('contract') && isModEnabled('ticket') && isModEnabled('workflow') && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT') && getDolGlobalString('TICKET_PRODUCT_CATEGORY') && !empty($object->fk_soc)) {
510 $societe = new Societe($this->db);
511 $company_ids = (!getDolGlobalString('WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS')) ? [$object->fk_soc] : $societe->getParentsForCompany($object->fk_soc, [$object->fk_soc]);
512
513 $contrat = new Contrat($this->db);
514 $number_contracts_found = 0;
515 foreach ($company_ids as $company_id) {
516 $contrat->socid = $company_id;
517
518 $list = $contrat->getListOfContracts($option = 'all', $status = [Contrat::STATUS_DRAFT, Contrat::STATUS_VALIDATED], $product_categories = [$conf->global->TICKET_PRODUCT_CATEGORY], $line_status = [ContratLigne::STATUS_INITIAL, ContratLigne::STATUS_OPEN]);
519 if (!is_array($list) || empty($list)) {
520 continue;
521 }
522 $number_contracts_found = count($list);
523 if ($number_contracts_found == 0) {
524 continue;
525 }
526
527 foreach ($list as $linked_contract) {
528 $object->setContract($linked_contract->id);
529 // don't set '$contractid' so it is not used when creating an intervention.
530 }
531
532 if ($number_contracts_found > 1 && !defined('NOLOGIN')) {
533 setEventMessage($langs->trans('TicketManyContractsLinked'), 'warnings');
534 }
535 break;
536 }
537 if ($number_contracts_found == 0 && !defined('NOLOGIN')) {
538 setEventMessage($langs->trans('TicketNoContractFoundToLink'), 'mesgs');
539 }
540 }
541 // Automatically create intervention
542 if (isModEnabled('ficheinter') && isModEnabled('ticket') && isModEnabled('workflow') && getDolGlobalString('WORKFLOW_TICKET_CREATE_INTERVENTION')) {
543 $fichinter = new Fichinter($this->db);
544 $fichinter->socid = (int) $object->fk_soc;
545 $fichinter->fk_project = (int) $object->fk_project;
546 $fichinter->fk_contrat = (int) $object->fk_contract;
547 $fichinter->author = $user->id;
548 $fichinter->model_pdf = getDolGlobalString('FICHEINTER_ADDON_PDF', 'soleil');
549 $fichinter->origin = $object->element;
550 $fichinter->origin_id = $object->id;
551
552 // Extrafields
553 $extrafields = new ExtraFields($this->db);
554 $extrafields->fetch_name_optionals_label($fichinter->table_element);
555 $array_options = $extrafields->getOptionalsFromPost($fichinter->table_element);
556 $fichinter->array_options = $array_options;
557
558 $id = $fichinter->create($user);
559 if ($id <= 0) {
560 setEventMessages($fichinter->error, null, 'errors');
561 }
562 }
563 }
564 return 0;
565 }
566
577 private function shouldClassify($conf, $totalonlinkedelements, $object_total_ht)
578 {
579 // if the configuration allows unmatching amounts, allow classification anyway
580 if (getDolGlobalString('WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS')) {
581 return true;
582 }
583 // if the amount are same, allow classification, else deny
584 return (price2num($totalonlinkedelements, 'MT') == price2num($object_total_ht, 'MT'));
585 }
586}
Class to manage predefined suppliers products.
const STATUS_RECEIVED_PARTIALLY
Received partially.
const STATUS_RECEIVED_COMPLETELY
Received completely.
const STATUS_ORDERSENT
Order sent, shipment on process.
Class to manage customers orders.
const STATUS_SHIPMENTONPROCESS
Shipment on process.
const STATUS_CLOSED
Closed (Sent, billed or not)
const STATUS_VALIDATED
Validated status.
Class to stock current configuration.
Class to manage contracts.
Class that all the triggers must extend.
runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
Function called when a Dolibarrr business event is done.
setErrorsFromObject($object)
setErrorsFromObject
const STATUS_CLOSED
Closed status.
const STATUS_VALIDATED
Validated status.
Class to manage standard extra fields.
Class to manage invoices.
Class to manage interventions.
shouldClassify($conf, $totalonlinkedelements, $object_total_ht)
const STATUS_SIGNED
Signed quote.
const STATUS_BILLED
Billed or processed quote.
Class to manage third parties objects (customers, suppliers, prospects...)
const STATUS_SIGNED
Signed quote.
const STATUS_CLOSE
Billed or closed/processed quote.
Class to manage translations.
Class to manage Dolibarr users.
print $script_file $mode $langs defaultlang(is_numeric($duration_value) ? " delay=". $duration_value :"").(is_numeric($duration_value2) ? " after cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
setEventMessage($mesgs, $style='mesgs', $noduplicate=0)
Set event message in dol_events session object.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:124