feat:테넌트설정 API 및 다수 서비스 개선
- TenantSetting CRUD API 추가 - Calendar, Entertainment, VAT 서비스 개선 - 5130 BOM 계산 로직 수정 - quote_items에 item_type 컬럼 추가 - tenant_settings 테이블 마이그레이션 - Swagger 문서 업데이트
This commit is contained in:
@@ -201,11 +201,31 @@ public function update(int $id, array $data)
|
||||
|
||||
// 품목 교체 (있는 경우)
|
||||
if ($items !== null) {
|
||||
// 기존 품목의 floor_code/symbol_code 매핑 저장 (item_name + specification → floor_code/symbol_code)
|
||||
$existingMappings = [];
|
||||
foreach ($order->items as $existingItem) {
|
||||
$key = ($existingItem->item_name ?? '').'|'.($existingItem->specification ?? '');
|
||||
$existingMappings[$key] = [
|
||||
'floor_code' => $existingItem->floor_code,
|
||||
'symbol_code' => $existingItem->symbol_code,
|
||||
];
|
||||
}
|
||||
|
||||
$order->items()->delete();
|
||||
foreach ($items as $index => $item) {
|
||||
$item['tenant_id'] = $tenantId;
|
||||
$item['serial_no'] = $index + 1; // 1부터 시작하는 순번
|
||||
$item['sort_order'] = $index;
|
||||
|
||||
// floor_code/symbol_code 보존: 프론트엔드에서 전달되지 않으면 기존 값 사용
|
||||
if (empty($item['floor_code']) || empty($item['symbol_code'])) {
|
||||
$key = ($item['item_name'] ?? '').'|'.($item['specification'] ?? '');
|
||||
if (isset($existingMappings[$key])) {
|
||||
$item['floor_code'] = $item['floor_code'] ?? $existingMappings[$key]['floor_code'];
|
||||
$item['symbol_code'] = $item['symbol_code'] ?? $existingMappings[$key]['symbol_code'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->calculateItemAmounts($item);
|
||||
$order->items()->create($item);
|
||||
}
|
||||
@@ -277,6 +297,7 @@ public function updateStatus(int $id, string $status)
|
||||
|
||||
return DB::transaction(function () use ($order, $status, $userId) {
|
||||
$createdSale = null;
|
||||
$previousStatus = $order->status_code;
|
||||
|
||||
// 수주확정 시 매출 자동 생성 (sales_recognition = on_order_confirm인 경우)
|
||||
if ($status === Order::STATUS_CONFIRMED && $order->shouldCreateSaleOnConfirm()) {
|
||||
@@ -284,6 +305,18 @@ public function updateStatus(int $id, string $status)
|
||||
$order->sale_id = $createdSale->id;
|
||||
}
|
||||
|
||||
// 🆕 수주확정 시 재고 예약
|
||||
if ($status === Order::STATUS_CONFIRMED && $previousStatus !== Order::STATUS_CONFIRMED) {
|
||||
$order->load('items');
|
||||
app(StockService::class)->reserveForOrder($order->items, $order->id);
|
||||
}
|
||||
|
||||
// 🆕 수주취소 시 재고 예약 해제
|
||||
if ($status === Order::STATUS_CANCELLED && $previousStatus === Order::STATUS_CONFIRMED) {
|
||||
$order->load('items');
|
||||
app(StockService::class)->releaseReservationForOrder($order->items, $order->id);
|
||||
}
|
||||
|
||||
$order->status_code = $status;
|
||||
$order->updated_by = $userId;
|
||||
$order->save();
|
||||
@@ -437,14 +470,45 @@ public function createFromQuote(int $quoteId, array $data = [])
|
||||
|
||||
$order->save();
|
||||
|
||||
// calculation_inputs에서 제품-부품 매핑 정보 추출
|
||||
$calculationInputs = $quote->calculation_inputs ?? [];
|
||||
$calcInputItems = $calculationInputs['items'] ?? [];
|
||||
|
||||
// 견적 품목을 수주 품목으로 변환
|
||||
foreach ($quote->items as $index => $quoteItem) {
|
||||
// calculation_inputs.items에서 해당 품목의 floor/code 정보 찾기
|
||||
// 1. item_index로 매칭 시도
|
||||
// 2. 없으면 배열 인덱스로 fallback
|
||||
$floorCode = null;
|
||||
$symbolCode = null;
|
||||
|
||||
$itemIndex = $quoteItem->item_index ?? null;
|
||||
if ($itemIndex !== null) {
|
||||
// item_index로 매칭
|
||||
foreach ($calcInputItems as $calcItem) {
|
||||
if (($calcItem['index'] ?? null) === $itemIndex) {
|
||||
$floorCode = $calcItem['floor'] ?? null;
|
||||
$symbolCode = $calcItem['code'] ?? null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// item_index로 못 찾으면 배열 인덱스로 fallback
|
||||
if ($floorCode === null && $symbolCode === null && isset($calcInputItems[$index])) {
|
||||
$floorCode = $calcInputItems[$index]['floor'] ?? null;
|
||||
$symbolCode = $calcInputItems[$index]['code'] ?? null;
|
||||
}
|
||||
|
||||
$order->items()->create([
|
||||
'tenant_id' => $tenantId,
|
||||
'serial_no' => $index + 1, // 1부터 시작하는 순번
|
||||
'item_id' => $quoteItem->item_id,
|
||||
'item_code' => $quoteItem->item_code,
|
||||
'item_name' => $quoteItem->item_name,
|
||||
'specification' => $quoteItem->specification,
|
||||
'floor_code' => $floorCode,
|
||||
'symbol_code' => $symbolCode,
|
||||
'quantity' => $quoteItem->calculated_quantity,
|
||||
'unit' => $quoteItem->unit,
|
||||
'unit_price' => $quoteItem->unit_price,
|
||||
|
||||
Reference in New Issue
Block a user