feat:개소별 자재 투입 관리 API 추가

- work_order_material_inputs 테이블 신규 생성 (개소별 자재 투입 추적)
- 개소별 자재 조회/투입/이력/삭제/수정 API 5개 추가
- StockService.increaseToLot: LOT 수량 복원 메서드 추가
- WorkOrderService에 개소별 자재 투입 비즈니스 로직 구현
- WorkOrder, WorkOrderItem 모델에 materialInputs 관계 추가

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-13 03:41:35 +09:00
parent d730c2d91a
commit e4c53c7b17
9 changed files with 872 additions and 70 deletions

View File

@@ -213,6 +213,14 @@ public function documents(): MorphMany
return $this->morphMany(Document::class, 'linkable');
}
/**
* 개소별 자재 투입 이력
*/
public function materialInputs(): HasMany
{
return $this->hasMany(WorkOrderMaterialInput::class);
}
/**
* 출하 목록
*/

View File

@@ -8,6 +8,7 @@
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* 작업지시 품목 모델
@@ -81,6 +82,14 @@ public function sourceOrderItem(): BelongsTo
return $this->belongsTo(OrderItem::class, 'source_order_item_id');
}
/**
* 자재 투입 이력
*/
public function materialInputs(): HasMany
{
return $this->hasMany(WorkOrderMaterialInput::class);
}
// ──────────────────────────────────────────────────────────────
// 스코프
// ──────────────────────────────────────────────────────────────

View File

@@ -0,0 +1,103 @@
<?php
namespace App\Models\Production;
use App\Models\Items\Item;
use App\Models\Members\User;
use App\Models\Tenants\StockLot;
use App\Traits\Auditable;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* 개소별 자재 투입 이력 모델
*
* 작업지시 품목(개소)별 자재 투입을 추적
*/
class WorkOrderMaterialInput extends Model
{
use Auditable, BelongsToTenant;
protected $table = 'work_order_material_inputs';
protected $fillable = [
'tenant_id',
'work_order_id',
'work_order_item_id',
'stock_lot_id',
'item_id',
'qty',
'input_by',
'input_at',
];
protected $casts = [
'qty' => 'decimal:3',
'input_at' => 'datetime',
];
// ──────────────────────────────────────────────────────────────
// 관계
// ──────────────────────────────────────────────────────────────
/**
* 작업지시
*/
public function workOrder(): BelongsTo
{
return $this->belongsTo(WorkOrder::class);
}
/**
* 작업지시 품목 (개소)
*/
public function workOrderItem(): BelongsTo
{
return $this->belongsTo(WorkOrderItem::class);
}
/**
* 투입 로트
*/
public function stockLot(): BelongsTo
{
return $this->belongsTo(StockLot::class);
}
/**
* 자재 품목
*/
public function item(): BelongsTo
{
return $this->belongsTo(Item::class);
}
/**
* 투입자
*/
public function inputBy(): BelongsTo
{
return $this->belongsTo(User::class, 'input_by');
}
// ──────────────────────────────────────────────────────────────
// 스코프
// ──────────────────────────────────────────────────────────────
/**
* 특정 개소의 투입 이력
*/
public function scopeForItem($query, int $workOrderItemId)
{
return $query->where('work_order_item_id', $workOrderItemId);
}
/**
* 특정 자재의 투입 이력
*/
public function scopeForMaterial($query, int $itemId)
{
return $query->where('item_id', $itemId);
}
}