27 require_once DOL_DOCUMENT_ROOT.
'/core/triggers/dolibarrtriggers.class.php';
45 $this->
name = preg_replace(
'/^Interface/i',
'', get_class($this));
46 $this->family =
"core";
47 $this->
description =
"Triggers of this module allows to manage workflows";
49 $this->version = self::VERSION_DOLIBARR;
50 $this->picto =
'technic';
66 if (empty($conf->workflow) || empty($conf->workflow->enabled)) {
73 if ($action ==
'PROPAL_CLOSE_SIGNED') {
74 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
75 if (!empty($conf->commande->enabled) && !empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER)) {
76 $object->fetchObjectLinked();
77 if (!empty($object->linkedObjectsIds[
'commande'])) {
81 include_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
84 $newobject->context[
'createfrompropal'] =
'createfrompropal';
85 $newobject->context[
'origin'] = $object->element;
86 $newobject->context[
'origin_id'] = $object->id;
88 $ret = $newobject->createFromProposal($object, $user);
90 $this->error = $newobject->error;
91 $this->errors[] = $newobject->error;
94 $object->clearObjectLinkedCache();
102 if ($action ==
'ORDER_CLOSE') {
103 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
104 if (
isModEnabled(
'facture') && !empty($conf->global->WORKFLOW_ORDER_AUTOCREATE_INVOICE)) {
105 include_once DOL_DOCUMENT_ROOT.
'/compta/facture/class/facture.class.php';
108 $newobject->context[
'createfromorder'] =
'createfromorder';
109 $newobject->context[
'origin'] = $object->element;
110 $newobject->context[
'origin_id'] = $object->id;
112 $ret = $newobject->createFromOrder($object, $user);
114 $this->error = $newobject->error;
115 $this->errors[] = $newobject->error;
118 $object->clearObjectLinkedCache();
125 if ($action ==
'ORDER_CLASSIFY_BILLED') {
126 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
127 if (!empty($conf->propal->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL)) {
128 $object->fetchObjectLinked(
'',
'propal', $object->id, $object->element);
129 if (!empty($object->linkedObjects)) {
130 $totalonlinkedelements = 0;
131 foreach ($object->linkedObjects[
'propal'] as $element) {
133 $totalonlinkedelements += $element->total_ht;
136 dol_syslog(
"Amount of linked proposals = ".$totalonlinkedelements.
", of order = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
137 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
138 foreach ($object->linkedObjects[
'propal'] as $element) {
139 $ret = $element->classifyBilled($user);
148 if ($action ==
'BILL_VALIDATE') {
149 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
152 if (!empty($conf->commande->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER)) {
153 $object->fetchObjectLinked(
'',
'commande', $object->id, $object->element);
154 if (!empty($object->linkedObjects)) {
155 $totalonlinkedelements = 0;
156 foreach ($object->linkedObjects[
'commande'] as $element) {
158 $totalonlinkedelements += $element->total_ht;
161 dol_syslog(
"Amount of linked orders = ".$totalonlinkedelements.
", of invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
162 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
163 foreach ($object->linkedObjects[
'commande'] as $element) {
164 $ret = $element->classifyBilled($user);
171 if (!empty($conf->propal->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL)) {
172 $object->fetchObjectLinked(
'',
'propal', $object->id, $object->element);
173 if (!empty($object->linkedObjects)) {
174 $totalonlinkedelements = 0;
175 foreach ($object->linkedObjects[
'propal'] as $element) {
177 $totalonlinkedelements += $element->total_ht;
180 dol_syslog(
"Amount of linked proposals = ".$totalonlinkedelements.
", of invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
181 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
182 foreach ($object->linkedObjects[
'propal'] as $element) {
183 $ret = $element->classifyBilled($user);
189 if (!empty($conf->expedition->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE)) {
191 $object->fetchObjectLinked(
'',
'shipping', $object->id, $object->element);
193 if (!empty($object->linkedObjects)) {
195 $shipment = array_shift($object->linkedObjects[
'shipping']);
197 $ret = $shipment->setClosed();
205 if ($action ==
'BILL_SUPPLIER_VALIDATE') {
206 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
210 if (((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)) && !empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER)) {
211 $object->fetchObjectLinked(
'',
'order_supplier', $object->id, $object->element);
212 if (!empty($object->linkedObjects)) {
213 $totalonlinkedelements = 0;
214 foreach ($object->linkedObjects[
'order_supplier'] as $element) {
216 $totalonlinkedelements += $element->total_ht;
219 dol_syslog(
"Amount of linked orders = ".$totalonlinkedelements.
", of invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
220 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
221 foreach ($object->linkedObjects[
'order_supplier'] as $element) {
222 $ret = $element->classifyBilled($user);
232 if (!empty($conf->supplier_proposal->enabled) && !empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL)) {
233 $object->fetchObjectLinked(
'',
'supplier_proposal', $object->id, $object->element);
234 if (!empty($object->linkedObjects)) {
235 $totalonlinkedelements = 0;
236 foreach ($object->linkedObjects[
'supplier_proposal'] as $element) {
238 $totalonlinkedelements += $element->total_ht;
241 dol_syslog(
"Amount of linked supplier proposals = ".$totalonlinkedelements.
", of supplier invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
242 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
243 foreach ($object->linkedObjects[
'supplier_proposal'] as $element) {
244 $ret = $element->classifyBilled($user);
254 if (!empty($conf->reception->enabled) && !empty($conf->global->WORKFLOW_BILL_ON_RECEPTION)) {
255 $object->fetchObjectLinked(
'',
'reception', $object->id, $object->element);
256 if (!empty($object->linkedObjects)) {
257 $totalonlinkedelements = 0;
258 foreach ($object->linkedObjects[
'reception'] as $element) {
259 if ($element->statut == Reception::STATUS_VALIDATED) {
260 $totalonlinkedelements += $element->total_ht;
263 dol_syslog(
"Amount of linked reception = ".$totalonlinkedelements.
", of invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
264 if ($totalonlinkedelements == $object->total_ht) {
265 foreach ($object->linkedObjects[
'reception'] as $element) {
266 $ret = $element->setBilled();
279 if ($action ==
'BILL_PAYED') {
280 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
282 if (!empty($conf->commande->enabled) && !empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER)) {
283 $object->fetchObjectLinked(
'',
'commande', $object->id, $object->element);
284 if (!empty($object->linkedObjects)) {
285 $totalonlinkedelements = 0;
286 foreach ($object->linkedObjects[
'commande'] as $element) {
288 $totalonlinkedelements += $element->total_ht;
291 dol_syslog(
"Amount of linked orders = ".$totalonlinkedelements.
", of invoice = ".$object->total_ht.
", egality is ".($totalonlinkedelements == $object->total_ht));
292 if ($this->
shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) {
293 foreach ($object->linkedObjects[
'commande'] as $element) {
294 $ret = $element->classifyBilled($user);
303 if (($action ==
'SHIPPING_VALIDATE') || ($action ==
'SHIPPING_CLOSED')) {
304 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
306 if (!empty($conf->commande->enabled) && !empty($conf->expedition->enabled) && !empty($conf->workflow->enabled) &&
308 (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING) && ($action ==
'SHIPPING_VALIDATE')) ||
309 (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED) && ($action ==
'SHIPPING_CLOSED'))
312 $qtyshipped = array();
313 $qtyordred = array();
314 require_once DOL_DOCUMENT_ROOT.
'/commande/class/commande.class.php';
318 $ret = $order->fetch($object->origin_id);
320 $this->error = $order->error;
321 $this->errors = $order->errors;
324 $ret = $order->fetchObjectLinked($order->id,
'commande',
null,
'shipping');
326 $this->error = $order->error;
327 $this->errors = $order->errors;
331 if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) {
332 foreach ($order->linkedObjects as $type => $shipping_array) {
333 if ($type ==
'shipping' && is_array($shipping_array) && count($shipping_array) > 0) {
334 foreach ($shipping_array as $shipping) {
335 if (is_array($shipping->lines) && count($shipping->lines) > 0) {
336 foreach ($shipping->lines as $shippingline) {
337 $qtyshipped[$shippingline->fk_product] += $shippingline->qty;
346 if (is_array($order->lines) && count($order->lines) > 0) {
347 foreach ($order->lines as $orderline) {
349 if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $orderline->product_type > 0) {
352 $qtyordred[$orderline->fk_product] += $orderline->qty;
358 $diff_array = array_diff_assoc($qtyordred, $qtyshipped);
359 if (count($diff_array) == 0) {
363 $this->error = $order->error;
364 $this->errors = $order->errors;
372 if (($action ==
'RECEPTION_VALIDATE') || ($action ==
'RECEPTION_CLOSED')) {
373 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
375 if ((!empty($conf->fournisseur->enabled) || !empty($conf->supplier_order->enabled)) && !empty($conf->reception->enabled) && !empty($conf->workflow->enabled) &&
377 (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION) && ($action ==
'RECEPTION_VALIDATE')) ||
378 (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED) && ($action ==
'RECEPTION_CLOSED'))
381 $qtyshipped = array();
382 $qtyordred = array();
383 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.commande.class.php';
387 $ret = $order->fetch($object->origin_id);
389 $this->error = $order->error;
390 $this->errors = $order->errors;
393 $ret = $order->fetchObjectLinked($order->id,
'supplier_order',
null,
'reception');
395 $this->error = $order->error;
396 $this->errors = $order->errors;
400 if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) {
401 foreach ($order->linkedObjects as $type => $shipping_array) {
402 if ($type ==
'reception' && is_array($shipping_array) && count($shipping_array) > 0) {
403 foreach ($shipping_array as $shipping) {
404 if (is_array($shipping->lines) && count($shipping->lines) > 0) {
405 foreach ($shipping->lines as $shippingline) {
406 $qtyshipped[$shippingline->fk_product] += $shippingline->qty;
415 if (is_array($order->lines) && count($order->lines) > 0) {
416 foreach ($order->lines as $orderline) {
418 if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $orderline->product_type > 0) {
421 $qtyordred[$orderline->fk_product] += $orderline->qty;
427 $diff_array = array_diff_assoc($qtyordred, $qtyshipped);
428 if (count($diff_array) == 0) {
432 $this->error = $order->error;
433 $this->errors = $order->errors;
440 if ($action ==
'TICKET_CREATE') {
441 dol_syslog(
"Trigger '".$this->
name.
"' for action '$action' launched by ".__FILE__.
". id=".$object->id);
443 if (!empty($conf->contract->enabled) && !empty($conf->ticket->enabled) && !empty($conf->ficheinter->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_TICKET_LINK_CONTRACT) && !empty($conf->global->TICKET_PRODUCT_CATEGORY) && !empty($object->fk_soc)) {
445 $company_ids = (empty($conf->global->WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS)) ? [$object->fk_soc] : $societe->getParentsForCompany($object->fk_soc, [$object->fk_soc]);
448 $number_contracts_found = 0;
449 foreach ($company_ids as $company_id) {
450 $contrat->socid = $company_id;
451 $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]);
452 if (is_array($list) && !empty($list)) {
453 $number_contracts_found = count($list);
454 if ($number_contracts_found == 1) {
455 foreach ($list as $linked_contract) {
456 $object->setContract($linked_contract->id);
459 } elseif ($number_contracts_found > 1) {
460 foreach ($list as $linked_contract) {
461 $object->setContract($linked_contract->id);
464 if (empty(NOLOGIN))
setEventMessage($langs->trans(
'TicketManyContractsLinked'),
'warnings');
469 if ($number_contracts_found == 0) {
470 if (empty(NOLOGIN))
setEventMessage($langs->trans(
'TicketNoContractFoundToLink'),
'mesgs');
474 if (!empty($conf->ficheinter->enabled) && !empty($conf->ticket->enabled) && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_TICKET_CREATE_INTERVENTION)) {
476 $fichinter->socid = (int) $object->fk_soc;
477 $fichinter->fk_project = $projectid;
478 $fichinter->fk_contrat = (
int) $object->fk_contract;
479 $fichinter->author = $user->id;
480 $fichinter->model_pdf = (!empty($conf->global->FICHEINTER_ADDON_PDF)) ? $conf->global->FICHEINTER_ADDON_PDF :
'soleil';
481 $fichinter->origin = $object->element;
482 $fichinter->origin_id = $object->id;
486 $extrafields->fetch_name_optionals_label($fichinter->table_element);
487 $array_options = $extrafields->getOptionalsFromPost($fichinter->table_element);
488 $fichinter->array_options = $array_options;
490 $id = $fichinter->create($user);
512 if (!empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) {
516 return (
price2num($totalonlinkedelements,
'MT') ==
price2num($object_total_ht,
'MT'));