| Total Complexity | 210 |
| Total Lines | 593 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like InterfaceWorkflowManager often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use InterfaceWorkflowManager, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 43 | class InterfaceWorkflowManager extends DolibarrTriggers |
||
| 44 | { |
||
| 45 | /** |
||
| 46 | * Constructor |
||
| 47 | * |
||
| 48 | * @param DoliDB $db Database handler |
||
| 49 | */ |
||
| 50 | public function __construct($db) |
||
| 51 | { |
||
| 52 | $this->db = $db; |
||
| 53 | |||
| 54 | $this->name = preg_replace('/^Interface/i', '', get_class($this)); |
||
| 55 | $this->family = "core"; |
||
| 56 | $this->description = "Triggers of this module allows to manage workflows"; |
||
| 57 | $this->version = self::VERSIONS['prod']; |
||
| 58 | $this->picto = 'technic'; |
||
| 59 | } |
||
| 60 | |||
| 61 | /** |
||
| 62 | * Function called when a Dolibarr business event is done. |
||
| 63 | * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared) |
||
| 64 | * |
||
| 65 | * @param string $action Event action code |
||
| 66 | * @param CommonObject $object Object |
||
| 67 | * @param User $user Object user |
||
| 68 | * @param Translate $langs Object langs |
||
| 69 | * @param Conf $conf Object conf |
||
| 70 | * @return int Return integer <0 if KO, 0 if no triggered ran, >0 if OK |
||
| 71 | */ |
||
| 72 | public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf) |
||
| 73 | { |
||
| 74 | if (empty($conf->workflow) || empty($conf->workflow->enabled)) { |
||
| 75 | return 0; // Module not active, we do nothing |
||
| 76 | } |
||
| 77 | |||
| 78 | $ret = 0; |
||
| 79 | |||
| 80 | // Proposals to order |
||
| 81 | if ($action == 'PROPAL_CLOSE_SIGNED') { |
||
| 82 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 83 | if (isModEnabled('order') && getDolGlobalString('WORKFLOW_PROPAL_AUTOCREATE_ORDER')) { |
||
| 84 | $object->fetchObjectLinked(); |
||
| 85 | if (!empty($object->linkedObjectsIds['commande'])) { |
||
| 86 | if (empty($object->context['closedfromonlinesignature'])) { |
||
| 87 | $langs->load("orders"); |
||
| 88 | setEventMessages($langs->trans("OrderExists"), null, 'warnings'); |
||
| 89 | } |
||
| 90 | return $ret; |
||
| 91 | } |
||
| 92 | |||
| 93 | $newobject = new Commande($this->db); |
||
| 94 | |||
| 95 | $newobject->context['createfrompropal'] = 'createfrompropal'; |
||
| 96 | $newobject->context['origin'] = $object->element; |
||
| 97 | $newobject->context['origin_id'] = $object->id; |
||
| 98 | |||
| 99 | $ret = $newobject->createFromProposal($object, $user); |
||
| 100 | if ($ret < 0) { |
||
| 101 | $this->setErrorsFromObject($newobject); |
||
| 102 | } |
||
| 103 | |||
| 104 | $object->clearObjectLinkedCache(); |
||
| 105 | |||
| 106 | return (int)$ret; |
||
| 107 | } |
||
| 108 | } |
||
| 109 | |||
| 110 | // Order to invoice |
||
| 111 | if ($action == 'ORDER_CLOSE') { |
||
| 112 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 113 | if (isModEnabled('invoice') && getDolGlobalString('WORKFLOW_ORDER_AUTOCREATE_INVOICE')) { |
||
| 114 | $newobject = new Facture($this->db); |
||
| 115 | |||
| 116 | $newobject->context['createfromorder'] = 'createfromorder'; |
||
| 117 | $newobject->context['origin'] = $object->element; |
||
| 118 | $newobject->context['origin_id'] = $object->id; |
||
| 119 | |||
| 120 | $ret = $newobject->createFromOrder($object, $user); |
||
| 121 | if ($ret < 0) { |
||
| 122 | $this->setErrorsFromObject($newobject); |
||
| 123 | } else { |
||
| 124 | if (empty($object->fk_account) && !empty($object->thirdparty->fk_account) && !getDolGlobalInt('BANK_ASK_PAYMENT_BANK_DURING_ORDER')) { |
||
| 125 | $res = $newobject->setBankAccount($object->thirdparty->fk_account, true, $user); |
||
| 126 | if ($ret < 0) { |
||
| 127 | $this->setErrorsFromObject($newobject); |
||
| 128 | } |
||
| 129 | } |
||
| 130 | } |
||
| 131 | |||
| 132 | $object->clearObjectLinkedCache(); |
||
| 133 | |||
| 134 | return $ret; |
||
| 135 | } |
||
| 136 | } |
||
| 137 | |||
| 138 | // Order classify billed proposal |
||
| 139 | if ($action == 'ORDER_CLASSIFY_BILLED') { |
||
| 140 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 141 | if (isModEnabled("propal") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL')) { |
||
| 142 | $object->fetchObjectLinked('', 'propal', $object->id, $object->element); |
||
| 143 | if (!empty($object->linkedObjects)) { |
||
| 144 | $totalonlinkedelements = 0; |
||
| 145 | foreach ($object->linkedObjects['propal'] as $element) { |
||
| 146 | if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) { |
||
| 147 | $totalonlinkedelements += $element->total_ht; |
||
| 148 | } |
||
| 149 | } |
||
| 150 | dol_syslog("Amount of linked proposals = " . $totalonlinkedelements . ", of order = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 151 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 152 | foreach ($object->linkedObjects['propal'] as $element) { |
||
| 153 | $ret = $element->classifyBilled($user); |
||
| 154 | } |
||
| 155 | } |
||
| 156 | } |
||
| 157 | return $ret; |
||
| 158 | } |
||
| 159 | } |
||
| 160 | |||
| 161 | // classify billed order & billed propososal |
||
| 162 | if ($action == 'BILL_VALIDATE') { |
||
| 163 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 164 | |||
| 165 | // First classify billed the order to allow the proposal classify process |
||
| 166 | if (isModEnabled('order') && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER')) { |
||
| 167 | $object->fetchObjectLinked('', 'commande', $object->id, $object->element); |
||
| 168 | if (!empty($object->linkedObjects)) { |
||
| 169 | $totalonlinkedelements = 0; |
||
| 170 | foreach ($object->linkedObjects['commande'] as $element) { |
||
| 171 | if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) { |
||
| 172 | $totalonlinkedelements += $element->total_ht; |
||
| 173 | } |
||
| 174 | } |
||
| 175 | dol_syslog("Amount of linked orders = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 176 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 177 | foreach ($object->linkedObjects['commande'] as $element) { |
||
| 178 | $ret = $element->classifyBilled($user); |
||
| 179 | } |
||
| 180 | } |
||
| 181 | } |
||
| 182 | } |
||
| 183 | |||
| 184 | // Second classify billed the proposal. |
||
| 185 | if (isModEnabled("propal") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL')) { |
||
| 186 | $object->fetchObjectLinked('', 'propal', $object->id, $object->element); |
||
| 187 | if (!empty($object->linkedObjects)) { |
||
| 188 | $totalonlinkedelements = 0; |
||
| 189 | foreach ($object->linkedObjects['propal'] as $element) { |
||
| 190 | if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) { |
||
| 191 | $totalonlinkedelements += $element->total_ht; |
||
| 192 | } |
||
| 193 | } |
||
| 194 | dol_syslog("Amount of linked proposals = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 195 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 196 | foreach ($object->linkedObjects['propal'] as $element) { |
||
| 197 | $ret = $element->classifyBilled($user); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | } |
||
| 201 | } |
||
| 202 | |||
| 203 | // Set shipment to "Closed" if WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE is set (deprecated, has been replaced with WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE instead)) |
||
| 204 | if (isModEnabled("shipping") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE')) { |
||
| 205 | $object->fetchObjectLinked('', 'shipping', $object->id, $object->element); |
||
| 206 | if (!empty($object->linkedObjects)) { |
||
| 207 | $totalonlinkedelements = 0; |
||
| 208 | foreach ($object->linkedObjects['shipping'] as $element) { |
||
| 209 | if ($element->statut == Expedition::STATUS_VALIDATED) { |
||
| 210 | $totalonlinkedelements += $element->total_ht; |
||
| 211 | } |
||
| 212 | } |
||
| 213 | dol_syslog("Amount of linked shipment = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht), LOG_DEBUG); |
||
| 214 | if ($totalonlinkedelements == $object->total_ht) { |
||
| 215 | foreach ($object->linkedObjects['shipping'] as $element) { |
||
| 216 | $ret = $element->setClosed(); |
||
| 217 | if ($ret < 0) { |
||
| 218 | return (int)$ret; |
||
| 219 | } |
||
| 220 | } |
||
| 221 | } |
||
| 222 | } |
||
| 223 | } |
||
| 224 | |||
| 225 | if (isModEnabled("shipping") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE')) { |
||
| 226 | $object->fetchObjectLinked('', 'shipping', $object->id, $object->element); |
||
| 227 | if (!empty($object->linkedObjects)) { |
||
| 228 | $totalonlinkedelements = 0; |
||
| 229 | foreach ($object->linkedObjects['shipping'] as $element) { |
||
| 230 | if ($element->statut == Expedition::STATUS_VALIDATED || $element->statut == Expedition::STATUS_CLOSED) { |
||
| 231 | $totalonlinkedelements += $element->total_ht; |
||
| 232 | } |
||
| 233 | } |
||
| 234 | dol_syslog("Amount of linked shipment = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht), LOG_DEBUG); |
||
| 235 | if ($totalonlinkedelements == $object->total_ht) { |
||
| 236 | foreach ($object->linkedObjects['shipping'] as $element) { |
||
| 237 | $ret = $element->setBilled(); |
||
| 238 | if ($ret < 0) { |
||
| 239 | return (int)$ret; |
||
| 240 | } |
||
| 241 | } |
||
| 242 | } |
||
| 243 | } |
||
| 244 | } |
||
| 245 | |||
| 246 | // First classify billed the order to allow the proposal classify process |
||
| 247 | if (isModEnabled('order') && isModEnabled('workflow') && getDolGlobalString('WORKFLOW_SUM_INVOICES_AMOUNT_CLASSIFY_BILLED_ORDER')) { |
||
| 248 | $object->fetchObjectLinked('', 'commande', $object->id, $object->element); |
||
| 249 | if (!empty($object->linkedObjects['commande']) && count($object->linkedObjects['commande']) == 1) { // If the invoice has only 1 source order |
||
| 250 | $orderLinked = reset($object->linkedObjects['commande']); |
||
| 251 | $orderLinked->fetchObjectLinked($orderLinked->id, '', $orderLinked->element); |
||
| 252 | if (count($orderLinked->linkedObjects['facture']) >= 1) { |
||
| 253 | $totalHTInvoices = 0; |
||
| 254 | $areAllInvoicesValidated = true; |
||
| 255 | foreach ($orderLinked->linkedObjects['facture'] as $key => $invoice) { |
||
| 256 | if ($invoice->statut == Facture::STATUS_VALIDATED || $object->id == $invoice->id) { |
||
| 257 | $totalHTInvoices += (float)$invoice->total_ht; |
||
| 258 | } else { |
||
| 259 | $areAllInvoicesValidated = false; |
||
| 260 | break; |
||
| 261 | } |
||
| 262 | } |
||
| 263 | if ($areAllInvoicesValidated) { |
||
| 264 | $isSameTotal = (price2num($totalHTInvoices, 'MT') == price2num($orderLinked->total_ht, 'MT')); |
||
| 265 | dol_syslog("Amount of linked invoices = " . $totalHTInvoices . ", of order = " . $orderLinked->total_ht . ", isSameTotal = " . (string)$isSameTotal, LOG_DEBUG); |
||
| 266 | if ($isSameTotal) { |
||
| 267 | $ret = $orderLinked->classifyBilled($user); |
||
| 268 | if ($ret < 0) { |
||
| 269 | return $ret; |
||
| 270 | } |
||
| 271 | } |
||
| 272 | } |
||
| 273 | } |
||
| 274 | } |
||
| 275 | } |
||
| 276 | return $ret; |
||
| 277 | } |
||
| 278 | |||
| 279 | // classify billed order & billed proposal |
||
| 280 | if ($action == 'BILL_SUPPLIER_VALIDATE') { |
||
| 281 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 282 | |||
| 283 | // Firstly, we set to purchase order to "Billed" if WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER is set. |
||
| 284 | // After we will set proposals |
||
| 285 | if ((isModEnabled("supplier_order") || isModEnabled("supplier_invoice")) && getDolGlobalString('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER')) { |
||
| 286 | $object->fetchObjectLinked('', 'order_supplier', $object->id, $object->element); |
||
| 287 | if (!empty($object->linkedObjects)) { |
||
| 288 | $totalonlinkedelements = 0; |
||
| 289 | foreach ($object->linkedObjects['order_supplier'] as $element) { |
||
| 290 | if ($element->statut == CommandeFournisseur::STATUS_ACCEPTED || $element->statut == CommandeFournisseur::STATUS_ORDERSENT || $element->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY || $element->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) { |
||
| 291 | $totalonlinkedelements += $element->total_ht; |
||
| 292 | } |
||
| 293 | } |
||
| 294 | dol_syslog("Amount of linked orders = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 295 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 296 | foreach ($object->linkedObjects['order_supplier'] as $element) { |
||
| 297 | $ret = $element->classifyBilled($user); |
||
| 298 | if ($ret < 0) { |
||
| 299 | return $ret; |
||
| 300 | } |
||
| 301 | } |
||
| 302 | } |
||
| 303 | } |
||
| 304 | } |
||
| 305 | |||
| 306 | // Secondly, we set to linked Proposal to "Billed" if WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL is set. |
||
| 307 | if (isModEnabled('supplier_proposal') && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL')) { |
||
| 308 | $object->fetchObjectLinked('', 'supplier_proposal', $object->id, $object->element); |
||
| 309 | if (!empty($object->linkedObjects)) { |
||
| 310 | $totalonlinkedelements = 0; |
||
| 311 | foreach ($object->linkedObjects['supplier_proposal'] as $element) { |
||
| 312 | if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_CLOSE) { |
||
| 313 | $totalonlinkedelements += $element->total_ht; |
||
| 314 | } |
||
| 315 | } |
||
| 316 | dol_syslog("Amount of linked supplier proposals = " . $totalonlinkedelements . ", of supplier invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 317 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 318 | foreach ($object->linkedObjects['supplier_proposal'] as $element) { |
||
| 319 | $ret = $element->classifyBilled($user); |
||
| 320 | if ($ret < 0) { |
||
| 321 | return $ret; |
||
| 322 | } |
||
| 323 | } |
||
| 324 | } |
||
| 325 | } |
||
| 326 | } |
||
| 327 | |||
| 328 | // Set reception to "Closed" if WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE is set (deprecated, WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE instead)) |
||
| 329 | /* |
||
| 330 | if (isModEnabled("reception") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE)) { |
||
| 331 | $object->fetchObjectLinked('', 'reception', $object->id, $object->element); |
||
| 332 | if (!empty($object->linkedObjects)) { |
||
| 333 | $totalonlinkedelements = 0; |
||
| 334 | foreach ($object->linkedObjects['reception'] as $element) { |
||
| 335 | if ($element->statut == Reception::STATUS_VALIDATED || $element->statut == Reception::STATUS_CLOSED) { |
||
| 336 | $totalonlinkedelements += $element->total_ht; |
||
| 337 | } |
||
| 338 | } |
||
| 339 | dol_syslog("Amount of linked reception = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); |
||
| 340 | if ($totalonlinkedelements == $object->total_ht) { |
||
| 341 | foreach ($object->linkedObjects['reception'] as $element) { |
||
| 342 | $ret = $element->setClosed(); |
||
| 343 | if ($ret < 0) { |
||
| 344 | return $ret; |
||
| 345 | } |
||
| 346 | } |
||
| 347 | } |
||
| 348 | } |
||
| 349 | } |
||
| 350 | */ |
||
| 351 | |||
| 352 | // Then set reception to "Billed" if WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE is set |
||
| 353 | if (isModEnabled("reception") && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE')) { |
||
| 354 | $object->fetchObjectLinked('', 'reception', $object->id, $object->element); |
||
| 355 | if (!empty($object->linkedObjects)) { |
||
| 356 | $totalonlinkedelements = 0; |
||
| 357 | foreach ($object->linkedObjects['reception'] as $element) { |
||
| 358 | if ($element->statut == Reception::STATUS_VALIDATED || $element->statut == Reception::STATUS_CLOSED) { |
||
| 359 | $totalonlinkedelements += $element->total_ht; |
||
| 360 | } |
||
| 361 | } |
||
| 362 | dol_syslog("Amount of linked reception = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht), LOG_DEBUG); |
||
| 363 | if ($totalonlinkedelements == $object->total_ht) { |
||
| 364 | foreach ($object->linkedObjects['reception'] as $element) { |
||
| 365 | $ret = $element->setBilled(); |
||
| 366 | if ($ret < 0) { |
||
| 367 | return $ret; |
||
| 368 | } |
||
| 369 | } |
||
| 370 | } |
||
| 371 | } |
||
| 372 | } |
||
| 373 | |||
| 374 | return $ret; |
||
| 375 | } |
||
| 376 | |||
| 377 | // Invoice classify billed order |
||
| 378 | if ($action == 'BILL_PAYED') { |
||
| 379 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 380 | |||
| 381 | if (isModEnabled('order') && getDolGlobalString('WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER')) { |
||
| 382 | $object->fetchObjectLinked('', 'commande', $object->id, $object->element); |
||
| 383 | if (!empty($object->linkedObjects)) { |
||
| 384 | $totalonlinkedelements = 0; |
||
| 385 | foreach ($object->linkedObjects['commande'] as $element) { |
||
| 386 | if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) { |
||
| 387 | $totalonlinkedelements += $element->total_ht; |
||
| 388 | } |
||
| 389 | } |
||
| 390 | dol_syslog("Amount of linked orders = " . $totalonlinkedelements . ", of invoice = " . $object->total_ht . ", egality is " . json_encode($totalonlinkedelements == $object->total_ht)); |
||
| 391 | if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht)) { |
||
| 392 | foreach ($object->linkedObjects['commande'] as $element) { |
||
| 393 | $ret = $element->classifyBilled($user); |
||
| 394 | } |
||
| 395 | } |
||
| 396 | } |
||
| 397 | return $ret; |
||
| 398 | } |
||
| 399 | } |
||
| 400 | |||
| 401 | // If we validate or close a shipment |
||
| 402 | if (($action == 'SHIPPING_VALIDATE') || ($action == 'SHIPPING_CLOSED')) { |
||
| 403 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 404 | |||
| 405 | if ( |
||
| 406 | isModEnabled('order') && isModEnabled("shipping") && !empty($conf->workflow->enabled) && |
||
| 407 | ( |
||
| 408 | (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING') && ($action == 'SHIPPING_VALIDATE')) || |
||
| 409 | (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED') && ($action == 'SHIPPING_CLOSED')) |
||
| 410 | ) |
||
| 411 | ) { |
||
| 412 | $qtyshipped = array(); |
||
| 413 | $qtyordred = array(); |
||
| 414 | |||
| 415 | // The original sale order is id in $object->origin_id |
||
| 416 | // Find all shipments on sale order origin |
||
| 417 | |||
| 418 | if (in_array($object->origin, array('order', 'commande')) && $object->origin_id > 0) { |
||
|
|
|||
| 419 | $order = new Commande($this->db); |
||
| 420 | $ret = $order->fetch($object->origin_id); |
||
| 421 | if ($ret < 0) { |
||
| 422 | $this->setErrorsFromObject($order); |
||
| 423 | return $ret; |
||
| 424 | } |
||
| 425 | $ret = $order->fetchObjectLinked($order->id, 'commande', null, 'shipping'); |
||
| 426 | if ($ret < 0) { |
||
| 427 | $this->setErrorsFromObject($order); |
||
| 428 | return $ret; |
||
| 429 | } |
||
| 430 | //Build array of quantity shipped by product for an order |
||
| 431 | if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) { |
||
| 432 | foreach ($order->linkedObjects as $type => $shipping_array) { |
||
| 433 | if ($type != 'shipping' || !is_array($shipping_array) || count($shipping_array) == 0) { |
||
| 434 | continue; |
||
| 435 | } |
||
| 436 | /** @var Expedition[] $shipping_array */ |
||
| 437 | foreach ($shipping_array as $shipping) { |
||
| 438 | if ($shipping->status <= 0 || !is_array($shipping->lines) || count($shipping->lines) == 0) { |
||
| 439 | continue; |
||
| 440 | } |
||
| 441 | |||
| 442 | foreach ($shipping->lines as $shippingline) { |
||
| 443 | if (isset($qtyshipped[$shippingline->fk_product])) { |
||
| 444 | $qtyshipped[$shippingline->fk_product] += $shippingline->qty; |
||
| 445 | } else { |
||
| 446 | $qtyshipped[$shippingline->fk_product] = $shippingline->qty; |
||
| 447 | } |
||
| 448 | } |
||
| 449 | } |
||
| 450 | } |
||
| 451 | } |
||
| 452 | |||
| 453 | //Build array of quantity ordered to be shipped |
||
| 454 | if (is_array($order->lines) && count($order->lines) > 0) { |
||
| 455 | foreach ($order->lines as $orderline) { |
||
| 456 | // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors |
||
| 457 | if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') && $orderline->product_type > 0) { |
||
| 458 | continue; |
||
| 459 | } |
||
| 460 | if (isset($qtyordred[$shippingline->fk_product])) { |
||
| 461 | $qtyordred[$orderline->fk_product] += $orderline->qty; |
||
| 462 | } else { |
||
| 463 | $qtyordred[$orderline->fk_product] = $orderline->qty; |
||
| 464 | } |
||
| 465 | } |
||
| 466 | } |
||
| 467 | //dol_syslog(var_export($qtyordred,true),LOG_DEBUG); |
||
| 468 | //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG); |
||
| 469 | //Compare array |
||
| 470 | $diff_array = array_diff_assoc($qtyordred, $qtyshipped); |
||
| 471 | if (count($diff_array) == 0) { |
||
| 472 | //No diff => mean everything is shipped |
||
| 473 | $ret = $order->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin, 'ORDER_CLOSE'); |
||
| 474 | if ($ret < 0) { |
||
| 475 | $this->setErrorsFromObject($order); |
||
| 476 | return $ret; |
||
| 477 | } |
||
| 478 | } |
||
| 479 | } |
||
| 480 | } |
||
| 481 | } |
||
| 482 | |||
| 483 | // If we validate or close a shipment |
||
| 484 | if (($action == 'RECEPTION_VALIDATE') || ($action == 'RECEPTION_CLOSED')) { |
||
| 485 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 486 | |||
| 487 | if ( |
||
| 488 | (isModEnabled("fournisseur") || isModEnabled("supplier_order")) && isModEnabled("reception") && isModEnabled('workflow') && |
||
| 489 | ( |
||
| 490 | (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION') && ($action == 'RECEPTION_VALIDATE')) || |
||
| 491 | (getDolGlobalString('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED') && ($action == 'RECEPTION_CLOSED')) |
||
| 492 | ) |
||
| 493 | ) { |
||
| 494 | $qtyshipped = array(); |
||
| 495 | $qtyordred = array(); |
||
| 496 | |||
| 497 | // The original purchase order is id in $object->origin_id |
||
| 498 | // Find all reception on purchase order origin |
||
| 499 | |||
| 500 | if (in_array($object->origin, array('order_supplier', 'supplier_order', 'commandeFournisseur')) && $object->origin_id > 0) { |
||
| 501 | $order = new CommandeFournisseur($this->db); |
||
| 502 | $ret = $order->fetch($object->origin_id); |
||
| 503 | if ($ret < 0) { |
||
| 504 | $this->setErrorsFromObject($order); |
||
| 505 | return $ret; |
||
| 506 | } |
||
| 507 | $ret = $order->fetchObjectLinked($order->id, $order->element, null, 'reception'); |
||
| 508 | if ($ret < 0) { |
||
| 509 | $this->setErrorsFromObject($order); |
||
| 510 | return $ret; |
||
| 511 | } |
||
| 512 | |||
| 513 | // Build array of quantity received by product for a purchase order |
||
| 514 | if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) { |
||
| 515 | foreach ($order->linkedObjects as $type => $shipping_array) { |
||
| 516 | if ($type != 'reception' || !is_array($shipping_array) || count($shipping_array) == 0) { |
||
| 517 | continue; |
||
| 518 | } |
||
| 519 | |||
| 520 | foreach ($shipping_array as $shipping) { |
||
| 521 | if (!is_array($shipping->lines) || count($shipping->lines) == 0) { |
||
| 522 | continue; |
||
| 523 | } |
||
| 524 | |||
| 525 | foreach ($shipping->lines as $shippingline) { |
||
| 526 | $qtyshipped[$shippingline->fk_product] += $shippingline->qty; |
||
| 527 | } |
||
| 528 | } |
||
| 529 | } |
||
| 530 | } |
||
| 531 | |||
| 532 | // Build array of quantity ordered to be received |
||
| 533 | if (is_array($order->lines) && count($order->lines) > 0) { |
||
| 534 | foreach ($order->lines as $orderline) { |
||
| 535 | // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors |
||
| 536 | if (!getDolGlobalString('STOCK_SUPPORTS_SERVICES') && $orderline->product_type > 0) { |
||
| 537 | continue; |
||
| 538 | } |
||
| 539 | $qtyordred[$orderline->fk_product] += $orderline->qty; |
||
| 540 | } |
||
| 541 | } |
||
| 542 | //dol_syslog(var_export($qtyordred,true),LOG_DEBUG); |
||
| 543 | //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG); |
||
| 544 | //Compare array |
||
| 545 | $diff_array = array_diff_assoc($qtyordred, $qtyshipped); |
||
| 546 | if (count($diff_array) == 0) { |
||
| 547 | //No diff => mean everything is received |
||
| 548 | $ret = $order->setStatut(CommandeFournisseur::STATUS_RECEIVED_COMPLETELY, null, null, 'SUPPLIER_ORDER_CLOSE'); |
||
| 549 | if ($ret < 0) { |
||
| 550 | $this->setErrorsFromObject($order); |
||
| 551 | return $ret; |
||
| 552 | } |
||
| 553 | } |
||
| 554 | } |
||
| 555 | } |
||
| 556 | } |
||
| 557 | |||
| 558 | if ($action == 'TICKET_CREATE') { |
||
| 559 | dol_syslog("Trigger '" . $this->name . "' for action '$action' launched by " . __FILE__ . ". id=" . $object->id); |
||
| 560 | // Auto link ticket to contract |
||
| 561 | if (isModEnabled('contract') && isModEnabled('ticket') && isModEnabled('workflow') && getDolGlobalString('WORKFLOW_TICKET_LINK_CONTRACT') && getDolGlobalString('TICKET_PRODUCT_CATEGORY') && !empty($object->fk_soc)) { |
||
| 562 | $societe = new Societe($this->db); |
||
| 563 | $company_ids = (!getDolGlobalString('WORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS')) ? [$object->fk_soc] : $societe->getParentsForCompany($object->fk_soc, [$object->fk_soc]); |
||
| 564 | |||
| 565 | $contrat = new Contrat($this->db); |
||
| 566 | $number_contracts_found = 0; |
||
| 567 | foreach ($company_ids as $company_id) { |
||
| 568 | $contrat->socid = $company_id; |
||
| 569 | $list = $contrat->getListOfContracts('all', array(Contrat::STATUS_DRAFT, Contrat::STATUS_VALIDATED), array(getDolGlobalString('TICKET_PRODUCT_CATEGORY')), array(ContratLigne::STATUS_INITIAL, ContratLigne::STATUS_OPEN)); |
||
| 570 | if (!is_array($list) || empty($list)) { |
||
| 571 | continue; |
||
| 572 | } |
||
| 573 | $number_contracts_found = count($list); |
||
| 574 | if ($number_contracts_found == 0) { |
||
| 575 | continue; |
||
| 576 | } |
||
| 577 | |||
| 578 | foreach ($list as $linked_contract) { |
||
| 579 | $object->setContract($linked_contract->id); |
||
| 580 | // don't set '$contractid' so it is not used when creating an intervention. |
||
| 581 | } |
||
| 582 | |||
| 583 | if ($number_contracts_found > 1 && !defined('NOLOGIN')) { |
||
| 584 | setEventMessages($langs->trans('TicketManyContractsLinked'), null, 'warnings'); |
||
| 585 | } |
||
| 586 | break; |
||
| 587 | } |
||
| 588 | if ($number_contracts_found == 0 && !defined('NOLOGIN')) { |
||
| 589 | setEventMessages($langs->trans('TicketNoContractFoundToLink'), null, 'mesgs'); |
||
| 590 | } |
||
| 591 | } |
||
| 592 | // Automatically create intervention |
||
| 593 | if (isModEnabled('intervention') && isModEnabled('ticket') && !empty($conf->workflow->enabled) && getDolGlobalString('WORKFLOW_TICKET_CREATE_INTERVENTION')) { |
||
| 594 | $fichinter = new Fichinter($this->db); |
||
| 595 | $fichinter->socid = (int)$object->fk_soc; |
||
| 596 | $fichinter->fk_project = (int)$object->fk_project; |
||
| 597 | $fichinter->fk_contrat = (int)$object->fk_contract; |
||
| 598 | $fichinter->author = $user->id; |
||
| 599 | $fichinter->model_pdf = (getDolGlobalString('FICHEINTER_ADDON_PDF')) ? $conf->global->FICHEINTER_ADDON_PDF : 'soleil'; |
||
| 600 | $fichinter->origin = $object->element; |
||
| 601 | $fichinter->origin_id = $object->id; |
||
| 602 | |||
| 603 | // Extrafields |
||
| 604 | $extrafields = new ExtraFields($this->db); |
||
| 605 | $extrafields->fetch_name_optionals_label($fichinter->table_element); |
||
| 606 | $array_options = $extrafields->getOptionalsFromPost($fichinter->table_element); |
||
| 607 | $fichinter->array_options = $array_options; |
||
| 608 | |||
| 609 | $id = $fichinter->create($user); |
||
| 610 | if ($id <= 0) { |
||
| 611 | setEventMessages($fichinter->error, null, 'errors'); |
||
| 612 | } |
||
| 613 | } |
||
| 614 | } |
||
| 615 | return 0; |
||
| 616 | } |
||
| 617 | |||
| 618 | /** |
||
| 619 | * @param Object $conf Dolibarr settings object |
||
| 620 | * @param float $totalonlinkedelements Sum of total amounts (excl VAT) of |
||
| 621 | * invoices linked to $object |
||
| 622 | * @param float $object_total_ht The total amount (excl VAT) of the object |
||
| 623 | * (an order, a proposal, a bill, etc.) |
||
| 624 | * @return bool True if the amounts are equal (rounded on total amount) |
||
| 625 | * True if the module is configured to skip the amount equality check |
||
| 626 | * False otherwise. |
||
| 627 | */ |
||
| 628 | private function shouldClassify($conf, $totalonlinkedelements, $object_total_ht) |
||
| 636 | } |
||
| 637 | } |
||
| 638 |
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.