feat(API): 부실채권, 재고, 입고 기능 개선

- BadDebt 컨트롤러/서비스 기능 확장
- StockService 재고 조회 로직 개선
- ProcessReceivingRequest 검증 규칙 수정
- Item, Order, CommonCode, Shipment 모델 업데이트
- TodayIssueObserverService 개선

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-23 21:32:23 +09:00
parent 5104a6641c
commit 09db0da43b
10 changed files with 282 additions and 73 deletions

View File

@@ -85,6 +85,14 @@ public function details()
return $this->hasOne(ItemDetail::class);
}
/**
* 재고 정보 (1:1)
*/
public function stock()
{
return $this->hasOne(\App\Models\Tenants\Stock::class);
}
/**
* 카테고리
*/
@@ -130,26 +138,29 @@ public function tags()
/**
* 특정 타입 필터
* join 시 ambiguous 에러 방지를 위해 테이블 prefix 사용
*/
public function scopeType($query, string $type)
{
return $query->where('item_type', strtoupper($type));
return $query->where('items.item_type', strtoupper($type));
}
/**
* Products 타입만 (FG, PT)
* join 시 ambiguous 에러 방지를 위해 테이블 prefix 사용
*/
public function scopeProducts($query)
{
return $query->whereIn('item_type', self::PRODUCT_TYPES);
return $query->whereIn('items.item_type', self::PRODUCT_TYPES);
}
/**
* Materials 타입만 (SM, RM, CS)
* join 시 ambiguous 에러 방지를 위해 테이블 prefix 사용
*/
public function scopeMaterials($query)
{
return $query->whereIn('item_type', self::MATERIAL_TYPES);
return $query->whereIn('items.item_type', self::MATERIAL_TYPES);
}
/**

View File

@@ -4,6 +4,7 @@
use App\Models\Items\Item;
use App\Models\Production\WorkOrder;
use App\Models\Products\CommonCode;
use App\Models\Quote\Quote;
use App\Models\Tenants\Sale;
use App\Models\Tenants\Shipment;
@@ -144,6 +145,13 @@ class Order extends Model
'deleted_at' => 'datetime',
];
/**
* JSON 응답에 자동 포함할 accessor
*/
protected $appends = [
'delivery_method_label',
];
/**
* 수주 상세 품목
*/
@@ -240,6 +248,14 @@ public function getSalesRecognitionLabelAttribute(): string
return self::SALES_RECOGNITION_TYPES[$this->sales_recognition] ?? '출하완료 시';
}
/**
* 배송방식 라벨 (common_codes 테이블에서 조회)
*/
public function getDeliveryMethodLabelAttribute(): string
{
return CommonCode::getLabel('delivery_method', $this->delivery_method_code);
}
/**
* 수주확정 시 매출 생성 여부
*/

View File

@@ -44,4 +44,42 @@ public function children()
{
return $this->hasMany(self::class, 'parent_id');
}
/**
* 코드 그룹과 코드로 라벨(name) 조회
*
* @param string $codeGroup 코드 그룹 (예: 'delivery_method')
* @param string|null $code 코드값 (예: 'direct')
* @return string 라벨 (없으면 코드값 반환)
*/
public static function getLabel(string $codeGroup, ?string $code): string
{
if (empty($code)) {
return '';
}
$commonCode = static::withoutGlobalScopes()
->where('code_group', $codeGroup)
->where('code', $code)
->where('is_active', true)
->first();
return $commonCode?->name ?? $code;
}
/**
* 코드 그룹의 전체 코드 목록 조회 (code => name 배열)
*
* @param string $codeGroup 코드 그룹
* @return array<string, string> [code => name] 형태의 배열
*/
public static function getCodeMap(string $codeGroup): array
{
return static::withoutGlobalScopes()
->where('code_group', $codeGroup)
->where('is_active', true)
->orderBy('sort_order')
->pluck('name', 'code')
->toArray();
}
}

View File

@@ -4,6 +4,7 @@
use App\Models\Orders\Order;
use App\Models\Production\WorkOrder;
use App\Models\Products\CommonCode;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
@@ -77,6 +78,7 @@ class Shipment extends Model
*/
protected $appends = [
'order_info',
'delivery_method_label',
];
/**
@@ -172,11 +174,11 @@ public function getPriorityLabelAttribute(): string
}
/**
* 배송방식 라벨
* 배송방식 라벨 (common_codes 테이블에서 조회)
*/
public function getDeliveryMethodLabelAttribute(): string
{
return self::DELIVERY_METHODS[$this->delivery_method] ?? $this->delivery_method;
return CommonCode::getLabel('delivery_method', $this->delivery_method);
}
/**