| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- <?php
- declare(strict_types=1);
- namespace plugin\saiadmin\app\service;
- use plugin\saiadmin\app\model\water\WaterAccount;
- use plugin\saiadmin\app\model\water\WaterEnterprise;
- use plugin\saiadmin\app\model\water\WaterLedger;
- use plugin\saiadmin\app\model\water\WaterModel;
- use plugin\saiadmin\app\model\water\WaterOrder;
- use plugin\saiadmin\app\model\water\WaterSku;
- use plugin\saiadmin\app\service\agent\WaterCommissionAccrual;
- use plugin\saiadmin\exception\ApiException;
- /** Only server-side catalog data or a persisted checkout snapshot may reach this service. */
- final class WaterPurchaseReceipt
- {
- public function issue(int $enterpriseId, array $package, string $reference, int $actor, bool $balance = false, ?int $checkoutId = null): array
- {
- return WaterModel::transaction(function () use ($enterpriseId, $package, $reference, $actor, $balance, $checkoutId) {
- $sku = WaterSku::query()->where('id', $package['sku_id'])->lockForUpdate()->first();
- $enterprise = WaterEnterprise::query()->where('id', $enterpriseId)->lockForUpdate()->first();
- if (!$sku || !$enterprise || (int) $sku->status !== 1 || (int) $enterprise->status !== 1) {
- throw new ApiException('企业或商品规格已停用或不存在');
- }
- $values = [
- 'enterprise_id' => $enterpriseId,
- 'package_id' => (int) $package['id'],
- 'sku_id' => (int) $package['sku_id'],
- 'buckets' => (int) $package['buckets'],
- 'amount_cents' => (int) $package['price_cents'],
- 'package_name' => $package['name'],
- ];
- $existing = WaterOrder::query()->where('reference', $reference)->first();
- if ($existing) {
- foreach ($values as $field => $value) {
- if ((string) $existing->$field !== (string) $value) {
- throw new ApiException('该收款凭据已被其他订单使用');
- }
- }
- return ['id' => (int) $existing->id, 'replayed' => true];
- }
- $now = date('Y-m-d H:i:s');
- $account = WaterAccount::query()->where(['enterprise_id' => $enterpriseId, 'sku_id' => $sku->id])->lockForUpdate()->first();
- if (!$account) {
- $account = WaterAccount::query()->create(['enterprise_id' => $enterpriseId, 'sku_id' => $sku->id, 'updated_at' => $now]);
- $account->refresh();
- }
- $order = WaterOrder::query()->create($values + ['reference' => $reference, 'created_by' => $actor, 'created_at' => $now]);
- $account->entitlement = (int) $account->entitlement + $values['buckets'];
- $account->updated_at = $now;
- $account->save();
- WaterLedger::query()->create([
- 'kind' => 'purchase', 'created_by' => $actor, 'sku_id' => $sku->id,
- 'enterprise_id' => $enterpriseId, 'quantity' => $values['buckets'],
- 'amount_cents' => $values['amount_cents'], 'reference' => $reference,
- 'note' => $balance ? '企业余额支付,按订单快照登记套餐权益' : '已核实线下收款,登记套餐权益',
- 'created_at' => $now,
- ]);
- (new WaterCommissionAccrual())->record($order, $enterprise);
- (new \plugin\saiadmin\app\service\promotion\PromotionReferrals())->purchased($order, $checkoutId);
- return ['id' => (int) $order->id];
- });
- }
- }
|