1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26class OrderStateCore extends ObjectModel
27{
28    /** @var array<string> Name */
29    public $name;
30
31    /** @var array<string> Template name if there is any e-mail to send */
32    public $template;
33
34    /** @var bool Send an e-mail to customer ? */
35    public $send_email;
36
37    public $module_name;
38
39    /** @var bool Allow customer to view and download invoice when order is at this state */
40    public $invoice;
41
42    /** @var string Display state in the specified color */
43    public $color;
44
45    public $unremovable;
46
47    /** @var bool Log authorization */
48    public $logable;
49
50    /** @var bool Delivery */
51    public $delivery;
52
53    /** @var bool Hidden */
54    public $hidden;
55
56    /** @var bool Shipped */
57    public $shipped;
58
59    /** @var bool Paid */
60    public $paid;
61
62    /** @var bool Attach PDF Invoice */
63    public $pdf_invoice;
64
65    /** @var bool Attach PDF Delivery Slip */
66    public $pdf_delivery;
67
68    /** @var bool True if carrier has been deleted (staying in database as deleted) */
69    public $deleted = 0;
70
71    /**
72     * @see ObjectModel::$definition
73     */
74    public static $definition = [
75        'table' => 'order_state',
76        'primary' => 'id_order_state',
77        'multilang' => true,
78        'fields' => [
79            'send_email' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
80            'module_name' => ['type' => self::TYPE_STRING, 'validate' => 'isModuleName'],
81            'invoice' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
82            'color' => ['type' => self::TYPE_STRING, 'validate' => 'isColor'],
83            'logable' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
84            'shipped' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
85            'unremovable' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
86            'delivery' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
87            'hidden' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
88            'paid' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
89            'pdf_delivery' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
90            'pdf_invoice' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
91            'deleted' => ['type' => self::TYPE_BOOL, 'validate' => 'isBool'],
92
93            /* Lang fields */
94            'name' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isGenericName', 'required' => true, 'size' => 64],
95            'template' => ['type' => self::TYPE_STRING, 'lang' => true, 'validate' => 'isTplName', 'size' => 64],
96        ],
97    ];
98
99    protected $webserviceParameters = [
100        'fields' => [
101            'unremovable' => [],
102            'delivery' => [],
103            'hidden' => [],
104        ],
105    ];
106
107    const FLAG_NO_HIDDEN = 1;  /* 00001 */
108    const FLAG_LOGABLE = 2;  /* 00010 */
109    const FLAG_DELIVERY = 4;  /* 00100 */
110    const FLAG_SHIPPED = 8;  /* 01000 */
111    const FLAG_PAID = 16; /* 10000 */
112
113    /**
114     * Get all available order statuses.
115     *
116     * @param int $id_lang Language id for status name
117     * @param bool $getDeletedStates
118     *
119     * @return array Order statuses
120     */
121    public static function getOrderStates($id_lang, $filterDeleted = true)
122    {
123        $deletedStates = $filterDeleted ? ' WHERE deleted = 0' : '';
124        $cache_id = 'OrderState::getOrderStates_' . (int) $id_lang;
125        $cache_id .= $filterDeleted ? '_filterDeleted' : '';
126
127        if (!Cache::isStored($cache_id)) {
128            $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->executeS('
129            SELECT *
130            FROM `' . _DB_PREFIX_ . 'order_state` os
131            LEFT JOIN `' . _DB_PREFIX_ . 'order_state_lang` osl ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = ' . (int) $id_lang . ')'
132            . $deletedStates . ' ORDER BY `name` ASC');
133            Cache::store($cache_id, $result);
134
135            return $result;
136        }
137
138        return Cache::retrieve($cache_id);
139    }
140
141    /**
142     * Check if we can make a invoice when order is in this state.
143     *
144     * @param int $id_order_state State ID
145     *
146     * @return bool availability
147     */
148    public static function invoiceAvailable($id_order_state)
149    {
150        $result = false;
151        if (Configuration::get('PS_INVOICE')) {
152            $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue('
153            SELECT `invoice`
154            FROM `' . _DB_PREFIX_ . 'order_state`
155            WHERE `id_order_state` = ' . (int) $id_order_state);
156        }
157
158        return (bool) $result;
159    }
160
161    public function isRemovable()
162    {
163        return !($this->unremovable);
164    }
165
166    /**
167     * Check if a localized name in database for a specific lang (and excluding some IDs)
168     *
169     * @param string $name
170     * @param int $idLang
171     * @param int|null $excludeIdOrderState ID of the order state excluded for the search
172     *
173     * @return bool
174     */
175    public static function existsLocalizedNameInDatabase(string $name, int $idLang, ?int $excludeIdOrderState): bool
176    {
177        return (bool) DB::getInstance(_PS_USE_SQL_SLAVE_)->getValue(
178            'SELECT COUNT(*) AS count' .
179            ' FROM ' . _DB_PREFIX_ . 'order_state_lang osl' .
180            ' INNER JOIN ' . _DB_PREFIX_ . 'order_state os ON (os.`id_order_state` = osl.`id_order_state` AND osl.`id_lang` = ' . $idLang . ')' .
181            ' WHERE osl.id_lang = ' . $idLang .
182            ' AND osl.name =  \'' . pSQL($name) . '\'' .
183            ' AND os.deleted = 0' .
184            ($excludeIdOrderState ? ' AND osl.id_order_state != ' . $excludeIdOrderState : '')
185        );
186    }
187}
188