2026_11_03_170000_repeat_loss_invite_rounds.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. <?php
  2. use App\Support\PromotionRules;
  3. use Illuminate\Database\Migrations\Migration;
  4. use Illuminate\Support\Facades\DB;
  5. return new class extends Migration {
  6. /**
  7. * Loss invite now repeats. Members who already claimed move to the next round, keeping their application on the reward;
  8. * coupon rewards record only the inviter's own coupons as the amount (budget_used already includes invitee coupons).
  9. */
  10. public function up(): void
  11. {
  12. $activities = DB::table('promotion_activities')->where('type', PromotionRules::LOSS)->pluck('id');
  13. if ($activities->isEmpty()) return;
  14. DB::transaction(function () use ($activities) {
  15. $now = date('Y-m-d H:i:s');
  16. $rewards = DB::table('promotion_rewards')->whereIn('activity_id', $activities)->lockForUpdate()->get();
  17. foreach ($rewards as $reward) {
  18. $rules = json_decode((string)$reward->rule_snapshot, true) ?: [];
  19. $update = [];
  20. $account = DB::table('promotion_accounts')->where('id', $reward->account_id)->lockForUpdate()->first();
  21. if ($account && (int)$account->round_no === (int)$reward->round_no) {
  22. $application = json_decode((string)$account->application_snapshot, true) ?: [];
  23. $rules['application'] ??= ['applied_at' => $account->applied_at] + array_diff_key($application, ['rules' => true]);
  24. DB::table('promotion_accounts')->where('id', $account->id)->update(['round_no' => (int)$account->round_no + 1,
  25. 'applied_at' => null, 'application_snapshot' => null, 'updated_at' => $now]);
  26. }
  27. if (($rules['reward_mode'] ?? 'cash') === 'coupon' && !isset($rules['coupon_face_value'])) {
  28. $rules['coupon_face_value'] = bcadd((string)$reward->amount, '0', 2);
  29. $update['amount'] = PromotionRules::faceValue($rules['inviter_coupons'] ?? []);
  30. }
  31. $update['rule_snapshot'] = json_encode($rules);
  32. DB::table('promotion_rewards')->where('id', $reward->id)->update($update + ['updated_at' => $now]);
  33. }
  34. });
  35. }
  36. public function down(): void
  37. {
  38. }
  39. };