Completed
Push — master ( d208aa...25518b )
by Lars
12:37
created

DebtorItem::getWeight()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
crap 2
1
<?php
2
/**
3
 * Handles items to debtor (quotation, order, invoice, credit note)
4
 *
5
 * @package Intraface_Debtor
6
 * @author Sune Jensen <[email protected]>
7
 * @author Lars Olesen <[email protected]>
8
 */
9
10
/**
11
 * Handles items to debtor (quotation, order, invoice, credit note)
12
 *
13
 * @package Intraface_Debtor
14
 * @author Sune Jensen <[email protected]>
15
 * @author Lars Olesen <[email protected]>
16
 */
17
class DebtorItem extends Intraface_Standard
18
{
19
    /**
20
     * @var array
21
     */
22
    public $value;
23
24
    /**
25
     * @var integer
26
     */
27
    private $id;
28
29
    /**
30
     * @var object
31
     */
32
    private $invoice;
0 ignored issues
show
Unused Code introduced by
The property $invoice is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
33
34
    /**
35
     * @var object
36
     */
37
    private $db;
38
39
    /**
40
     * @var object
41
     */
42
    private $product;
43
44
    /**
45
     * @var object Intraface_modules_product_Variation
46
     */
47
    private $product_variation;
48
49
    /**
50
     * @var object Intraface_modules_product_Variation_Detail
51
     */
52
    private $product_variation_detail;
53
54
    /**
55
     * @var integer
56
     */
57
    private $product_id;
0 ignored issues
show
Unused Code introduced by
The property $product_id is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
58
59
    /**
60
     * @var object
61
     */
62
    public $error;
63
64
    /**
65
     * Constructor
66
     *
67
     * @param object  $debtor Debtor object
68
     * @param integer $id     If a special item id is needed
69
     *
70
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
71
     */
72 68 View Code Duplication
    public function __construct($debtor, $id = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
73
    {
74 68
        $this->debtor = $debtor;
0 ignored issues
show
Bug introduced by
The property debtor does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
75 68
        $this->db = new DB_Sql;
76 68
        $this->error = new Intraface_Error;
77 68
        $this->id = (int)$id;
78
79 68
        if ($this->id > 0) {
80 1
            $this->load();
81 1
        }
82 68
    }
83
84
    /**
85
     * Loads data
86
     *
87
     * @return void
88
     */
89 1
    private function load()
90
    {
91 1
        if ($this->id == 0) {
92
            return;
93
        }
94 1
        $this->db->query("SELECT id, product_id, product_detail_id, product_variation_id, product_variation_detail_id, description, quantity FROM debtor_item WHERE id = ".$this->id." AND intranet_id = ".$this->debtor->kernel->intranet->get("id"));
95 1
        if ($this->db->nextRecord()) {
96 1
            $this->value["id"] = $this->db->f("id");
97 1
            $this->value["product_id"] = $this->db->f("product_id");
98 1
            $this->value["product_detail_id"] = $this->db->f("product_detail_id");
99 1
            $this->value["product_variation_id"] = $this->db->f("product_variation_id");
100 1
            $this->value["product_variation_detail_id"] = $this->db->f("product_variation_detail_id");
101 1
            $this->value["description"] = $this->db->f("description");
102 1
            $this->value["quantity"] = $this->db->f("quantity");
103 1
        }
104 1
    }
105
106
    /**
107
     * returns product object with loaded from item
108
     *
109
     * @return object Product
110
     */
111 View Code Duplication
    private function getProduct()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
112
    {
113
        if (!$this->product) {
114
            if ($this->get('product_id') == '' || $this->get('product_detail_id') == '') {
115
                throw new Exception('The item is not loaded');
116
            }
117
            $this->product = new Product($this->debtor->kernel, $this->get('product_id'), $this->get('product_detail_id'));
118
        }
119
        return $this->product;
120
    }
121
122
    /**
123
     * Returns Product variation loaded from item
124
     *
125
     * @return object Intraface_modules_product_Variation
126
     */
127 View Code Duplication
    private function getProductVariation()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
128
    {
129
        if (!$this->getProduct()->get('has_variation')) {
130
            throw new Exception('The product must have variation to request variations');
131
        }
132
        if (!$this->product_variation) {
133
            if (intval($this->get('product_variation_id')) == 0) {
134
                throw new Exception('The product variation id is not valid on item '.$this->get('id'));
135
            }
136
            $this->product_variation = $this->product->getVariation($this->get('product_variation_id'));
137
        }
138
        return $this->product_variation;
139
    }
140
141
    /**
142
     * Returns product variation detail loaded from item
143
     *
144
     * @return object Intraface_modules_product_Variation_Detail
145
     */
146 View Code Duplication
    private function getProductVariationDetail()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
    {
148
        if (!$this->getProduct()->get('has_variation')) {
149
            throw new Exception('The product must have variation to request variations');
150
        }
151
        if (!$this->product_variation_detail) {
152
            if (intval($this->get('product_variation_detail_id')) == 0) {
153
                throw new Exception('The product variation detail id is not valid on item '.$this->get('id'));
154
            }
155
            $this->product_variation_detail = $this->getProductVariation()->getDetail($this->get('product_variation_detail_id'));
156
        }
157
        return $this->product_variation_detail;
158
    }
159
160
    /**
161
     * Returns price of product without vat
162
     *
163
     * @return float price of product
164
     */
165 View Code Duplication
    public function getProductPrice()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
166
    {
167
        if ($this->getProduct()->get('has_variation')) {
168
            return $this->getProductVariationDetail()->getPrice($this->getProduct());
169
        } else {
170
            return $this->getProduct()->getDetails()->getPrice();
171
        }
172
    }
173
174
    /**
175
     * Returns weight of product without vat
176
     *
177
     * @return integer weight of product
178
     */
179
    public function getProductWeight()
180
    {
181
        if ($this->getProduct()->get('has_variation')) {
182
            return $this->getProduct()->get("weight") + $this->getProductVariationDetail()->getWeightDifference();
183
        } else {
184
            return $this->getProduct()->get("weight");
185
        }
186
    }
187
188
    /**
189
     * Returns number of product
190
     *
191
     * @return string product number
192
     */
193 View Code Duplication
    public function getProductNumber()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
    {
195
        if ($this->getProduct()->get('has_variation')) {
196
            return $this->getProduct()->get("number").'.'.$this->getProductVariation()->getNumber();
197
        } else {
198
            return $this->getProduct()->get("number");
199
        }
200
    }
201
202
    /**
203
     * Returns name of product
204
     *
205
     * @return string name of product
206
     */
207 View Code Duplication
    public function getProductName()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
    {
209
        if ($this->getProduct()->get('has_variation')) {
210
            return $this->getProduct()->get("name").' - '.$this->getProductVariation()->getName();
211
        } else {
212
            return $this->getProduct()->get("name");
213
        }
214
    }
215
216
217
    /**
218
     * Gets price without taxes
219
     *
220
     * @return float
221
     */
222
    public function getPrice()
223
    {
224
        // TODO how do we handle vat? this should return raw prices
225
        // and then the tax percent should return the tax to apply
226
        // the calculator should handle the final price
227
        return $this->getProductPrice() * $this->get('quantity');
228
    }
229
230
    /**
231
     * Gets weight
232
     *
233
     * @return float
234
     */
235
    public function getWeight()
236
    {
237
        return $this->getProductWeight() * $this->get('quantity');
238
    }
239
240
    /**
241
     * Gets the tax percent on the individual product
242
     *
243
     * @return float
244
     */
245
    public function getTaxPercent()
246
    {
247
        if ($this->getProduct()->get('vat')) {
248
            return 25;
249
        } else {
250
            return 0;
251
        }
252
    }
253
254
    /**
255
     * Saves data
256
     *
257
     * @TODO: Should have product object instead of product id in the param array.
258
     *
259
     * @param array $input Values to save
260
     *
261
     * @return integer
262
     */
263 19
    public function save($input)
264
    {
265 19
        if ($this->debtor->get("locked") == 1) {
266
            $this->error->set('Posten er l�st er l�st og der kan ikke opdateres varer p� den');
267
            return 0;
268
        }
269
270 19
        $input = safeToDb($input);
271
272 19
        $validator = new Intraface_Validator($this->error);
273
274 19
        settype($input["product_id"], 'integer');
275 19 View Code Duplication
        if ($validator->isNumeric($input["product_id"], "Du skal v�lge et produkt", "greater_than_zero")) {
276 18
            if (!isset($input['product_detail_id'])) {
277 18
                $input['product_detail_id'] = 0;
278 18
            }
279
280 18
            require_once 'Intraface/modules/product/Product.php';
281 18
            $product = new Product($this->debtor->kernel, $input["product_id"], $input['product_detail_id']);
282
283 18
            if (!is_object($product) || $product->get('id') == 0) {
284
                 $this->error->set("Ugyldigt produkt");
285
            } else {
286 18
                $product_detail_id = $product->get("detail_id");
287
            }
288
289 18
            if (!isset($input['product_variation_id'])) {
290 18
                $input['product_variation_id'] = 0;
291 18
            }
292 18
            if (intval($input['product_variation_id']) != 0) {
293
                $variation = $product->getVariation(intval($input['product_variation_id']));
294
                if (!$variation->getId()) {
295
                    $this->error->set("Invalid product variation");
296
                }
297
298
                if (!isset($input['product_variation_detail_id'])) {
299
                    $input['product_variation_detail_id'] = 0;
300
                }
301
                $detail = $variation->getDetail(intval($input['product_variation_detail_id']));
302
                if (!$detail->getId()) {
303
                    $this->error->set("Invalid product variation detail");
304
                }
305
306
                $variation_id = $variation->getId();
307
                $variation_detail_id = $detail->getId();
308
            } else {
309 18
                $variation_id = 0;
310 18
                $variation_detail_id = 0;
311
            }
312 18
        }
313
314 19
        if (!isset($input["quantity"])) {
315 1
            $input["quantity"] = 0;
316 1
        }
317 19
        $validator->isDouble($input["quantity"], "Du skal angive et antal", "");
318 19
        $quantity = new Intraface_Amount($input["quantity"]);
319 19
        if ($quantity->convert2db()) {
320 19
            $input["quantity"] = $quantity->get();
321 19
        } else {
322
            $this->error->set("Ugyligt antal");
323
        }
324 19
        if (!isset($input['description'])) {
325 6
            $input['description'] = '';
326 6
        }
327 19
        $validator->isString($input["description"], "Fejl i beskrivelse", "<b><i>", "allow_empty");
328
329 19
        if ($this->error->isError()) {
330 1
            return(false);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by DebtorItem::save of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
331
        }
332
333 18
        $sql = "product_id = ".$input["product_id"].",
334 18
            product_detail_id = ".$product_detail_id.",
0 ignored issues
show
Bug introduced by
The variable $product_detail_id 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...
335 18
            product_variation_id = ".$variation_id.",
0 ignored issues
show
Bug introduced by
The variable $variation_id 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...
336 18
            product_variation_detail_id = ".$variation_detail_id.",
0 ignored issues
show
Bug introduced by
The variable $variation_detail_id 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...
337 18
            quantity = ".$input["quantity"].",
338 18
            description = '".$input["description"]."'";
339
340 18
        if ($this->id == 0) {
341 18
            $position = $this->getPosition(MDB2::singleton(DB_DSN))->getMaxPosition() + 1;
342 18
            $sql = $sql.', position = '.$position;
343
344 18
            $this->db->query("INSERT INTO debtor_item SET ".$sql.", intranet_id = ".$this->debtor->kernel->intranet->get("id").", debtor_id = ".$this->debtor->get("id").", active = 1");
345 18
            $this->id = $this->db->InsertedId();
346 18
        } else {
347
            $this->db->query("UPDATE debtor_item SET ".$sql." WHERE id = ".$this->id." and debtor_id = ".$this->debtor->get("id"));
348
        }
349
350
        // hvis det er et kreditnota, skal fakturastatus opdateres
351 18 View Code Duplication
        if ($this->debtor->get("type") == "credit_note" && $this->debtor->get("where_from") == "invoice" && $this->debtor->get("where_from_id") != 0) {
352
            $invoice = Debtor::factory($this->debtor->kernel, (int)$this->debtor->get("where_from_id"));
353
            $invoice->updateStatus();
0 ignored issues
show
Bug introduced by
The method updateStatus does only exist in Invoice, but not in CreditNote and Order and Quotation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
354
        }
355
356 18
        return $this->id;
357
    }
358
359
    /**
360
     * Changes the product assigned to the item
361
     *
362
     * @param integer $product_id
363
     * @param integer $product_variation_id
364
     * @return boolean true on success
365
     */
366
    public function changeProduct($product_id, $product_variation_id = 0)
367
    {
368
        if (!$this->id) {
369
            throw new Exception('You cannot change product when not saved');
370
        }
371
372
        require_once 'Intraface/modules/product/Product.php';
373
        $product = new Product($this->debtor->kernel, $product_id);
374
375
        if (!is_object($product) || $product->get('id') == 0) {
376
             throw new Excetion('Invalid product id');
377
        } else {
378
            $product_detail_id = $product->get("detail_id");
379
        }
380
381 View Code Duplication
        if (intval($product_variation_id) != 0) {
382
            $variation = $product->getVariation(intval($product_variation_id));
383
            if (!$variation->getId()) {
384
                throw new Exception('Invalid product variation id');
385
            }
386
387
            $detail = $variation->getDetail();
388
            if (!$detail->getId()) {
389
                throw new Exception("Invalid product variation detail");
390
            }
391
392
            $variation_id = $variation->getId();
393
            $variation_detail_id = $detail->getId();
394
        } else {
395
            $variation_id = 0;
396
            $variation_detail_id = 0;
397
        }
398
399
        $sql = "product_id = ".$product->getId().",
400
            product_detail_id = ".$product_detail_id.",
401
            product_variation_id = ".$variation_id.",
402
            product_variation_detail_id = ".$variation_detail_id;
403
404
        $this->db->query("UPDATE debtor_item SET ".$sql." WHERE id = ".$this->id." and debtor_id = ".$this->debtor->get("id"));
405
        return true;
406
    }
407
408
    /**
409
     * Deletes a product
410
     *
411
     * @return boolean
412
     */
413
    public function delete()
414
    {
415
        if ($this->debtor->get("locked") == true) {
416
            $this->error->set('Du kan ikke slette vare til en l�st post');
417
            return false;
418
        }
419
        $this->db->query("UPDATE debtor_item SET active = 0 WHERE id = ".$this->id." AND debtor_id = ".$this->debtor->get("id"));
420
        $this->id = 0;
421
422 View Code Duplication
        if ($this->debtor->get("type") == "credit_note" && $this->debtor->get("where_from") == "invoice" && $this->debtor->get("where_from_id") != 0) {
423
            $invoice = Debtor::factory($this->debtor->kernel, intval($this->debtor->get("where_from_id")));
424
            $invoice->updateStatus();
0 ignored issues
show
Bug introduced by
The method updateStatus does only exist in Invoice, but not in CreditNote and Order and Quotation.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
425
        }
426
427
        return true;
428
    }
429
430
    /**
431
     * Get a list with Debtor items
432
     *
433
     * @return array
434
     */
435 63
    public function getList()
436
    {
437 63
        $db = new DB_Sql;
438 63
        $db2 = new DB_Sql;
0 ignored issues
show
Unused Code introduced by
$db2 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
439
440 63
        $db->query("SELECT id, product_id, product_detail_id, product_variation_id, product_variation_detail_id, quantity, description FROM debtor_item WHERE active = 1 AND intranet_id = ".$this->debtor->kernel->intranet->get("id")." AND debtor_id = ".$this->debtor->get("id")." ORDER BY position ASC, id ASC");
441 63
        $i = 0;
442 63
        $j = 0;
443 63
        $item_no_vat = array();
444 63
        $item_with_vat = array();
445
446 63
        require_once 'Intraface/modules/product/Product.php';
447
448 63
        $currency = $this->debtor->getCurrency();
449
450 63
        while ($db->nextRecord()) {
451 15
            $product = new Product($this->debtor->kernel, $db->f('product_id'), $db->f('product_detail_id'));
452
453 15
            if ($product->getId() != 0 && $product->get('detail_id') != 0) {
454 15
                $item = array();
455 15
                $item["description"] = $db->f("description");
456 15
                $item["quantity"] = $db->f("quantity");
457 15
                $item["id"] = $db->f("id");
458
459 15
                $item["vat"] = $product->get("vat");
460 15
                $item["product_id"] = $product->getId();
461 15
                $item["product_detail_id"] = $product->get("detail_id");
462 15
                $unit = $product->get('unit');
463 15 View Code Duplication
                if ($db->f("quantity") == 1) {
464
                    $item["unit"] = $unit['singular'];
465
                } else {
466 15
                    $item["unit"] = $unit['plural'];
467
                }
468
469 15
                if ($product->get('has_variation')) {
470
                    $variation = $product->getVariation($db->f('product_variation_id'));
471
                    $detail = $variation->getDetail($db->f('product_variation_detail_id'));
472
                    $item["name"] = $product->get("name").' - '.$variation->getName();
473
                    $item["number"]= $product->get("number").'.'.$variation->getNumber();
474
                    $item["price"] = $detail->getPrice($product);
475
                    if ($currency) {
476
                        $item['price_currency'] = $detail->getPriceInCurrency($currency, $this->debtor->get('currency_product_price_exchange_rate_id'), $product);
477
                    }
478
                } else {
479 15
                    $item["name"] = $product->get("name");
480 15
                    $item["number"]= $product->get("number");
481 15
                    $item["price"] = $product->getDetails()->getPrice();
482 15
                    if ($currency) {
483 2
                        $item['price_currency'] = $product->getDetails()->getPriceInCurrency($currency, $this->debtor->get('currency_product_price_exchange_rate_id'));
484 18
                    }
485
                }
486
487 15
                if ($product->get("vat") == 0) {
488 2
                    $item_no_vat[$j] = $item;
489 2
                    $item_no_vat[$j]["amount"] = new Ilib_Variable_Float($item["quantity"] * $item["price"]->getAsIso(2));
490 2 View Code Duplication
                    if ($currency) {
491 18
                        $item_no_vat[$j]["amount_currency"] = new Ilib_Variable_Float($item["quantity"] * $item["price_currency"]->getAsIso(2), 'iso');
492
                    }
493 2
                    $j++;
494 2
                } else {
495 13
                    $item_with_vat[$i] = $item;
496 13
                    $item_with_vat[$i]["amount"] = new Ilib_Variable_Float($item["quantity"] * $item["price"]->getAsIso(2) * 1.25);
497 13 View Code Duplication
                    if ($currency) {
498 2
                        $item_with_vat[$i]["amount_currency"] = new Ilib_Variable_Float($item["quantity"] * $item["price_currency"]->getAsIso(2) * 1.25, 'iso');
499 2
                    }
500 13
                    $i++;
501
                }
502 15
            } else {
503
                 throw new Exception("Ugyldig produktdetalje i DebtorItem->getList() on ".$db->f('product_id').'/'.$db->f('product_detail_id'));
504
            }
505 15
        }
506 63
        unset($db);
507 63
        return(array_merge($item_with_vat, $item_no_vat));
508
    }
509
510
    /**
511
     * Method to get quantity of each product
512
     *
513
     * TODO This should not be in this class
514
     *
515
     * @param integer $product_id Product id
516
     * @param string  $from_date  Which date to start the quantity from
517
     * @param string  $sent       TODO WHAT IS THIS
518
     *
519
     * @return integer
520
     */
521 1
    public function getQuantity($product_id, $product_variation_id, $from_date, $sent = "")
522
    {
523
524
        /*
0 ignored issues
show
Unused Code Comprehensibility introduced by
79% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
525
        0=>'created',
526
            1=>'sent',
527
            2=>'executed',
528
            3=>'cancelled'
529
        */
530
531 1
        if (!in_array($sent, array("", "not_sent"))) {
532
            throw new Exception("Ugyldig værdi i 3. parameter til debtor->item->getQuantity()");
533
        }
534
535 1
        if ($this->debtor->get('type') == "quotation") {
536 1
            $status_sql = "debtor.status = 0 OR debtor.status = 1"; // tilbud der er oprettet eller sent.
537 1
            $date_sql = "";
538 1
        } elseif ($this->debtor->get('type') == "order") {
539 1
            $status_sql = "debtor.status = 0 OR debtor.status = 1"; // ordre der er oprettet eller sent.
540 1
            $date_sql = "";
541 1 View Code Duplication
        } elseif ($this->debtor->get('type') == "invoice" && $sent == "") {
542 1
            $status_sql = "debtor.status = 1 OR debtor.status = 2"; // fakturaer der er sent eller f�rdigbehandlet
543 1
            $date_sql = "AND debtor.date_sent > \"".$from_date."\"";
544 1
        } elseif ($this->debtor->get('type') == "invoice" && $sent == "not_sent") {
545 1
            $status_sql = "debtor.status = 0"; // fakturaer der er oprettet.
546 1
            $date_sql = "";
547 1 View Code Duplication
        } elseif ($this->debtor->get('type') == "credit_note") {
548 1
            $status_sql = "debtor.status = 2"; // kredit notaer der er f�rdigbehandlet
549 1
            $date_sql = "AND debtor.date_executed > \"".$from_date."\"";
550 1
        } else {
551
            throw new Exception("Der er opstået en fejl i Debtor->item->getQuantity()");
552
        }
553
554 1
        $db = new DB_sql;
555
556
        $sql = "SELECT SUM(quantity) AS sum_quantity
557
            FROM debtor_item INNER JOIN debtor
558
                ON debtor_item.debtor_id = debtor.id
559
            WHERE debtor_item.active = 1 AND debtor.active = 1
560 1
                AND debtor_item.intranet_id = ".$this->debtor->kernel->intranet->get("id")." AND debtor.intranet_id = ".$this->debtor->kernel->intranet->get("id")."
561 1
                AND debtor.type = ".$this->debtor->get('type_key')." AND (".$status_sql.")
562 1
                AND debtor_item.product_id = ".intval($product_id)."
563 1
                AND debtor_item.product_variation_id = ".intval($product_variation_id)." ".$date_sql;
564 1
        $db->query($sql);
565 1
        $db->nextRecord(); // Der vil altid v�re en post
566 1
        return intval($db->f("sum_quantity"));
567
    }
568
569
    /**
570
     * Returns position object
571
     *
572
     * @return object Ilib_Position
573
     */
574 18
    function getPosition($db)
575
    {
576 18
        return new Ilib_Position($db, "debtor_item", $this->id, "intranet_id=".$this->debtor->kernel->intranet->get('id')." AND debtor_id=".$this->debtor->get('id')." AND active = 1", "position", "id");
577
    }
578
}
579