'수주확정', self::SOURCE_SHIPMENT_COMPLETE => '출하완료', self::SOURCE_MANUAL => '수동등록', ]; protected $fillable = [ 'tenant_id', 'order_id', 'shipment_id', 'sale_number', 'sale_date', 'client_id', 'supply_amount', 'tax_amount', 'total_amount', 'description', 'status', 'source_type', 'account_code', 'tax_invoice_issued', 'transaction_statement_issued', 'tax_invoice_id', 'deposit_id', 'created_by', 'updated_by', 'deleted_by', ]; protected $casts = [ 'sale_date' => 'date:Y-m-d', 'supply_amount' => 'decimal:2', 'tax_amount' => 'decimal:2', 'total_amount' => 'decimal:2', 'client_id' => 'integer', 'order_id' => 'integer', 'shipment_id' => 'integer', 'tax_invoice_issued' => 'boolean', 'transaction_statement_issued' => 'boolean', 'tax_invoice_id' => 'integer', 'deposit_id' => 'integer', ]; /** * 상태 목록 */ public const STATUSES = [ 'draft' => '임시저장', 'confirmed' => '확정', 'invoiced' => '세금계산서발행', ]; /** * 수주 관계 */ public function order(): BelongsTo { return $this->belongsTo(Order::class); } /** * 출하 관계 */ public function shipment(): BelongsTo { return $this->belongsTo(Shipment::class); } /** * 거래처 관계 */ public function client(): BelongsTo { return $this->belongsTo(\App\Models\Orders\Client::class); } /** * 입금 관계 */ public function deposit(): BelongsTo { return $this->belongsTo(Deposit::class); } /** * 생성자 관계 */ public function creator(): BelongsTo { return $this->belongsTo(\App\Models\Members\User::class, 'created_by'); } /** * 상태 라벨 */ public function getStatusLabelAttribute(): string { return self::STATUSES[$this->status] ?? $this->status; } /** * 확정 가능 여부 */ public function canConfirm(): bool { return $this->status === 'draft'; } /** * 수정 가능 여부 */ public function canEdit(): bool { return $this->status === 'draft'; } /** * 삭제 가능 여부 */ public function canDelete(): bool { return $this->status === 'draft'; } /** * 생성 시점 라벨 */ public function getSourceTypeLabelAttribute(): string { return self::SOURCE_TYPES[$this->source_type] ?? $this->source_type ?? '수동등록'; } /** * 수주에서 매출 생성 */ public static function createFromOrder(Order $order, string $saleNumber): self { return new self([ 'tenant_id' => $order->tenant_id, 'order_id' => $order->id, 'sale_number' => $saleNumber, 'sale_date' => now()->toDateString(), 'client_id' => $order->client_id, 'supply_amount' => $order->supply_amount, 'tax_amount' => $order->tax_amount, 'total_amount' => $order->total_amount, 'description' => "수주 {$order->order_no} 매출", 'status' => 'draft', 'source_type' => self::SOURCE_ORDER_CONFIRM, 'created_by' => $order->updated_by ?? $order->created_by, ]); } /** * 출하에서 매출 생성 */ public static function createFromShipment(Shipment $shipment, string $saleNumber): self { return new self([ 'tenant_id' => $shipment->tenant_id, 'order_id' => $shipment->order_id, 'shipment_id' => $shipment->id, 'sale_number' => $saleNumber, 'sale_date' => $shipment->shipped_date ?? now()->toDateString(), 'client_id' => $shipment->order?->client_id, 'supply_amount' => $shipment->total_amount / 1.1, // 세전 역산 'tax_amount' => $shipment->total_amount - ($shipment->total_amount / 1.1), 'total_amount' => $shipment->total_amount, 'description' => "출하 {$shipment->shipment_no} 매출", 'status' => 'draft', 'source_type' => self::SOURCE_SHIPMENT_COMPLETE, 'created_by' => $shipment->updated_by ?? $shipment->created_by, ]); } }