feat: 견적 단가 자동 적용 기능 추가

- 고객 그룹별 단가 조정 지원
- 견적 생성 시 자동 단가 조회
- 매출단가만 사용 (매입단가는 경고)
This commit is contained in:
2025-10-13 21:52:34 +09:00
parent be36073282
commit a6b06be61d
17 changed files with 3794 additions and 47 deletions

View File

@@ -2,6 +2,8 @@
namespace App\Models\Products;
use App\Models\Orders\ClientGroup;
use App\Traits\BelongsToTenant;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
@@ -10,6 +12,74 @@
*/
class PriceHistory extends Model
{
use SoftDeletes;
protected $fillable = ['tenant_id','item_type_code','item_id','price_type_code','price','started_at','ended_at'];
use BelongsToTenant, SoftDeletes;
protected $fillable = [
'tenant_id',
'item_type_code',
'item_id',
'price_type_code',
'client_group_id',
'price',
'started_at',
'ended_at',
'created_by',
'updated_by',
'deleted_by',
];
protected $casts = [
'price' => 'decimal:4',
'started_at' => 'date',
'ended_at' => 'date',
];
// ClientGroup 관계
public function clientGroup()
{
return $this->belongsTo(ClientGroup::class, 'client_group_id');
}
// Polymorphic 관계 (item_type_code에 따라 Product 또는 Material)
public function item()
{
if ($this->item_type_code === 'PRODUCT') {
return $this->belongsTo(Product::class, 'item_id');
} elseif ($this->item_type_code === 'MATERIAL') {
return $this->belongsTo(\App\Models\Materials\Material::class, 'item_id');
}
return null;
}
// 스코프
public function scopeForItem($query, string $itemType, int $itemId)
{
return $query->where('item_type_code', $itemType)
->where('item_id', $itemId);
}
public function scopeForClientGroup($query, ?int $clientGroupId)
{
return $query->where('client_group_id', $clientGroupId);
}
public function scopeValidAt($query, $date)
{
return $query->where('started_at', '<=', $date)
->where(function ($q) use ($date) {
$q->whereNull('ended_at')
->orWhere('ended_at', '>=', $date);
});
}
public function scopeSalePrice($query)
{
return $query->where('price_type_code', 'SALE');
}
public function scopePurchasePrice($query)
{
return $query->where('price_type_code', 'PURCHASE');
}
}