feat: [order] 재고생산관리(STOCK) 타입 추가

- Order 모델에 TYPE_STOCK = 'STOCK' 상수 추가
- StoreOrderRequest/UpdateOrderRequest에 STOCK 타입 validation 추가
- options에 production_reason, target_stock_qty 필드 추가
- 재고생산 채번: STK{YYYYMMDD}{NNNN} 형식
- stats()에 order_type 필터 파라미터 추가
- STOCK 타입 확정 시 매출 자동 생성 스킵
This commit is contained in:
김보곤
2026-03-16 21:27:13 +09:00
parent a7f98ccdf5
commit 407afe38e4
5 changed files with 49 additions and 12 deletions

View File

@@ -109,17 +109,22 @@ public function index(array $params)
/**
* 통계 조회
*/
public function stats(): array
public function stats(?string $orderType = null): array
{
$tenantId = $this->tenantId();
$counts = Order::where('tenant_id', $tenantId)
$baseQuery = Order::where('tenant_id', $tenantId);
if ($orderType !== null) {
$baseQuery->where('order_type_code', $orderType);
}
$counts = (clone $baseQuery)
->select('status_code', DB::raw('count(*) as count'))
->groupBy('status_code')
->pluck('count', 'status_code')
->toArray();
$amounts = Order::where('tenant_id', $tenantId)
$amounts = (clone $baseQuery)
->select('status_code', DB::raw('sum(total_amount) as total'))
->groupBy('status_code')
->pluck('total', 'status_code')
@@ -162,10 +167,13 @@ public function store(array $data)
$userId = $this->apiUserId();
return DB::transaction(function () use ($data, $tenantId, $userId) {
// 수주번호 자동 생성
// 수주번호 자동 생성 (재고생산은 STK 접두사)
$pairCode = $data['pair_code'] ?? null;
unset($data['pair_code']);
$data['order_no'] = $this->generateOrderNo($tenantId, $pairCode);
$isStock = ($data['order_type_code'] ?? null) === Order::TYPE_STOCK;
$data['order_no'] = $isStock
? $this->generateStockOrderNo($tenantId)
: $this->generateOrderNo($tenantId, $pairCode);
$data['tenant_id'] = $tenantId;
$data['created_by'] = $userId;
$data['updated_by'] = $userId;
@@ -629,8 +637,8 @@ public function updateStatus(int $id, string $status)
$createdSale = null;
$previousStatus = $order->status_code;
// 수주확정 시 매출 자동 생성 (sales_recognition = on_order_confirm인 경우)
if ($status === Order::STATUS_CONFIRMED && $order->shouldCreateSaleOnConfirm()) {
// 수주확정 시 매출 자동 생성 (재고생산은 매출 생성 불필요)
if ($status === Order::STATUS_CONFIRMED && $order->order_type_code !== Order::TYPE_STOCK && $order->shouldCreateSaleOnConfirm()) {
$createdSale = $this->createSaleFromOrder($order, $userId);
$order->sale_id = $createdSale->id;
}
@@ -776,6 +784,29 @@ private function generateOrderNoLegacy(int $tenantId): string
return sprintf('%s%s%04d', $prefix, $date, $seq);
}
/**
* 재고생산 번호 생성 (STK{YYYYMMDD}{NNNN})
*/
private function generateStockOrderNo(int $tenantId): string
{
$prefix = 'STK';
$date = now()->format('Ymd');
$lastNo = Order::withoutGlobalScopes()
->where('tenant_id', $tenantId)
->where('order_no', 'like', "{$prefix}{$date}%")
->orderByDesc('order_no')
->value('order_no');
if ($lastNo) {
$seq = (int) substr($lastNo, -4) + 1;
} else {
$seq = 1;
}
return sprintf('%s%s%04d', $prefix, $date, $seq);
}
/**
* 견적에서 수주 생성
*/