diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index 0d4d2dd..7c17250 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -275,11 +275,66 @@ public function updateStatus(int $id, string $status) // 상태 전환 규칙 검증 $this->validateStatusTransition($order->status_code, $status); - $order->status_code = $status; - $order->updated_by = $userId; - $order->save(); + return DB::transaction(function () use ($order, $status, $userId) { + $createdSale = null; - return $order->load(['client:id,name', 'items']); + // 수주확정 시 매출 자동 생성 (sales_recognition = on_order_confirm인 경우) + if ($status === Order::STATUS_CONFIRMED && $order->shouldCreateSaleOnConfirm()) { + $createdSale = $this->createSaleFromOrder($order, $userId); + $order->sale_id = $createdSale->id; + } + + $order->status_code = $status; + $order->updated_by = $userId; + $order->save(); + + $result = $order->load(['client:id,name', 'items']); + + // 매출이 생성된 경우 응답에 포함 + if ($createdSale) { + $result->setAttribute('created_sale', $createdSale); + } + + return $result; + }); + } + + /** + * 수주에서 매출 생성 + */ + private function createSaleFromOrder(Order $order, int $userId): Sale + { + $saleNumber = $this->generateSaleNumber($order->tenant_id); + + $sale = Sale::createFromOrder($order, $saleNumber); + $sale->created_by = $userId; + $sale->save(); + + return $sale; + } + + /** + * 매출번호 자동 생성 + */ + private function generateSaleNumber(int $tenantId): string + { + $prefix = 'SAL'; + $yearMonth = now()->format('Ym'); + + // 해당 월 기준 마지막 번호 조회 + $lastNo = Sale::withoutGlobalScopes() + ->where('tenant_id', $tenantId) + ->where('sale_number', 'like', "{$prefix}-{$yearMonth}-%") + ->orderByDesc('sale_number') + ->value('sale_number'); + + if ($lastNo) { + $seq = (int) substr($lastNo, -4) + 1; + } else { + $seq = 1; + } + + return sprintf('%s-%s-%04d', $prefix, $yearMonth, $seq); } /**