Issues (4714)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Intraface/modules/procurement/ProcurementItem.php (18 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Handles items to procurement
4
 *
5
 * @package Intraface_Procurement
6
 * @author Sune Jensen <[email protected]>
7
 * @author Lars Olesen <[email protected]>
8
 */
9
10
/**
11
 * Handles items to procurement
12
 *
13
 * @package Intraface_Procurement
14
 * @author Sune Jensen <[email protected]>
15
 * @author Lars Olesen <[email protected]>
16
 */
17 1
require_once 'Intraface/modules/product/Product.php';
18
19
class ProcurementItem extends Intraface_Standard
20
{
21
    /**
22
     * @var integer id of item
23
     */
24
    private $id;
25
26
    /**
27
     * @var object DB_sql
28
     */
29
    private $db;
0 ignored issues
show
The property $db 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...
30
31
    /**
32
     * @var object procurement
33
     */
34
    private $procurement;
35
36
    /**
37
     * @var object product
38
     */
39
    private $product;
40
41
    /**
42
     * @var object product variation
43
     */
44
    private $product_variation;
45
46
    /**
47
     * @var obejct product variation detail
48
     */
49
    private $product_variation_detail;
50
51
    /**
52
     * @var object Ilib_Error
53
     */
54
    public $error;
55
56
    /**
57
     * Constructor
58
     *
59
     * @param object Procurement
60
     * @param integer item id
61
     * @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...
62
     */
63 1 View Code Duplication
    public function __construct($procurement, $id)
0 ignored issues
show
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...
64
    {
65 1
        $this->procurement = $procurement;
66 1
        $this->error = new Intraface_Error;
67 1
        $this->id = (int) $id;
68
69 1
        if ($this->id > 0) {
70
            $this->load();
71
        }
72 1
    }
73
74
    /**
75
     * load data to object
76
     *
77
     * @return void
78
     */
79
    private function load()
80
    {
81
        if ($this->id == 0) {
82
            return;
83
        }
84
85
        $db = new DB_Sql;
86
87
        $db->query("SELECT procurement_item.* FROM procurement_item
88
                    INNER JOIN procurement ON procurement_item.procurement_id = procurement.id
89
                    WHERE procurement_item.id = " . $this->id . " AND procurement.id = " . $this->procurement->get('id') . " AND procurement_item.intranet_id = " . $this->procurement->kernel->intranet->get("id"));
90
        if ($db->nextRecord()) {
91
            $this->value["id"] = $db->f("id");
92
            $this->value["product_id"] = $db->f("product_id");
93
            $this->value["product_detail_id"] = $db->f("product_detail_id");
94
            $this->value["product_variation_id"] = $db->f("product_variation_id");
95
            $this->value["product_variation_detail_id"] = $db->f("product_variation_detail_id");
96
            $this->value["unit_purchase_price"] = $db->f("unit_purchase_price");
97
            $this->value["dk_unit_purchase_price"] = number_format($db->f("unit_purchase_price"), 2, ",", ".");
98
            $this->value["quantity"] = $db->f("quantity");
99
        } else {
100
            $this->id = 0;
101
            $this->value['id'] = 0;
102
        }
103
    }
104
105
    /**
106
     * Returns product object with loaded from item
107
     *
108
     * @return object Product
109
     */
110 View Code Duplication
    private function getProduct()
0 ignored issues
show
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...
111
    {
112
        if (!$this->product) {
113
            if ($this->get('product_id') == '' || $this->get('product_detail_id') == '') {
114
                throw new Exception('The item is not loaded');
115
            }
116
            $this->product = new Product($this->procurement->kernel, $this->get('product_id'), $this->get('product_detail_id'));
117
        }
118
        return $this->product;
119
    }
120
121
    /**
122
     * Returns Product variation loaded from item
123
     *
124
     * @return object Intraface_modules_product_Variation
125
     */
126 View Code Duplication
    private function getProductVariation()
0 ignored issues
show
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...
127
    {
128
        if (!$this->getProduct()->get('has_variation')) {
129
            throw new Exception('The product must have variation to request variations');
130
        }
131
        if (!$this->product_variation) {
132
            if (intval($this->get('product_variation_id')) == 0) {
133
                throw new Exception('The product variation id is not valid on item '.$this->get('id'));
134
            }
135
            $this->product_variation = $this->product->getVariation($this->get('product_variation_id'));
136
        }
137
        return $this->product_variation;
138
    }
139
140
    /**
141
     * Returns product variation detail loaded from item
142
     *
143
     * @return object Intraface_modules_product_Variation_Detail
144
     */
145 View Code Duplication
    private function getProductVariationDetail()
0 ignored issues
show
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...
146
    {
147
        if (!$this->getProduct()->get('has_variation')) {
148
            throw new Exception('The product must have variation to request variations');
149
        }
150
        if (!$this->product_variation_detail) {
151
            if (intval($this->get('product_variation_detail_id')) == 0) {
152
                throw new Exception('The product variation detail id is not valid on item '.$this->get('id'));
153
            }
154
            $this->product_variation_detail = $this->getProductVariation()->getDetail($this->get('product_variation_detail_id'));
155
        }
156
        return $this->product_variation_detail;
157
    }
158
159
    /**
160
     * Returns price of product without vat
161
     *
162
     * @return float price of product
163
     */
164 View Code Duplication
    public function getProductPrice()
0 ignored issues
show
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...
165
    {
166
        if ($this->getProduct()->get('has_variation')) {
167
            return $this->getProductVariationDetail()->getPrice($this->getProduct());
168
        } else {
169
            return $this->getProduct()->getDetails()->getPrice();
170
        }
171
    }
172
173
    /**
174
     * Returns number of product
175
     *
176
     * @return string product number
177
     */
178 View Code Duplication
    public function getProductNumber()
0 ignored issues
show
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...
179
    {
180
        if ($this->getProduct()->get('has_variation')) {
181
            return $this->getProduct()->get("number").'.'.$this->getProductVariation()->getNumber();
182
        } else {
183
            return $this->getProduct()->get("number");
184
        }
185
    }
186
187
    /**
188
     * Returns name of product
189
     *
190
     * @return string name of product
191
     */
192 View Code Duplication
    public function getProductName()
0 ignored issues
show
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...
193
    {
194
        if ($this->getProduct()->get('has_variation')) {
195
            return $this->getProduct()->get("name").' - '.$this->getProductVariation()->getName();
196
        } else {
197
            return $this->getProduct()->get("name");
198
        }
199
    }
200
201
    /**
202
     * Gets the tax percent on the individual product
203
     *
204
     * @return float
205
     */
206
    public function getProductTaxPercent()
207
    {
208
        if ($this->getProduct()->get('vat')) {
209
            return 25;
210
        } else {
211
            return 0;
212
        }
213
    }
214
215
    /**
216
     * Saves item
217
     *
218
     * @param array input to be saved
219
     * @return integer id of item
220
     */
221
    function save($input)
222
    {
223
        $input = safeToDb($input);
224
225
        $validator = new Intraface_Validator($this->error);
226
227
        settype($input["product_id"], 'integer');
228 View Code Duplication
        if ($validator->isNumeric($input["product_id"], "Du skal v�lge et produkt", "greater_than_zero")) {
229
            if (!isset($input['product_detail_id'])) {
230
                $input['product_detail_id'] = 0;
231
            }
232
233
            require_once 'Intraface/modules/product/Product.php';
234
            $product = new Product($this->procurement->kernel, $input["product_id"], $input['product_detail_id']);
235
236
            if (!is_object($product) || $product->get('id') == 0) {
237
                 $this->error->set("Ugyldigt produkt");
238
            } else {
239
                $product_detail_id = $product->get("detail_id");
240
            }
241
242
            if (!isset($input['product_variation_id'])) {
243
                $input['product_variation_id'] = 0;
244
            }
245
            if (intval($input['product_variation_id']) != 0) {
246
                $variation = $product->getVariation(intval($input['product_variation_id']));
247
                if (!$variation->getId()) {
248
                    $this->error->set("Invalid product variation");
249
                }
250
251
                if (!isset($input['product_variation_detail_id'])) {
252
                    $input['product_variation_detail_id'] = 0;
253
                }
254
                $detail = $variation->getDetail(intval($input['product_variation_detail_id']));
255
                if (!$detail->getId()) {
256
                    $this->error->set("Invalid product variation detail");
257
                }
258
259
                $variation_id = $variation->getId();
260
                $variation_detail_id = $detail->getId();
261
            } else {
262
                $variation_id = 0;
263
                $variation_detail_id = 0;
264
            }
265
        }
266
267
        $validator->isNumeric($input["quantity"], "Du skal angive et antal", "greater_than_zero,integer");
268
269
        if (!isset($input["dk_unit_purchase_price"])) {
270
            $input["dk_unit_purchase_price"] = 0;
271
        }
272
        $validator->isDouble($input["dk_unit_purchase_price"], "Du skal angive en indk�bspris", "zero_or_greater");
273
        $unit_purchase_price = new Intraface_Amount($input["dk_unit_purchase_price"]);
274
        if ($unit_purchase_price->convert2db()) {
275
            $input["unit_purchase_price"] = $unit_purchase_price->get();
276
        } else {
277
            $this->error->set("Invalid purchase price");
278
        }
279
280
        if ($this->error->isError()) {
281
            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 ProcurementItem::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...
282
            exit;
0 ignored issues
show
die; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
Coding Style Compatibility introduced by
The method save() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
283
        }
284
285
        $sql = "product_id = " . $product->getId() . ",
0 ignored issues
show
The variable $product 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...
286
                product_detail_id = " . $product_detail_id . ",
0 ignored issues
show
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...
287
                product_variation_id = " . $variation_id . ",
0 ignored issues
show
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...
288
                product_variation_detail_id = " . $variation_detail_id . ",
0 ignored issues
show
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...
289
                quantity = " . $input["quantity"] . ",
290
                unit_purchase_price = " . $input["unit_purchase_price"];
291
292
        $db = new DB_Sql;
293
294
        if ($this->id == 0) {
295
            $db->query("INSERT INTO procurement_item SET " . $sql . ", intranet_id = " . $this->procurement->kernel->intranet->get("id") . ", procurement_id = " . $this->procurement->get("id") . ", active = 1");
296
            $this->id = $db->InsertedId();
297 View Code Duplication
        } else {
298
            $db->query("UPDATE procurement_item SET " . $sql . " WHERE id = " . $this->id . " AND procurement_id = " . $this->procurement->get("id") . " AND intranet_id = " . $this->procurement->kernel->intranet->get("id"));
299
        }
300
301
        return $this->id;
302
    }
303
304
    /**
305
     * Sets the purchase price of an item
306
     *
307
     * @param float $price
308
     * @return boolean true on success
309
     */
310
    public function setPurchasePrice($price)
311
    {
312
313
        if ($this->id == 0) {
314
            throw new Exception('You can only set purchase price when item has been saved');
315
        }
316
        $validator = new Intraface_Validator($this->error);
317
        if ($validator->isDouble($price, "Ugyldig indk�bspris", "zero_or_greater")) {
318
            $unit_purchase_price = new Intraface_Amount($price);
319
            $unit_purchase_price->convert2db();
320
        }
321
322
        if ($this->error->isError()) {
323
            return false;
324
        }
325
326
        $sql = "unit_purchase_price = " . $unit_purchase_price->get();
0 ignored issues
show
The variable $unit_purchase_price 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...
327
328
        $db = new DB_Sql;
329
        $db->query("UPDATE procurement_item SET " . $sql . " WHERE id = " . $this->id . " AND procurement_id = " . $this->procurement->get("id") . " AND intranet_id = " . $this->procurement->kernel->intranet->get("id"));
330
        return true;
331
    }
332
333
    /**
334
     * Changes the product assigned to the item
335
     *
336
     * @param integer $product_id
337
     * @param integer $product_variation_id
338
     * @return boolean true on success
339
     */
340
    public function changeProduct($product_id, $product_variation_id = 0)
341
    {
342
        if (!$this->id) {
343
            throw new Exception('You cannot change product when not saved');
344
        }
345
346
        require_once 'Intraface/modules/product/Product.php';
347
        $product = new Product($this->procurement->kernel, $product_id);
348
349
        if (!is_object($product) || $product->get('id') == 0) {
350
             throw new Excetion('Invalid product id');
351
        } else {
352
            $product_detail_id = $product->get("detail_id");
353
        }
354
355 View Code Duplication
        if (intval($product_variation_id) != 0) {
356
            $variation = $product->getVariation(intval($product_variation_id));
357
            if (!$variation->getId()) {
358
                throw new Exception('Invalid product variation id');
359
            }
360
361
            $detail = $variation->getDetail();
362
            if (!$detail->getId()) {
363
                throw new Exception("Invalid product variation detail");
364
            }
365
366
            $variation_id = $variation->getId();
367
            $variation_detail_id = $detail->getId();
368
        } else {
369
            $variation_id = 0;
370
            $variation_detail_id = 0;
371
        }
372
373
        $sql = "product_id = ".$product->getId().",
374
            product_detail_id = ".$product_detail_id.",
375
            product_variation_id = ".$variation_id.",
376
            product_variation_detail_id = ".$variation_detail_id;
377
378
        $db = new DB_Sql;
379
        $db->query("UPDATE procurement_item SET " . $sql . " WHERE id = " . $this->id . " AND procurement_id = " . $this->procurement->get("id") . " AND intranet_id = " . $this->procurement->kernel->intranet->get("id"));
380
381
        return true;
382
    }
383
384
    /**
385
     * Deletes item
386
     *
387
     */
388 View Code Duplication
    public function delete()
0 ignored issues
show
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...
389
    {
390
        $db = new DB_Sql;
391
        $db->query("UPDATE procurement_item SET active = 0 WHERE intranet_id = " . $this->procurement->kernel->intranet->get('id') . " AND id = " . $this->id . " AND procurement_id = " . $this->procurement->get("id"));
392
        $this->id = 0;
393
394
        return 1;
395
    }
396
397
    /**
398
     * Returns list of items
399
     *
400
     * @return array list of items
401
     */
402
    public function getList()
403
    {
404
        $db = new DB_Sql;
405
        $db->query("SELECT * FROM procurement_item WHERE active = 1 AND intranet_id = " . $this->procurement->kernel->intranet->get("id") . " AND procurement_id = " . $this->procurement->get("id") . " ORDER BY id ASC");
406
        $i = 0;
407
        $item = array ();
408
409
        if ($this->procurement->get("price_items") > 0) {
410
            // calculates shipment etc per item price kr
411
            $calculated = $this->procurement->get("price_shipment_etc") / $this->procurement->get("price_items");
412
        } else {
413
            $calculated = 0;
414
        }
415
416
        while ($db->nextRecord()) {
417
            $product = new Product($this->procurement->kernel, $db->f("product_id"), $db->f("product_detail_id"));
418
            $item[$i]["id"] = $db->f("id");
419
420
            $unit = $product->get("unit");
421 View Code Duplication
            if ($db->f("quantity") == 1) {
422
                $item[$i]["unit"] = $unit['singular'];
423
            } else {
424
                $item[$i]["unit"] = $unit['plural'];
425
            }
426
            $item[$i]["unit_purchase_price"] = $db->f("unit_purchase_price");
427
            $item[$i]["calculated_unit_price"] = $db->f("unit_purchase_price") + $db->f("unit_purchase_price") * $calculated;
428
            $item[$i]["quantity"] = $db->f("quantity");
429
            $item[$i]["vat"] = $product->get("vat");
430
            $item[$i]["product_id"] = $product->get("id");
431
            $item[$i]["amount"] = $db->f("quantity") * $db->f("unit_purchase_price");
432
433
            if ($product->get('has_variation')) {
434
                $variation = $product->getVariation($db->f('product_variation_id'));
435
                $detail = $variation->getDetail($db->f('product_variation_detail_id'));
436
                $item[$i]["name"] = $product->get("name").' - '.$variation->getName();
437
                $item[$i]["number"]= $product->get("number").'.'.$variation->getNumber();
438
                $item[$i]["price"] = $detail->getPrice($product);
439
            } else {
440
                $item[$i]["name"] = $product->get("name");
441
                $item[$i]["number"] = $product->get("number");
442
                $item[$i]["price"] = $product->getDetails()->getPrice();
443
            }
444
            $i++;
445
        }
446
        return $item;
447
    }
448
449
    /**
450
     * Returns the quantity of a given product used
451
     */
452 1
    public function getQuantity($status, $product_id, $product_variation_id, $from_date = "")
453
    {
454 1
        if (!in_array($status, array (
455 1
                'ordered',
456
                'delivered'
457 1
            ))) {
458
            throw new Exception("Ugyldig status", FATAL);
459
        }
460
461 1
        $db = new DB_sql;
462
463 1
        if ($status == "ordered") {
464 1
            $db->query("SELECT SUM(quantity) AS on_order
465
                        FROM procurement_item INNER JOIN procurement
466
                            ON procurement_item.procurement_id = procurement.id
467
                        WHERE procurement_item.active = 1 AND procurement.active = 1
468 1
                            AND procurement_item.intranet_id = " . $this->procurement->kernel->intranet->get("id") . " AND procurement.intranet_id = " . $this->procurement->kernel->intranet->get("id") . "
469 1
                            AND procurement_item.product_id = " . $product_id . " AND procurement.status_key = 0
470 1
                            AND procurement_item.product_variation_id = ".$product_variation_id);
471 1
            $db->nextRecord(); // a post will always be present
472 1
            return intval($db->f("on_order"));
473
        } else {
474
            // delivered
475 1
            $db->query("SELECT SUM(quantity) AS stock_in
476
                        FROM procurement_item INNER JOIN procurement
477
                            ON procurement_item.procurement_id = procurement.id
478
                        WHERE procurement_item.active = 1 AND procurement.active = 1
479 1
                            AND procurement_item.intranet_id = " . $this->procurement->kernel->intranet->get("id") . " AND procurement.intranet_id = " . $this->procurement->kernel->intranet->get("id") . "
480 1
                            AND procurement_item.product_id = " . $product_id . "
481 1
                            AND procurement_item.product_variation_id = ".$product_variation_id."
482
                            AND procurement.status_key = 1
483 1
                            AND procurement.date_recieved > \"" . $from_date . "\"");
484 1
            $db->nextRecord(); // a post will always be present
485 1
            return intval($db->f("stock_in"));
486
        }
487
    }
488
}
489