Completed
Branch develop (451d3e)
by
unknown
27:33
created

InterfaceWorkflowManager   D

Complexity

Total Complexity 93

Size/Duplication

Total Lines 281
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 281
rs 4.8717
c 0
b 0
f 0
wmc 93
lcom 1
cbo 4

1 Method

Rating   Name   Duplication   Size   Complexity  
F runTrigger() 0 261 93

How to fix   Complexity   

Complex Class

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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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
2
/* Copyright (C) 2010      Regis Houssin       <[email protected]>
3
 * Copyright (C) 2011-2017 Laurent Destailleur <[email protected]>
4
 * Copyright (C) 2014      Marcos García       <[email protected]>
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 <http://www.gnu.org/licenses/>.
18
 */
19
20
/**
21
 *  \file       htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php
22
 *  \ingroup    core
23
 *  \brief      Trigger file for workflows
24
 */
25
26
require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php';
27
28
29
/**
30
 *  Class of triggers for workflow module
31
 */
32
33
class InterfaceWorkflowManager extends DolibarrTriggers
34
{
35
	public $picto = 'technic';
36
	public $family = 'core';
37
	public $description = "Triggers of this module allows to manage workflows";
38
	public $version = self::VERSION_DOLIBARR;
39
40
	/**
41
	 * Function called when a Dolibarrr business event is done.
42
	 * All functions "runTrigger" are triggered if file is inside directory htdocs/core/triggers or htdocs/module/code/triggers (and declared)
43
	 *
44
	 * @param string		$action		Event action code
45
	 * @param Object		$object     Object
46
	 * @param User		    $user       Object user
47
	 * @param Translate 	$langs      Object langs
48
	 * @param conf		    $conf       Object conf
49
	 * @return int         				<0 if KO, 0 if no triggered ran, >0 if OK
50
	 */
51
	public function runTrigger($action, $object, User $user, Translate $langs, Conf $conf)
52
    {
53
        if (empty($conf->workflow->enabled)) return 0;     // Module not active, we do nothing
54
55
        // Proposals to order
56
        if ($action == 'PROPAL_CLOSE_SIGNED')
57
        {
58
        	dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
59
            if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_PROPAL_AUTOCREATE_ORDER))
60
            {
61
                include_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
62
                $newobject = new Commande($this->db);
63
64
                $newobject->context['createfrompropal'] = 'createfrompropal';
65
                $newobject->context['origin'] = $object->element;
66
                $newobject->context['origin_id'] = $object->id;
67
68
                $ret=$newobject->createFromProposal($object, $user);
69
                if ($ret < 0) { $this->error=$newobject->error; $this->errors[]=$newobject->error; }
70
                return $ret;
71
            }
72
        }
73
74
        // Order to invoice
75
        if ($action == 'ORDER_CLOSE')
76
        {
77
            dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
78
            if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_ORDER_AUTOCREATE_INVOICE))
79
            {
80
                include_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
81
                $newobject = new Facture($this->db);
82
83
                $newobject->context['createfromorder'] = 'createfromorder';
84
                $newobject->context['origin'] = $object->element;
85
                $newobject->context['origin_id'] = $object->id;
86
87
                $ret=$newobject->createFromOrder($object, $user);
88
                if ($ret < 0) { $this->error=$newobject->error; $this->errors[]=$newobject->error; }
89
                return $ret;
90
            }
91
        }
92
93
        // Order classify billed proposal
94
        if ($action == 'ORDER_CLASSIFY_BILLED')
95
        {
96
        	dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
97
        	if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL))
98
        	{
99
        		$object->fetchObjectLinked('','propal',$object->id,$object->element);
100
				if (! empty($object->linkedObjects))
101
				{
102
				    $totalonlinkedelements=0;
103
					foreach($object->linkedObjects['propal'] as $element)
104
					{
105
					    if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
106
					}
107
					dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
108
					if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
109
					{
110
    					foreach($object->linkedObjects['propal'] as $element)
111
    					{
112
    					    $ret=$element->classifyBilled($user);
113
    					}
114
					}
115
				}
116
        		return $ret;
0 ignored issues
show
Bug introduced by
The variable $ret does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
117
        	}
118
        }
119
120
        // classify billed order & billed propososal
121
        if ($action == 'BILL_VALIDATE')
122
        {
123
        	dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
124
125
			// First classify billed the order to allow the proposal classify process
126
			if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER))
127
        	{
128
        		$object->fetchObjectLinked('','commande',$object->id,$object->element);
129
        		if (! empty($object->linkedObjects))
130
        		{
131
        		    $totalonlinkedelements=0;
132
        		    foreach($object->linkedObjects['commande'] as $element)
133
        		    {
134
        		        if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
135
        		    }
136
        		    dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
137
        		    if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
138
        		    {
139
        		        foreach($object->linkedObjects['commande'] as $element)
140
        		        {
141
        		            $ret=$element->classifyBilled($user);
142
        		        }
143
        		    }
144
        		}
145
        		return $ret;
146
        	}
147
148
			// Second classify billed the proposal.
149
        	if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL))
150
        	{
151
        		$object->fetchObjectLinked('','propal',$object->id,$object->element);
152
        		if (! empty($object->linkedObjects))
153
        		{
154
        		    $totalonlinkedelements=0;
155
        		    foreach($object->linkedObjects['propal'] as $element)
156
        		    {
157
        		        if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
158
        		    }
159
        		    dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
160
        		    if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
161
        		    {
162
        		        foreach($object->linkedObjects['propal'] as $element)
163
        		        {
164
        		            $ret=$element->classifyBilled($user);
165
        		        }
166
        		    }
167
        		}
168
        		return $ret;
169
        	}
