| 1234567891011121314151617181920212223242526272829303132 |
- <?php
- namespace App\Services;
- use App\Models\ActivityReward;
- use Illuminate\Support\Facades\DB;
- /** Preserve the monetary budget behavior for activities created before quotas. */
- class ActivityBudgetService
- {
- public static function award(ActivityReward $activity, $amount, callable $grant): bool
- {
- if (!is_numeric($amount) || !preg_match('/^\d{1,12}(\.\d{1,2})?$/', (string)$amount)
- || bccomp((string)$amount, '0', 2) <= 0) {
- return false;
- }
- return DB::transaction(function () use ($activity, $amount, $grant) {
- $locked = ActivityReward::where('id', $activity->id)->lockForUpdate()->first();
- if (!$locked) return false;
- if ((int)$locked->type === 2) {
- $grant();
- return true;
- }
- $used = bcadd((string)($locked->budget_used ?? '0'), (string)$amount, 2);
- if ($locked->budget !== null && bccomp($used, (string)$locked->budget, 2) > 0) return false;
- $grant();
- $locked->budget_used = $used;
- $locked->save();
- return true;
- });
- }
- }
|