Completed
Branch develop (0fc56d)
by
unknown
26:25
created

InterfaceWorkflowManager   C

Complexity

Total Complexity 68

Size/Duplication

Total Lines 229
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 0
loc 229
rs 5.6756
c 0
b 0
f 0
wmc 68
lcom 1
cbo 4

1 Method

Rating   Name   Duplication   Size   Complexity  
F runTrigger() 0 209 68

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, LOG_DEBUG);
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);
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, LOG_DEBUG);
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);
88
                if ($ret < 0) { $this->error=$newobject->error; $this->errors[]=$newobject->error; }
89
                return $ret;
90
            }
91
        }
92
93
94
95
        // Order classify billed proposal
96
        if ($action == 'ORDER_CLASSIFY_BILLED')
97
        {
98
        	dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG);
99
        	if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL))
100
        	{
101
        		$object->fetchObjectLinked('','propal',$object->id,$object->element);
102
				if (! empty($object->linkedObjects))
103
				{
104
				    $totalonlinkedelements=0;
105
					foreach($object->linkedObjects['propal'] as $element)
106
					{
107
					    if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
108
					}
109
					dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
110
					if ($totalonlinkedelements == $object->total_ht)
111
					{
112
    					foreach($object->linkedObjects['propal'] as $element)
113
    					{
114
    					    $ret=$element->classifyBilled($user);
115
    					}
116
					}
117
				}
118
        		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...
119
        	}
120
        }
121
122
        // classify billed order
123
        if ($action == 'BILL_VALIDATE')
124
        {
125
        	dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG);
126
127
        	if (! empty($conf->propal->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL))
128
        	{
129
        		$object->fetchObjectLinked('','propal',$object->id,$object->element);
130
        		if (! empty($object->linkedObjects))
131
        		{
132
        		    $totalonlinkedelements=0;
133
        		    foreach($object->linkedObjects['propal'] as $element)
134
        		    {
135
        		        if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
136
        		    }
137
        		    dol_syslog("Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
138
        		    if ($totalonlinkedelements == $object->total_ht)
139
        		    {
140
        		        foreach($object->linkedObjects['propal'] as $element)
141
        		        {
142
        		            $ret=$element->classifyBilled($user);
143
        		        }
144
        		    }
145
        		}
146
        		return $ret;
147
        	}
148
149
        	if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER))
150
        	{
151
        		$object->fetchObjectLinked('','commande',$object->id,$object->element);
152
        		if (! empty($object->linkedObjects))
153
        		{
154
        		    $totalonlinkedelements=0;
155
        		    foreach($object->linkedObjects['commande'] as $element)
156
        		    {
157
        		        if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
158
        		    }
159
        		    dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
160
        		    if ($totalonlinkedelements == $object->total_ht)
161
        		    {
162
        		        foreach($object->linkedObjects['commande'] as $element)
163
        		        {
164
        		            $ret=$element->classifyBilled($user);
165
        		        }
166
        		    }
167
        		}
168
        		return $ret;
169
        	}
170
        }
171
172
        // Invoice classify billed order
173
        if ($action == 'BILL_PAYED')
174
        {
175
            dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG);
176
177
            if (! empty($conf->commande->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER))
178
            {
179
                $object->fetchObjectLinked('','commande',$object->id,$object->element);
180
                if (! empty($object->linkedObjects))
181
                {
182
                    $totalonlinkedelements=0;
183
                    foreach($object->linkedObjects['commande'] as $element)
184
                    {
185
                        if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
186
                    }
187
                    dol_syslog("Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG);
188
                    if ($totalonlinkedelements == $object->total_ht)
189
                    {
190
                        foreach($object->linkedObjects['commande'] as $element)
191
                        {
192
                            $ret=$element->classifyBilled($user);
193
                        }
194
                    }
195
                }
196
                return $ret;
197
            }
198
        }
199
200
        if ($action=='SHIPPING_VALIDATE')
201
        {
202
        	dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id, LOG_DEBUG);
203
204
205
        	if (! empty($conf->commande->enabled) && ! empty($conf->expedition->enabled) && ! empty($conf->global->WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING))
206
        	{
207
        		$qtyshipped=array();
208
        		$qtyordred=array();
209
        		require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
210
211
        		//find all shippement on order origin
212
        		$order = new Commande($this->db);
213
        		$ret=$order->fetch($object->origin_id);
214
        		if ($ret<0) {
215
        			$this->error=$order->error; $this->errors=$order->errors;
216
        			return $ret;
217
        		}
218
        		$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...
219
        		if ($ret<0) {
220
        			$this->error=$order->error; $this->errors=$order->errors;
221
        			return $ret;
222
        		}
223
        		//Build array of quantity shipped by product for an order
224
        		if (is_array($order->linkedObjects) && count($order->linkedObjects)>0) {
225
        			foreach($order->linkedObjects as $type=>$shipping_array) {
226
        				if ($type=='shipping' && is_array($shipping_array) && count($shipping_array)>0) {
227
        					foreach ($shipping_array as $shipping) {
228
		        				if (is_array($shipping->lines) && count($shipping->lines)>0) {
229
		        					foreach($shipping->lines as $shippingline) {
230
		        						$qtyshipped[$shippingline->fk_product]+=$shippingline->qty;
231
		        					}
232
		        				}
233
	        				}
234
        				}
235
        			}
236
        		}
237
        		//Build array of quantity ordered by product
238
        		if (is_array($order->lines) && count($order->lines)>0) {
239
        			foreach($order->lines as $orderline) {
240
        				$qtyordred[$orderline->fk_product]+=$orderline->qty;
241
        			}
242
        		}
243
        		//dol_syslog(var_export($qtyordred,true),LOG_DEBUG);
244
        		//dol_syslog(var_export($qtyshipped,true),LOG_DEBUG);
245
        		//Compare array
246
        		$diff_array=array_diff_assoc($qtyordred,$qtyshipped);
247
        		if (count($diff_array)==0) {
248
        			//No diff => mean everythings is shipped
249
        			$ret=$object->setStatut(Commande::STATUS_CLOSED, $object->origin_id, $object->origin);
250
        			if ($ret<0) {
251
        				$this->error=$object->error; $this->errors=$object->errors;
252
        				return $ret;
253
        			}
254
        		}
255
        	}
256
        }
257
258
        return 0;
259
    }
260
261
}
262