$metadata 플러그인 확장용 메타데이터 * - deposit_used: 예치금 사용 합계 (예치금 플러그인) * - gift_card_used: 상품권 사용 합계 (상품권 플러그인) * - grade_discount: 회원등급 할인 합계 (회원등급 플러그인) */ public function __construct( public int $subtotal = 0, public int $productCouponDiscount = 0, public int $codeDiscount = 0, public int $orderCouponDiscount = 0, public int $totalDiscount = 0, public int $baseShippingTotal = 0, public int $extraShippingTotal = 0, public int $totalShipping = 0, public int $shippingDiscount = 0, public int $taxableAmount = 0, public int $taxFreeAmount = 0, public int $vatAmount = 0, public int $pointsEarning = 0, public int $pointsUsed = 0, public int $paymentAmount = 0, public int $finalAmount = 0, public ?MultiCurrencyPrices $multiCurrency = null, public ?string $selectedPaymentCurrency = null, public array $metadata = [], ) {} /** * 총 할인금액을 계산합니다. * * @return int 총 할인금액 */ public function calculateTotalDiscount(): int { return $this->productCouponDiscount + $this->codeDiscount + $this->orderCouponDiscount; } /** * 총 배송비를 계산합니다 (기본 + 추가). * * @return int 총 배송비 */ public function calculateTotalShipping(): int { return $this->baseShippingTotal + $this->extraShippingTotal; } /** * 결제금액을 계산합니다. * * @return int 결제금액 */ public function calculatePaymentAmount(): int { return max(0, $this->subtotal - $this->totalDiscount + $this->totalShipping - $this->shippingDiscount); } /** * 최종 지불금액을 계산합니다. * * @return int 최종 지불금액 */ public function calculateFinalAmount(): int { return max(0, $this->paymentAmount - $this->pointsUsed); } /** * 배열로 변환합니다. * * @return array 직렬화된 합계 배열 */ public function toArray(): array { $result = [ 'subtotal' => $this->subtotal, 'subtotal_formatted' => ecommerce_format_price($this->subtotal), 'product_coupon_discount' => $this->productCouponDiscount, 'product_coupon_discount_formatted' => ecommerce_format_price($this->productCouponDiscount), 'code_discount' => $this->codeDiscount, 'code_discount_formatted' => ecommerce_format_price($this->codeDiscount), 'order_coupon_discount' => $this->orderCouponDiscount, 'order_coupon_discount_formatted' => ecommerce_format_price($this->orderCouponDiscount), 'total_coupon_discount' => $this->productCouponDiscount + $this->orderCouponDiscount, 'total_coupon_discount_formatted' => ecommerce_format_price($this->productCouponDiscount + $this->orderCouponDiscount), 'total_discount' => $this->totalDiscount, 'discount_formatted' => ecommerce_format_price($this->totalDiscount), 'base_shipping_total' => $this->baseShippingTotal, 'extra_shipping_total' => $this->extraShippingTotal, 'total_shipping' => $this->totalShipping, 'total_shipping_fee' => $this->totalShipping, 'shipping_fee_formatted' => ecommerce_format_price($this->totalShipping), 'shipping_discount' => $this->shippingDiscount, 'shipping_discount_formatted' => ecommerce_format_price($this->shippingDiscount), 'taxable_amount' => $this->taxableAmount, 'tax_free_amount' => $this->taxFreeAmount, 'vat_amount' => $this->vatAmount, 'points_earning' => $this->pointsEarning, 'total_mileage' => $this->pointsEarning, 'mileage_formatted' => number_format($this->pointsEarning).'P', 'points_used' => $this->pointsUsed, // 마일리지 사용액(차감) 포맷 — 다른 금액과 동일한 통화 포맷 (요약/결제완료 화면이 바인딩). // 마일리지는 base_currency 단일 정산이므로 multi_currency 변환 없이 루트 키로만 제공. 'points_used_formatted' => ecommerce_format_price($this->pointsUsed), 'payment_amount' => $this->paymentAmount, 'payment_amount_formatted' => ecommerce_format_price($this->paymentAmount), 'final_amount' => $this->finalAmount, 'final_amount_formatted' => ecommerce_format_price($this->finalAmount), // 하위 호환 (deprecated) 'coupon_discount' => $this->productCouponDiscount, 'coupon_discount_formatted' => ecommerce_format_price($this->productCouponDiscount), 'order_discount' => $this->orderCouponDiscount, 'order_discount_formatted' => ecommerce_format_price($this->orderCouponDiscount), ]; if ($this->selectedPaymentCurrency !== null) { $result['selected_payment_currency'] = $this->selectedPaymentCurrency; } if ($this->multiCurrency !== null) { $result['multi_currency'] = $this->multiCurrency->toArray(); } if (! empty($this->metadata)) { $result['metadata'] = $this->metadata; } return $result; } /** * 배열에서 DTO를 생성합니다. * * @param array $data 배열 데이터 * @return self 생성된 Summary DTO */ public static function fromArray(array $data): self { return new self( subtotal: $data['subtotal'] ?? 0, productCouponDiscount: $data['product_coupon_discount'] ?? $data['coupon_discount'] ?? 0, codeDiscount: $data['code_discount'] ?? 0, orderCouponDiscount: $data['order_coupon_discount'] ?? $data['order_discount'] ?? 0, totalDiscount: $data['total_discount'] ?? 0, baseShippingTotal: $data['base_shipping_total'] ?? 0, extraShippingTotal: $data['extra_shipping_total'] ?? 0, totalShipping: $data['total_shipping'] ?? 0, shippingDiscount: $data['shipping_discount'] ?? 0, taxableAmount: $data['taxable_amount'] ?? 0, taxFreeAmount: $data['tax_free_amount'] ?? 0, vatAmount: $data['vat_amount'] ?? 0, pointsEarning: $data['points_earning'] ?? 0, pointsUsed: $data['points_used'] ?? 0, paymentAmount: $data['payment_amount'] ?? 0, finalAmount: $data['final_amount'] ?? 0, multiCurrency: isset($data['multi_currency']) ? MultiCurrencyPrices::fromArray($data['multi_currency']) : null, selectedPaymentCurrency: $data['selected_payment_currency'] ?? null, metadata: $data['metadata'] ?? [], ); } }