170
        }
171
172
        // classify billed order & billed propososal
173
        if ($action == 'BILL_SUPPLIER_VALIDATE')
174
        {
175
        	dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
176
177
        	// First classify billed the order to allow the proposal classify process
178
        	if (! empty($conf->fournisseur->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER))
179
        	{
180
        		$object->fetchObjectLinked('','order_supplier',$object->id,$object->element);
181
        		if (! empty($object->linkedObjects))
182
        		{
183
        			$totalonlinkedelements=0;
184
        			foreach($object->linkedObjects['order_supplier'] as $element)
185
        			{
186
        				if ($element->statut == CommandeFournisseur::STATUS_ACCEPTED || $element->statut == CommandeFournisseur::STATUS_ORDERSENT || $element->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY || $element->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) $totalonlinkedelements += $element->total_ht;
187
        			}
188
        			dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
189
        			if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
190
        			{
191
        				foreach($object->linkedObjects['order_supplier'] as $element)
192
        				{
193
        					$ret=$element->classifyBilled($user);
194
        				}
195
        			}
196
        		}
197
        		return $ret;
198
        	}
199
200
        	// Second classify billed the proposal.
201
        	if (! empty($conf->supplier_proposal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_SUPPLIER_PROPOSAL))
202
        	{
203
        		$object->fetchObjectLinked('','supplier_proposal',$object->id,$object->element);
204
        		if (! empty($object->linkedObjects))
205
        		{
206
        			$totalonlinkedelements=0;
207
        			foreach($object->linkedObjects['supplier_proposal'] as $element)
208
        			{
209
        				if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
210
        			}
211
        			dol_syslog( "Amount of linked supplier proposals = ".$totalonlinkedelements.", of supplier invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
212
        			if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
213
        			{
214
        				foreach($object->linkedObjects['supplier_proposal'] as $element)
215
        				{
216
        					$ret=$element->classifyBilled($user);
217
        				}
218
        			}
219
        		}
220
        		return $ret;
221
        	}
222
        }
223
224
        // Invoice classify billed order
225
        if ($action == 'BILL_PAYED')
226
        {
227
            dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
228
229
            if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER))
230
            {
231
                $object->fetchObjectLinked('','commande',$object->id,$object->element);
232
                if (! empty($object->linkedObjects))
233
                {
234
                    $totalonlinkedelements=0;
235
                    foreach($object->linkedObjects['commande'] as $element)
236
                    {
237
                        if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
238
                    }
239
                    dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
240
                    if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
241
                    {
242
                        foreach($object->linkedObjects['commande'] as $element)
243
                        {
244
                            $ret=$element->classifyBilled($user);
245
                        }
246
                    }
247
                }
248
                return $ret;
249
            }
250
        }
251
252
        if ($action=='SHIPPING_VALIDATE')
253
        {
254
        	dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
255
256
        	if (! empty($conf->commande->enabled) && ! empty($conf->expedition->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING))
257
        	{
258
        		$qtyshipped=array();
259
        		$qtyordred=array();
260
        		require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
261
262
        		//find all shippement on order origin
263
        		$order = new Commande($this->db);
264
        		$ret=$order->fetch($object->origin_id);
265
        		if ($ret<0) {
266
        			$this->error=$order->error; $this->errors=$order->errors;
267
        			return $ret;
268
        		}
269
        		$ret=$order->fetchObjectLinked($order->id,'commande',null,'shipping');
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $ret is correct as $order->fetchObjectLinke...nde', null, 'shipping') (which targets CommonObject::fetchObjectLinked()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
270
        		if ($ret<0) {
271
        			$this->error=$order->error; $this->errors=$order->errors;
272
        			return $ret;
273
        		}
274
        		//Build array of quantity shipped by product for an order
275
        		if (is_array($order->linkedObjects) && count($order->linkedObjects)>0) {
276
        			foreach($order->linkedObjects as $type=>$shipping_array) {
277
        				if ($type=='shipping' && is_array($shipping_array) && count($shipping_array)>0) {
278
        					foreach ($shipping_array as $shipping) {
279
		        				if (is_array($shipping->lines) && count($shipping->lines)>0) {
280
		        					foreach($shipping->lines as $shippingline) {
281
		        						$qtyshipped[$shippingline->fk_product]+=$shippingline->qty;
282
		        					}
283
		        				}
284
	        				}
285
        				}
286
        			}
287
        		}
288
289
        		//Build array of quantity ordered by product
290
        		if (is_array($order->lines) && count($order->lines)>0) {
291
        			foreach($order->lines as $orderline) {
292
        				$qtyordred[$orderline->fk_product]+=$orderline->qty;
293
        			}
294
        		}
295
        		//dol_syslog(var_export($qtyordred,true),LOG_DEBUG);
296
        		//dol_syslog(var_export($qtyshipped,true),LOG_DEBUG);
297
        		//Compare array
298
        		$diff_array=array_diff_assoc($qtyordred,$qtyshipped);
299
        		if (count($diff_array)==0) {
300
        			//No diff => mean everythings is shipped
301
        			$ret=$object->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin);
302
        			if ($ret<0) {
303
        				$this->error=$object->error; $this->errors=$object->errors;
304
        				return $ret;
305
        			}
306
        		}
307
        	}
308
        }
309
310
        return 0;
311
    }
312
313
}
314