diff --git a/app/Http/Requests/Admin/Manage/OrderRequest.php b/app/Http/Requests/Admin/Manage/OrderRequest.php
index d87473b..09ef1d5 100644
--- a/app/Http/Requests/Admin/Manage/OrderRequest.php
+++ b/app/Http/Requests/Admin/Manage/OrderRequest.php
@@ -39,6 +39,7 @@ public function rules(): array
'tiktok_order_id' => [Rule::requiredIf(fn () => $this->channel === OrderChannel::TIKTOK->value), 'string', 'max:100'],
'shopee_order_id' => [Rule::requiredIf(fn () => $this->channel === OrderChannel::SHOPEE->value), 'string', 'max:100'],
'discount' => ['nullable', 'integer', 'min:0'],
+ 'nego_price' => ['nullable', 'integer', 'min:0'],
'notes' => ['nullable', 'string'],
'status' => ['nullable', Rule::enum(OrderStatus::class)],
];
@@ -72,6 +73,7 @@ public function attributes(): array
'tiktok_order_id' => 'ID pesanan TikTok Shop',
'shopee_order_id' => 'ID pesanan Shopee',
'discount' => 'diskon',
+ 'nego_price' => 'harga nego',
'notes' => 'keterangan',
'status' => 'status pesanan',
'items' => 'produk',
diff --git a/app/Models/Order.php b/app/Models/Order.php
index 27eb30a..080e576 100644
--- a/app/Models/Order.php
+++ b/app/Models/Order.php
@@ -22,6 +22,7 @@
#[Appends([
'subtotal_formatted',
'discount_formatted',
+ 'nego_price_formatted',
'total_amount_formatted',
'created_at_formatted',
'channel_label',
@@ -45,6 +46,7 @@ protected function casts(): array
'status' => OrderStatus::class,
'subtotal' => 'integer',
'discount' => 'integer',
+ 'nego_price' => 'integer',
'marketplace_settings_snapshot' => 'array',
'total_amount' => 'integer',
];
@@ -96,6 +98,13 @@ public function discountFormatted(): Attribute
);
}
+ public function negoPriceFormatted(): Attribute
+ {
+ return Attribute::make(
+ get: fn () => $this->nego_price !== null ? 'Rp '.number_format($this->nego_price, 0, ',', '.') : null,
+ );
+ }
+
public function totalAmountFormatted(): Attribute
{
return Attribute::make(
diff --git a/app/Services/Manage/OrderService.php b/app/Services/Manage/OrderService.php
index b1381bb..2adf610 100644
--- a/app/Services/Manage/OrderService.php
+++ b/app/Services/Manage/OrderService.php
@@ -437,7 +437,8 @@ public function create(array $validated, User $user): Order
$subtotal = $draftItems->sum('subtotal');
$discount = (int) ($validated['discount'] ?? 0);
- $totalAmount = max($subtotal - $discount, 0);
+ $negoPrice = isset($validated['nego_price']) && $validated['nego_price'] !== '' ? (int) $validated['nego_price'] : null;
+ $totalAmount = $negoPrice !== null ? max($negoPrice, 0) : max($subtotal - $discount, 0);
$channel = OrderChannel::from($validated['channel']);
$status = isset($validated['status'])
@@ -457,6 +458,7 @@ public function create(array $validated, User $user): Order
'created_by_id' => $user->id,
'subtotal' => $subtotal,
'discount' => $discount,
+ 'nego_price' => $negoPrice,
'marketplace_settings_snapshot' => $this->marketplaceService->buildOrderSnapshot(
$channel,
$totalAmount,
@@ -549,7 +551,8 @@ 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);
- $totalAmount = max($subtotal - $discount, 0);
+ $negoPrice = isset($validated['nego_price']) && $validated['nego_price'] !== '' ? (int) $validated['nego_price'] : null;
+ $totalAmount = $negoPrice !== null ? max($negoPrice, 0) : max($subtotal - $discount, 0);
$channel = OrderChannel::from($validated['channel']);
$order->customer_id = $validated['customer_id'] ?? null;
@@ -562,6 +565,7 @@ public function update(Order $order, array $validated): void
$order->shopee_order_id = $validated['shopee_order_id'] ?? null;
$order->subtotal = $subtotal;
$order->discount = $discount;
+ $order->nego_price = $negoPrice;
$order->marketplace_settings_snapshot = $this->marketplaceService->buildOrderSnapshot(
$channel,
$totalAmount,
diff --git a/database/migrations/2026_06_28_104300_add_nego_price_to_orders_table.php b/database/migrations/2026_06_28_104300_add_nego_price_to_orders_table.php
new file mode 100644
index 0000000..1b720be
--- /dev/null
+++ b/database/migrations/2026_06_28_104300_add_nego_price_to_orders_table.php
@@ -0,0 +1,22 @@
+unsignedBigInteger('nego_price')->nullable()->after('discount');
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('orders', function (Blueprint $table): void {
+ $table->dropColumn('nego_price');
+ });
+ }
+};
diff --git a/resources/js/lib/thermal-printer/encode-order-receipt.ts b/resources/js/lib/thermal-printer/encode-order-receipt.ts
index 8fc68d1..45623c8 100644
--- a/resources/js/lib/thermal-printer/encode-order-receipt.ts
+++ b/resources/js/lib/thermal-printer/encode-order-receipt.ts
@@ -97,9 +97,14 @@ export function encodeOrderReceipt(
const summaryRows: string[][] = [
['Subtotal', order.subtotal_formatted],
['Diskon', order.discount_formatted],
- ['Total', order.total_amount_formatted],
];
+ if (order.nego_price_formatted) {
+ summaryRows.push(['Harga Nego', order.nego_price_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 d0c360d..cbe8482 100644
--- a/resources/js/pages/admin/manage/orders/Edit.vue
+++ b/resources/js/pages/admin/manage/orders/Edit.vue
@@ -36,6 +36,7 @@ const initialData = computed(() => ({
tiktok_order_id: props.order.tiktok_order_id ?? '',
shopee_order_id: props.order.shopee_order_id ?? '',
discount: String(props.order.discount),
+ nego_price: props.order.nego_price != null ? String(props.order.nego_price) : '',
notes: props.order.notes ?? '',
status: props.order.status,
items: props.order.items.map((item) => ({
diff --git a/resources/js/pages/admin/manage/orders/Show.vue b/resources/js/pages/admin/manage/orders/Show.vue
index f59a68c..318c3f1 100644
--- a/resources/js/pages/admin/manage/orders/Show.vue
+++ b/resources/js/pages/admin/manage/orders/Show.vue
@@ -142,6 +142,10 @@ const summaryRows = computed(() => {
rows.push({ label: 'Diskon', value: `-${props.order.discount_formatted}` });
}
+ if (props.order.nego_price != null && props.order.nego_price > 0) {
+ rows.push({ label: 'Harga Nego', value: props.order.nego_price_formatted });
+ }
+
return rows;
});
diff --git a/resources/js/pages/admin/manage/orders/form/OrderPosForm.vue b/resources/js/pages/admin/manage/orders/form/OrderPosForm.vue
index f2bd209..4f58ee0 100644
--- a/resources/js/pages/admin/manage/orders/form/OrderPosForm.vue
+++ b/resources/js/pages/admin/manage/orders/form/OrderPosForm.vue
@@ -75,6 +75,7 @@ const props = defineProps<{
tiktok_order_id: string;
shopee_order_id: string;
discount: string;
+ nego_price: string;
notes: string;
status: string;
items: OrderCartItem[];
@@ -131,6 +132,7 @@ const form = useForm({
tiktok_order_id: '',
shopee_order_id: '',
discount: '',
+ nego_price: '',
notes: '',
status: OrderStatus.PENDING,
});
@@ -152,6 +154,7 @@ function populateForm() {
form.tiktok_order_id = props.initialData.tiktok_order_id;
form.shopee_order_id = props.initialData.shopee_order_id;
form.discount = props.initialData.discount;
+ form.nego_price = props.initialData.nego_price;
form.notes = props.initialData.notes;
form.status = props.initialData.status || OrderStatus.PENDING;
cart.value = props.initialData.items.map((item) => ({
@@ -260,7 +263,13 @@ const subtotal = computed(() =>
);
const discountAmount = computed(() => Number(parseRupiah(form.discount)) || 0);
-const totalAmount = computed(() => Math.max(subtotal.value - discountAmount.value, 0));
+const negoPriceAmount = computed(() => Number(parseRupiah(form.nego_price)) || 0);
+const totalAmount = computed(() => {
+ if (negoPriceAmount.value > 0) {
+ return negoPriceAmount.value;
+ }
+ return Math.max(subtotal.value - discountAmount.value, 0);
+});
function getVariantPrice(variant: ProductVariantItem): ProductPriceItem | undefined {
return variant.prices.find((price) => price.type === form.price_type);
@@ -475,6 +484,7 @@ function buildFormData(): FormData {
}
formData.append('discount', parseRupiah(form.discount));
+ formData.append('nego_price', parseRupiah(form.nego_price));
formData.append('notes', form.notes);
formData.append('status', form.status);
@@ -841,6 +851,12 @@ function submit() {
Jika diisi, harga nego menjadi total akhir.