102 lines
3.1 KiB
PHP
102 lines
3.1 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\DTOs\Production;
|
||
|
|
|
||
|
|
use InvalidArgumentException;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* dynamic_bom JSON 항목 DTO
|
||
|
|
*
|
||
|
|
* work_order_items.options.dynamic_bom 배열의 각 엔트리를 표현
|
||
|
|
*/
|
||
|
|
class DynamicBomEntry
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
public readonly int $child_item_id,
|
||
|
|
public readonly string $child_item_code,
|
||
|
|
public readonly string $lot_prefix,
|
||
|
|
public readonly string $part_type,
|
||
|
|
public readonly string $category,
|
||
|
|
public readonly string $material_type,
|
||
|
|
public readonly int $length_mm,
|
||
|
|
public readonly int|float $qty,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 배열에서 DTO 생성
|
||
|
|
*/
|
||
|
|
public static function fromArray(array $data): self
|
||
|
|
{
|
||
|
|
self::validate($data);
|
||
|
|
|
||
|
|
return new self(
|
||
|
|
child_item_id: (int) $data['child_item_id'],
|
||
|
|
child_item_code: (string) $data['child_item_code'],
|
||
|
|
lot_prefix: (string) $data['lot_prefix'],
|
||
|
|
part_type: (string) $data['part_type'],
|
||
|
|
category: (string) $data['category'],
|
||
|
|
material_type: (string) $data['material_type'],
|
||
|
|
length_mm: (int) $data['length_mm'],
|
||
|
|
qty: $data['qty'],
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DTO → 배열 변환 (JSON 저장용)
|
||
|
|
*/
|
||
|
|
public function toArray(): array
|
||
|
|
{
|
||
|
|
return [
|
||
|
|
'child_item_id' => $this->child_item_id,
|
||
|
|
'child_item_code' => $this->child_item_code,
|
||
|
|
'lot_prefix' => $this->lot_prefix,
|
||
|
|
'part_type' => $this->part_type,
|
||
|
|
'category' => $this->category,
|
||
|
|
'material_type' => $this->material_type,
|
||
|
|
'length_mm' => $this->length_mm,
|
||
|
|
'qty' => $this->qty,
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 필수 필드 검증
|
||
|
|
*
|
||
|
|
* @throws InvalidArgumentException
|
||
|
|
*/
|
||
|
|
public static function validate(array $data): bool
|
||
|
|
{
|
||
|
|
$required = ['child_item_id', 'child_item_code', 'lot_prefix', 'part_type', 'category', 'material_type', 'length_mm', 'qty'];
|
||
|
|
|
||
|
|
foreach ($required as $field) {
|
||
|
|
if (! array_key_exists($field, $data) || $data[$field] === null) {
|
||
|
|
throw new InvalidArgumentException("DynamicBomEntry: '{$field}' is required");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((int) $data['child_item_id'] <= 0) {
|
||
|
|
throw new InvalidArgumentException('DynamicBomEntry: child_item_id must be positive');
|
||
|
|
}
|
||
|
|
|
||
|
|
$validCategories = ['guideRail', 'bottomBar', 'shutterBox', 'smokeBarrier'];
|
||
|
|
if (! in_array($data['category'], $validCategories, true)) {
|
||
|
|
throw new InvalidArgumentException('DynamicBomEntry: category must be one of: '.implode(', ', $validCategories));
|
||
|
|
}
|
||
|
|
|
||
|
|
if ($data['qty'] <= 0) {
|
||
|
|
throw new InvalidArgumentException('DynamicBomEntry: qty must be positive');
|
||
|
|
}
|
||
|
|
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* DynamicBomEntry 배열 → JSON 저장용 배열 변환
|
||
|
|
*
|
||
|
|
* @param DynamicBomEntry[] $entries
|
||
|
|
*/
|
||
|
|
public static function toArrayList(array $entries): array
|
||
|
|
{
|
||
|
|
return array_map(fn (self $e) => $e->toArray(), $entries);
|
||
|
|
}
|
||
|
|
}
|