fix: [quality,qms] 검사 목록·품목명 미노출 + 관련서류 공정 매핑 확대
This commit is contained in:
@@ -27,15 +27,13 @@ public function index(array $params): array
|
||||
'documentOrders.locations',
|
||||
'performanceReport',
|
||||
])
|
||||
->where('status', QualityDocument::STATUS_COMPLETED);
|
||||
->where('status', QualityDocument::STATUS_COMPLETED)
|
||||
->whereHas('performanceReport', fn ($pr) => $pr->where('confirmation_status', '!=', 'unconfirmed'));
|
||||
|
||||
// 연도 필터
|
||||
if (! empty($params['year'])) {
|
||||
$year = (int) $params['year'];
|
||||
$query->where(function ($q) use ($year) {
|
||||
$q->whereHas('performanceReport', fn ($pr) => $pr->where('year', $year))
|
||||
->orWhereDoesntHave('performanceReport');
|
||||
});
|
||||
$query->whereHas('performanceReport', fn ($pr) => $pr->where('year', $year));
|
||||
}
|
||||
|
||||
// 분기 필터
|
||||
@@ -246,8 +244,17 @@ private function transformReportToFrontend(QualityDocument $doc): array
|
||||
private function getFgProductName(QualityDocument $doc): string
|
||||
{
|
||||
$order = $doc->documentOrders->first()?->order;
|
||||
if (! $order) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $order?->item?->name ?? '';
|
||||
// 1차: Order.item 릴레이션
|
||||
if ($order->item?->name) {
|
||||
return $order->item->name;
|
||||
}
|
||||
|
||||
// 2차: Order.items (order_items 테이블)의 첫 번째 품목명
|
||||
return $order->items->first()?->item_name ?? '';
|
||||
}
|
||||
|
||||
private function transformRouteToFrontend(QualityDocumentOrder $docOrder, QualityDocument $qualityDoc): array
|
||||
@@ -400,7 +407,7 @@ private function mapProcessToSubType(?string $processName): ?string
|
||||
str_contains($name, 'bending') || str_contains($name, '절곡') => 'bending',
|
||||
str_contains($name, 'slat') || str_contains($name, '슬랫') => 'slat',
|
||||
str_contains($name, 'jointbar') || str_contains($name, '조인트바') || str_contains($name, 'joint') => 'jointbar',
|
||||
default => null,
|
||||
default => mb_strtolower(trim($processName)),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -489,7 +496,7 @@ private function getOrderDetail(int $id): array
|
||||
$motorRight = [];
|
||||
foreach ($motorItems->groupBy('item_name') as $name => $group) {
|
||||
$item = $group->first();
|
||||
$totalQty = $group->sum('quantity');
|
||||
$totalQty = (int) $group->sum('quantity');
|
||||
$row = [
|
||||
'item' => $item['item_name'],
|
||||
'type' => $item['specification'] ?? '-',
|
||||
@@ -506,7 +513,8 @@ private function getOrderDetail(int $id): array
|
||||
|
||||
// 절곡물 (category: steel)
|
||||
$steelItems = $allBomItems->filter(fn ($i) => ($i['item_category'] ?? '') === 'steel');
|
||||
$bendingParts = $this->groupBendingParts($steelItems);
|
||||
$shutterCount = $rootNodes->count();
|
||||
$bendingParts = $this->groupBendingParts($steelItems, $shutterCount);
|
||||
|
||||
// 부자재 (category: parts)
|
||||
$partItems = $allBomItems->filter(fn ($i) => ($i['item_category'] ?? '') === 'parts');
|
||||
@@ -516,7 +524,7 @@ private function getOrderDetail(int $id): array
|
||||
$subsidiaryParts[] = [
|
||||
'name' => $item['item_name'],
|
||||
'spec' => $item['specification'] ?? '-',
|
||||
'qty' => $group->sum('quantity'),
|
||||
'qty' => (int) $group->sum('quantity'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -558,8 +566,12 @@ private function getOrderDetail(int $id): array
|
||||
|
||||
/**
|
||||
* 절곡물 BOM items를 그룹별로 분류
|
||||
* 문서 표시용: 길이 기반 BOM 수량 → 개수(EA) 기반으로 변환
|
||||
* - 가이드레일: 2 × 셔터수량 (좌/우)
|
||||
* - 케이스: 셔터수량
|
||||
* - 마구리(측면부): 2 × 셔터수량 (좌/우)
|
||||
*/
|
||||
private function groupBendingParts($steelItems): array
|
||||
private function groupBendingParts($steelItems, int $shutterCount = 0): array
|
||||
{
|
||||
$groups = [
|
||||
'가이드레일' => [],
|
||||
@@ -572,17 +584,30 @@ private function groupBendingParts($steelItems): array
|
||||
foreach ($steelItems->groupBy('item_name') as $name => $group) {
|
||||
$item = $group->first();
|
||||
$totalQty = $group->sum('quantity');
|
||||
|
||||
// 개수(EA) 기반 수량 결정
|
||||
$isMaguri = str_contains($name, '마구리') || str_contains($name, '측면');
|
||||
$isGuideRail = str_contains($name, '가이드레일');
|
||||
$isCase = str_contains($name, '케이스') && ! $isMaguri;
|
||||
|
||||
if ($shutterCount > 0 && ($isGuideRail || $isCase || $isMaguri)) {
|
||||
// 가이드레일, 마구리: 2 × 셔터수량 / 케이스: 셔터수량
|
||||
$qty = ($isGuideRail || $isMaguri) ? 2 * $shutterCount : $shutterCount;
|
||||
} else {
|
||||
$qty = $totalQty;
|
||||
}
|
||||
|
||||
$row = [
|
||||
'name' => $item['item_name'],
|
||||
'spec' => $item['specification'] ?? '-',
|
||||
'qty' => $totalQty,
|
||||
'qty' => (int) $qty,
|
||||
];
|
||||
|
||||
if (str_contains($name, '연기차단재')) {
|
||||
$groups['연기차단재'][] = $row;
|
||||
} elseif (str_contains($name, '가이드레일')) {
|
||||
} elseif ($isGuideRail) {
|
||||
$groups['가이드레일'][] = $row;
|
||||
} elseif (str_contains($name, '케이스') || str_contains($name, '마구리')) {
|
||||
} elseif ($isCase || $isMaguri) {
|
||||
$groups['케이스'][] = $row;
|
||||
} elseif (str_contains($name, '하장바') || str_contains($name, 'L-BAR') || str_contains($name, '보강평철')) {
|
||||
$groups['하단마감'][] = $row;
|
||||
|
||||
@@ -192,6 +192,7 @@ public function store(array $data)
|
||||
$data['tenant_id'] = $tenantId;
|
||||
$data['quality_doc_number'] = QualityDocument::generateDocNumber($tenantId);
|
||||
$data['status'] = QualityDocument::STATUS_RECEIVED;
|
||||
$data['received_date'] = $data['received_date'] ?? now()->toDateString();
|
||||
$data['created_by'] = $userId;
|
||||
|
||||
$doc = QualityDocument::create($data);
|
||||
|
||||
Reference in New Issue
Block a user