From 584387504c443e33a9b479f348cbf2fc6c328815 Mon Sep 17 00:00:00 2001 From: Yoga Pangestu Date: Sat, 13 Jun 2026 00:56:24 +0700 Subject: [PATCH] Refactor order management to remove marketplace fee handling. Update OrderRequest, Order model, and related services to utilize marketplace settings snapshot instead. Adjust frontend components and TypeScript types accordingly for consistency in order processing. --- .../Requests/Admin/Manage/OrderRequest.php | 2 -- app/Models/Order.php | 10 +----- app/Services/Manage/OrderService.php | 21 +++++++----- .../System/Setting/MarketplaceService.php | 32 +++++++++++++++++++ .../2026_06_12_100001_create_orders_table.php | 1 + .../admin/manage/orders/OrderGroupedTable.vue | 4 --- .../admin/manage/orders/OrderPosForm.vue | 13 +------- .../thermal-printer/encode-order-receipt.ts | 8 +---- .../js/pages/admin/manage/orders/Edit.vue | 1 - resources/js/types/order.ts | 2 -- 10 files changed, 49 insertions(+), 45 deletions(-) diff --git a/app/Http/Requests/Admin/Manage/OrderRequest.php b/app/Http/Requests/Admin/Manage/OrderRequest.php index b99b406..e9a9081 100644 --- a/app/Http/Requests/Admin/Manage/OrderRequest.php +++ b/app/Http/Requests/Admin/Manage/OrderRequest.php @@ -31,7 +31,6 @@ public function rules(): array 'channel' => ['required', Rule::enum(OrderChannel::class)], 'price_type' => ['required', Rule::enum(PriceType::class)], 'discount' => ['nullable', 'integer', 'min:0'], - 'marketplace_fee' => ['nullable', 'integer', 'min:0'], 'notes' => ['nullable', 'string'], ]; @@ -58,7 +57,6 @@ public function attributes(): array 'channel' => 'channel', 'price_type' => 'tipe harga', 'discount' => 'diskon', - 'marketplace_fee' => 'biaya marketplace', 'notes' => 'keterangan', 'items' => 'produk', 'items.*.product_variant_id' => 'varian produk', diff --git a/app/Models/Order.php b/app/Models/Order.php index 1d0f9ad..3a5ad43 100644 --- a/app/Models/Order.php +++ b/app/Models/Order.php @@ -19,7 +19,6 @@ #[Appends([ 'subtotal_formatted', 'discount_formatted', - 'marketplace_fee_formatted', 'total_amount_formatted', 'created_at_formatted', 'channel_label', @@ -40,7 +39,7 @@ protected function casts(): array 'status' => OrderStatus::class, 'subtotal' => 'integer', 'discount' => 'integer', - 'marketplace_fee' => 'integer', + 'marketplace_settings_snapshot' => 'array', 'total_amount' => 'integer', ]; } @@ -86,13 +85,6 @@ public function discountFormatted(): Attribute ); } - public function marketplaceFeeFormatted(): Attribute - { - return Attribute::make( - get: fn () => 'Rp '.number_format($this->marketplace_fee, 0, ',', '.'), - ); - } - public function totalAmountFormatted(): Attribute { return Attribute::make( diff --git a/app/Services/Manage/OrderService.php b/app/Services/Manage/OrderService.php index 2956fc6..8b1d48e 100644 --- a/app/Services/Manage/OrderService.php +++ b/app/Services/Manage/OrderService.php @@ -12,6 +12,7 @@ use App\Models\ProductPrice; use App\Models\ProductVariant; use App\Models\User; +use App\Services\System\Setting\MarketplaceService; use App\Support\Media\MediaPresenter; use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Builder; @@ -22,6 +23,10 @@ class OrderService { + public function __construct( + private readonly MarketplaceService $marketplaceService, + ) {} + /** * @param array{search: string, sort: string, direction: 'asc'|'desc'} $tableQuery */ @@ -283,18 +288,18 @@ public function create(array $validated, User $user): Order $subtotal = $draftItems->sum('subtotal'); $discount = (int) ($validated['discount'] ?? 0); - $marketplaceFee = (int) ($validated['marketplace_fee'] ?? 0); - $totalAmount = max($subtotal - $discount - $marketplaceFee, 0); + $totalAmount = max($subtotal - $discount, 0); + $channel = OrderChannel::from($validated['channel']); $order = Order::create([ 'customer_id' => $validated['customer_id'] ?? null, - 'channel' => $validated['channel'], + 'channel' => $channel, 'price_type' => $priceType, 'status' => OrderStatus::PENDING, 'created_by_id' => $user->id, 'subtotal' => $subtotal, 'discount' => $discount, - 'marketplace_fee' => $marketplaceFee, + 'marketplace_settings_snapshot' => $this->marketplaceService->snapshotForChannel($channel), 'total_amount' => $totalAmount, 'notes' => $validated['notes'] ?? null, ]); @@ -333,15 +338,15 @@ public function update(Order $order, array $validated): void $lineItems = $this->buildLineItems($validated['items'], $priceType); $subtotal = array_sum(array_column($lineItems, 'subtotal')); $discount = (int) ($validated['discount'] ?? 0); - $marketplaceFee = (int) ($validated['marketplace_fee'] ?? 0); - $totalAmount = max($subtotal - $discount - $marketplaceFee, 0); + $totalAmount = max($subtotal - $discount, 0); + $channel = OrderChannel::from($validated['channel']); $order->customer_id = $validated['customer_id'] ?? null; - $order->channel = $validated['channel']; + $order->channel = $channel; $order->price_type = $priceType; $order->subtotal = $subtotal; $order->discount = $discount; - $order->marketplace_fee = $marketplaceFee; + $order->marketplace_settings_snapshot = $this->marketplaceService->snapshotForChannel($channel); $order->total_amount = $totalAmount; $order->notes = $validated['notes'] ?? null; $order->save(); diff --git a/app/Services/System/Setting/MarketplaceService.php b/app/Services/System/Setting/MarketplaceService.php index 504942e..6c7c96e 100644 --- a/app/Services/System/Setting/MarketplaceService.php +++ b/app/Services/System/Setting/MarketplaceService.php @@ -2,6 +2,7 @@ namespace App\Services\System\Setting; +use App\Enums\OrderChannel; use App\Settings\MarketplaceSettings; class MarketplaceService @@ -52,4 +53,35 @@ public function updateMarketplace(array $validated): void $settings->save(); } + + /** + * @return array|null + */ + public function snapshotForChannel(OrderChannel $channel): ?array + { + $settings = app(MarketplaceSettings::class); + + return match ($channel) { + OrderChannel::SHOPEE => [ + 'platform' => 'shopee', + 'commission_fee' => $settings->shopee_commission_fee, + 'transaction_fee' => $settings->shopee_transaction_fee, + 'service_fee' => $settings->shopee_service_fee, + 'payment_fee' => $settings->shopee_payment_fee, + 'affiliate_commission' => $settings->shopee_affiliate_commission, + 'shipping_subsidy' => $settings->shopee_shipping_subsidy, + 'voucher_fee' => $settings->shopee_voucher_fee, + ], + OrderChannel::TIKTOK => [ + 'platform' => 'tiktok', + 'admin_fee' => $settings->tiktok_shop_admin_fee, + 'transaction_fee' => $settings->tiktok_shop_transaction_fee, + 'payment_fee' => $settings->tiktok_shop_payment_fee, + 'affiliate_commission' => $settings->tiktok_shop_affiliate_commission, + 'shipping_subsidy' => $settings->tiktok_shop_shipping_subsidy, + 'vat_rate' => $settings->tiktok_shop_vat_rate, + ], + OrderChannel::STORE => null, + }; + } } diff --git a/database/migrations/2026_06_12_100001_create_orders_table.php b/database/migrations/2026_06_12_100001_create_orders_table.php index 1110dab..a824761 100644 --- a/database/migrations/2026_06_12_100001_create_orders_table.php +++ b/database/migrations/2026_06_12_100001_create_orders_table.php @@ -22,6 +22,7 @@ public function up(): void $table->enum('status', array_column(OrderStatus::cases(), 'value'))->default(OrderStatus::PENDING->value); $table->unsignedBigInteger('subtotal'); $table->unsignedBigInteger('discount')->default(0); + $table->json('marketplace_settings_snapshot')->nullable(); $table->unsignedBigInteger('total_amount'); $table->text('notes')->nullable(); diff --git a/resources/js/components/admin/manage/orders/OrderGroupedTable.vue b/resources/js/components/admin/manage/orders/OrderGroupedTable.vue index 0c874b0..09363a2 100644 --- a/resources/js/components/admin/manage/orders/OrderGroupedTable.vue +++ b/resources/js/components/admin/manage/orders/OrderGroupedTable.vue @@ -113,10 +113,6 @@ function statusVariant(status: string): 'default' | 'secondary' | 'destructive' }} Diskon {{ order.discount_formatted }} - - Biaya MP {{ order.marketplace_fee_formatted - }} - Total {{ order.total_amount_formatted }} diff --git a/resources/js/components/admin/manage/orders/OrderPosForm.vue b/resources/js/components/admin/manage/orders/OrderPosForm.vue index b7ff9de..26d1137 100644 --- a/resources/js/components/admin/manage/orders/OrderPosForm.vue +++ b/resources/js/components/admin/manage/orders/OrderPosForm.vue @@ -49,7 +49,6 @@ const props = defineProps<{ channel: string; price_type: string; discount: string; - marketplace_fee: string; notes: string; items: OrderCartItem[]; }; @@ -69,12 +68,10 @@ const form = useForm({ channel: 'store', price_type: 'ecer', discount: '', - marketplace_fee: '', notes: '', }); const isStoreChannel = computed(() => form.channel === 'store'); -const isMarketplaceChannel = computed(() => form.channel === 'shopee' || form.channel === 'tiktok'); function populateForm() { if (!props.initialData) { @@ -85,7 +82,6 @@ function populateForm() { form.channel = props.initialData.channel; form.price_type = props.initialData.price_type; form.discount = props.initialData.discount; - form.marketplace_fee = props.initialData.marketplace_fee; form.notes = props.initialData.notes; cart.value = props.initialData.items.map((item) => ({ ...item })); } @@ -177,8 +173,7 @@ const subtotal = computed(() => ); const discountAmount = computed(() => Number(parseRupiah(form.discount)) || 0); -const marketplaceFeeAmount = computed(() => Number(parseRupiah(form.marketplace_fee)) || 0); -const totalAmount = computed(() => Math.max(subtotal.value - discountAmount.value - marketplaceFeeAmount.value, 0)); +const totalAmount = computed(() => Math.max(subtotal.value - discountAmount.value, 0)); function getVariantPrice(variant: ProductVariantItem): ProductPriceItem | undefined { return variant.prices.find((price) => price.type === form.price_type); @@ -319,7 +314,6 @@ function buildFormData(): FormData { formData.append('channel', form.channel); formData.append('price_type', form.price_type); formData.append('discount', parseRupiah(form.discount)); - formData.append('marketplace_fee', parseRupiah(form.marketplace_fee)); formData.append('notes', form.notes); if (props.method === 'put') { @@ -552,11 +546,6 @@ function submit() { - - Biaya Marketplace - - -
Total Rp {{ formatRupiah(totalAmount) }} diff --git a/resources/js/lib/thermal-printer/encode-order-receipt.ts b/resources/js/lib/thermal-printer/encode-order-receipt.ts index 82dac20..8fc68d1 100644 --- a/resources/js/lib/thermal-printer/encode-order-receipt.ts +++ b/resources/js/lib/thermal-printer/encode-order-receipt.ts @@ -40,7 +40,6 @@ export function encodeOrderReceipt( const createdBy = order.created_by?.profile?.full_name ?? order.created_by?.username ?? '-'; - const isMarketplace = order.channel !== 'store'; encoder.initialize() .align('center') @@ -98,14 +97,9 @@ export function encodeOrderReceipt( const summaryRows: string[][] = [ ['Subtotal', order.subtotal_formatted], ['Diskon', order.discount_formatted], + ['Total', order.total_amount_formatted], ]; - if (isMarketplace) { - summaryRows.push(['Biaya MP', order.marketplace_fee_formatted]); - } - - summaryRows.push(['Total', order.total_amount_formatted]); - encoder.table( [ { width: labelColumnWidth, align: 'left' }, diff --git a/resources/js/pages/admin/manage/orders/Edit.vue b/resources/js/pages/admin/manage/orders/Edit.vue index cb7628e..c83b730 100644 --- a/resources/js/pages/admin/manage/orders/Edit.vue +++ b/resources/js/pages/admin/manage/orders/Edit.vue @@ -20,7 +20,6 @@ const initialData = computed(() => ({ channel: props.order.channel, price_type: props.order.price_type, discount: String(props.order.discount), - marketplace_fee: String(props.order.marketplace_fee), notes: props.order.notes ?? '', items: props.order.items.map((item) => ({ product_variant_id: item.product_variant_id, diff --git a/resources/js/types/order.ts b/resources/js/types/order.ts index ec8a98c..3d7742c 100644 --- a/resources/js/types/order.ts +++ b/resources/js/types/order.ts @@ -47,7 +47,6 @@ export type OrderListItem = { available_actions: OrderStatusAction[]; subtotal_formatted: string; discount_formatted: string; - marketplace_fee_formatted: string; total_amount_formatted: string; notes: string | null; created_at_formatted: string; @@ -81,7 +80,6 @@ export type OrderEditItem = { price_type: string; status: string; discount: number; - marketplace_fee: number; notes: string | null; items: Array<{ product_variant_id: number;