utc(); $drawLocal = $this->parseInTimezone((string) $input['draw_time'], $tz); $startLocal = isset($input['start_time']) && $input['start_time'] !== null && $input['start_time'] !== '' ? $this->parseInTimezone((string) $input['start_time'], $tz) : null; $closeLocal = isset($input['close_time']) && $input['close_time'] !== null && $input['close_time'] !== '' ? $this->parseInTimezone((string) $input['close_time'], $tz) : null; if ($startLocal === null || $closeLocal === null) { $defaults = $this->timeline->windowsFromDrawLocal($drawLocal); $startLocal ??= $defaults['start_local']; $closeLocal ??= $defaults['close_local']; } if (! $startLocal->lt($closeLocal) || ! $closeLocal->lt($drawLocal)) { throw new \RuntimeException('draw_timeline_invalid'); } $businessDate = isset($input['business_date']) && $input['business_date'] !== '' ? (string) $input['business_date'] : $drawLocal->format('Y-m-d'); $sequenceNo = isset($input['sequence_no']) && $input['sequence_no'] !== null ? max(1, (int) $input['sequence_no']) : $this->nextSequenceForDate($businessDate); $drawNo = isset($input['draw_no']) && trim((string) $input['draw_no']) !== '' ? trim((string) $input['draw_no']) : $this->timeline->drawNo($businessDate, $sequenceNo); if (Draw::query()->where('draw_no', $drawNo)->exists()) { throw new \RuntimeException('draw_no_exists'); } $built = $this->timeline->buildFromLocals($startLocal, $closeLocal, $drawLocal, $nowUtc); return DB::transaction(function () use ( $drawNo, $businessDate, $sequenceNo, $built, ): Draw { return Draw::query()->create([ 'draw_no' => $drawNo, 'business_date' => $businessDate, 'sequence_no' => $sequenceNo, 'status' => $built['status'], 'start_time' => $built['start_utc'], 'close_time' => $built['close_utc'], 'draw_time' => $built['draw_utc'], 'cooling_end_time' => null, 'result_source' => null, 'current_result_version' => 0, 'settle_version' => 0, 'is_reopened' => false, ]); }); } private function parseInTimezone(string $value, string $tz): Carbon { return Carbon::parse($value, $tz); } private function nextSequenceForDate(string $businessDate): int { $max = (int) Draw::query() ->where('business_date', $businessDate) ->max('sequence_no'); return $max + 1; } }