|null $items */ public function createJob( AdminUser $admin, Request $request, string $reconcileType, ?Carbon $periodStart, ?Carbon $periodEnd, ?array $items, ): ReconcileJob { return DB::transaction(function () use ($admin, $request, $reconcileType, $periodStart, $periodEnd, $items): ReconcileJob { $jobNo = 'REC'.now()->format('YmdHis').strtoupper(Str::random(4)); $job = ReconcileJob::query()->create([ 'job_no' => $jobNo, 'admin_user_id' => (int) $admin->getKey(), 'reconcile_type' => $reconcileType, 'status' => 'completed', 'period_start' => $periodStart, 'period_end' => $periodEnd, 'summary_json' => null, 'finished_at' => now(), ]); $mismatch = 0; foreach ($items ?? [] as $row) { ReconcileItem::query()->create([ 'reconcile_job_id' => (int) $job->getKey(), 'side_a_ref' => $row['side_a_ref'] ?? null, 'side_b_ref' => $row['side_b_ref'] ?? null, 'difference_amount' => (int) ($row['difference_amount'] ?? 0), 'status' => (string) ($row['status'] ?? 'mismatch'), 'resolved_at' => null, ]); if (($row['status'] ?? 'mismatch') === 'mismatch') { $mismatch++; } } $job->forceFill([ 'summary_json' => [ 'item_count' => count($items ?? []), 'mismatch_count' => $mismatch, ], ])->save(); AuditLogger::recordForAdmin( $admin, $request, 'reconcile_jobs', 'create', 'reconcile_job', (string) $job->getKey(), null, [ 'job_no' => $jobNo, 'reconcile_type' => $reconcileType, 'item_count' => count($items ?? []), ], ); return $job->fresh(); }); } }