Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
userbudgetpool.php
1<?php
3
7
8Loc::loadMessages(__FILE__);
9
11{
12 private const STATUS_LOCKED_NOW = 1;
13 private const STATUS_LOCKED_EARLIER = -1;
14 private const STATUS_NOT_LOCKED = 0;
15
16 private $statusLock = self::STATUS_NOT_LOCKED;
17 private $userId;
18
19 protected static $userBudgetPool = [];
20
21 protected $items = [];
22
23 const BUDGET_TYPE_ORDER_CANCEL_PART = 'ORDER_CANCEL_PART';
24 const BUDGET_TYPE_ORDER_UNPAY = 'ORDER_UNPAY';
25 const BUDGET_TYPE_ORDER_PART_RETURN = 'ORDER_PART_RETURN';
26 const BUDGET_TYPE_OUT_CHARGE_OFF = 'OUT_CHARGE_OFF';
27 const BUDGET_TYPE_EXCESS_SUM_PAID = 'EXCESS_SUM_PAID';
28 const BUDGET_TYPE_MANUAL = 'MANUAL';
29 const BUDGET_TYPE_ORDER_PAY = 'ORDER_PAY';
30 const BUDGET_TYPE_ORDER_PAY_PART = 'ORDER_PAY_PART';
31
32 protected function __construct($userId)
33 {
34 $this->userId = $userId;
35 }
36
44 public function add($sum, $budgetType, Sale\Order $order, Sale\Payment $payment = null)
45 {
46 if (!$this->isLocked())
47 {
48 $this->lock();
49 }
50
51 if ($this->isStatusLockEarlier())
52 {
53 return;
54 }
55
56 $fields = [
57 "SUM" => $sum,
58 "CURRENCY" => $order->getCurrency(),
59 "TYPE" => $budgetType,
60 "ORDER" => $order,
61 ];
62
63 if ($payment !== null)
64 {
65 $fields['PAYMENT'] = $payment;
66 }
67
68 $this->items[] = $fields;
69
70 }
71
75 protected function lock()
76 {
77 if ($this->statusLock === self::STATUS_NOT_LOCKED)
78 {
79 $connection = Main\Application::getConnection();
80 $name = $connection->getSqlHelper()->forSql($this->getUniqLockName());
81 $dbRes = $connection->query("SELECT GET_LOCK('{$name}', 0) as L");
82 $result = $dbRes->fetch();
83 if ($result['L'] === '0')
84 {
85 $this->statusLock = self::STATUS_LOCKED_EARLIER;
86
87 return;
88 }
89
90 $this->statusLock = self::STATUS_LOCKED_NOW;
91 }
92 }
93
94 private function getUniqLockName() : string
95 {
96 return "user_budget_{$this->userId}";
97 }
98
103 protected function unlock()
104 {
105 if ($this->statusLock === self::STATUS_LOCKED_NOW)
106 {
107 $connection = Main\Application::getConnection();
108 $name = $connection->getSqlHelper()->forSql($this->getUniqLockName());
109 $connection->query("SELECT RELEASE_LOCK('{$name}')");
110
111 $this->statusLock = self::STATUS_NOT_LOCKED;
112 }
113 }
114
115 protected function isLocked()
116 {
117 return
118 $this->statusLock === self::STATUS_LOCKED_EARLIER
119 || $this->statusLock === self::STATUS_LOCKED_NOW
120 ;
121 }
122
123 protected function isStatusLockEarlier()
124 {
125 return $this->statusLock === self::STATUS_LOCKED_EARLIER;
126 }
127
131 public function get()
132 {
133 if (isset($this->items))
134 {
135 return $this->items;
136 }
137
138 return false;
139 }
140
146 public function delete($index)
147 {
148 if (isset($this->items) && isset($this->items[$index]))
149 {
150 unset($this->items[$index]);
151 if (count($this->items) === 0)
152 {
153 $this->unlock();
154 }
155
156 return true;
157 }
158
159 return false;
160 }
161
166 public static function getUserBudgetPool($userId)
167 {
168 if (!isset(static::$userBudgetPool[$userId]))
169 {
170 static::$userBudgetPool[$userId] = new static($userId);
171 }
172
173 return static::$userBudgetPool[$userId];
174 }
175
183 public static function addPoolItem(Sale\Order $order, $value, $type, Sale\Payment $payment = null)
184 {
185 if (floatval($value) == 0)
186 return;
187
188 $userId = $order->getUserId();
189 $pool = static::getUserBudgetPool($userId);
190 $pool->add($value, $type, $order, $payment);
191 }
192
197 public static function onUserBudgetSave($userId)
198 {
199 $result = new Sale\Result();
200
201 $pool = static::getUserBudgetPool($userId);
202
203 if ($pool->isStatusLockEarlier())
204 {
205 return $result->addError(
206 new Sale\ResultError(
207 Loc::getMessage('SALE_PROVIDER_USER_BUDGET_LOCKED')
208 )
209 );
210 }
211
212 foreach ($pool->get() as $key => $budgetDat)
213 {
214 $orderId = null;
215 $paymentId = null;
216
217 if (isset($budgetDat['ORDER'])
218 && ($budgetDat['ORDER'] instanceof Sale\OrderBase))
219 {
220 $orderId = $budgetDat['ORDER']->getId();
221 }
222
223 if (isset($budgetDat['PAYMENT'])
224 && ($budgetDat['PAYMENT'] instanceof Sale\Payment))
225 {
226 $paymentId = $budgetDat['PAYMENT']->getId();
227 }
228
229 if (!\CSaleUserAccount::UpdateAccount($userId, $budgetDat['SUM'], $budgetDat['CURRENCY'], $budgetDat['TYPE'], $orderId, '', $paymentId))
230 {
231 $result->addError( new Sale\ResultError(Loc::getMessage("SALE_PROVIDER_USER_BUDGET_".$budgetDat['TYPE']."_ERROR"), "SALE_PROVIDER_USER_BUDGET_".$budgetDat['TYPE']."_ERROR") );
232 }
233
234 $pool->delete($key);
235 }
236
237 return $result;
238 }
239
244 public static function getUserBudgetTransForOrder(Sale\Order $order)
245 {
246 $ignoreTypes = array(
247 static::BUDGET_TYPE_ORDER_PAY
248 );
249 $sumTrans = 0;
250
251 if ($order->getId() > 0)
252 {
253 $resTrans = \CSaleUserTransact::GetList(
254 array("TRANSACT_DATE" => "DESC"),
255 array(
256 "ORDER_ID" => $order->getId(),
257 ),
258 false,
259 false,
260 array("AMOUNT", "CURRENCY", "DEBIT")
261 );
262 while ($transactDat = $resTrans->Fetch())
263 {
264 if ($transactDat['DEBIT'] == "Y")
265 {
266 $sumTrans += $transactDat['AMOUNT'];
267 }
268 else
269 {
270 $sumTrans -= $transactDat['AMOUNT'];
271 }
272 }
273 }
274
275 if ($userBudgetPool = static::getUserBudgetPool($order->getUserId()))
276 {
277 foreach ($userBudgetPool->get() as $userBudgetDat)
278 {
279 if (in_array($userBudgetDat['TYPE'], $ignoreTypes))
280 continue;
281
282 $sumTrans += $userBudgetDat['SUM'];
283 }
284 }
285
286 return $sumTrans;
287 }
288
293 public static function getUserBudgetByOrder(Sale\Order $order)
294 {
295 $budget = static::getUserBudget($order->getUserId(), $order->getCurrency());
296 if ($userBudgetPool = static::getUserBudgetPool($order->getUserId()))
297 {
298 foreach ($userBudgetPool->get() as $userBudgetDat)
299 {
300 $budget += $userBudgetDat['SUM'];
301 }
302 }
303
304 return $budget;
305 }
306
312 public static function getUserBudget($userId, $currency)
313 {
314 $budget = null;
315 if ($userAccount = \CSaleUserAccount::GetByUserId($userId, $currency))
316 {
317 if ($userAccount['LOCKED'] != 'Y')
318 $budget = floatval($userAccount['CURRENT_BUDGET']);
319 }
320
321 return $budget;
322 }
323
324 public function __destruct()
325 {
326 $this->unlock();
327 }
328}
static loadMessages($file)
Definition loc.php:64
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
add($sum, $budgetType, Sale\Order $order, Sale\Payment $payment=null)
static getUserBudget($userId, $currency)
static getUserBudgetByOrder(Sale\Order $order)
static getUserBudgetTransForOrder(Sale\Order $order)
static addPoolItem(Sale\Order $order, $value, $type, Sale\Payment $payment=null)