feat: update OrderService and frontend components to automatically set order status to completed for cashiers; adjust payment and marketing fields accordingly; enhance tests to verify new behavior
This commit is contained in:
parent
02fb2045d2
commit
352599bf00
@ -393,8 +393,10 @@ public function create(array $validated, User $user): Order
|
||||
if ($user->hasRole('cashier')) {
|
||||
$validated['channel'] = 'store';
|
||||
$validated['price_type'] = 'retail';
|
||||
$validated['payment_type'] = 'cash';
|
||||
$validated['payment_type'] = $validated['payment_type'] ?? 'cash';
|
||||
$validated['status'] = OrderStatus::COMPLETED->value;
|
||||
unset($validated['customer_id']);
|
||||
unset($validated['marketing_id']);
|
||||
}
|
||||
|
||||
$order = $this->runInTransaction(
|
||||
|
||||
@ -35,7 +35,7 @@ defineProps<{
|
||||
canComplete: boolean;
|
||||
canCreate: boolean;
|
||||
cartEmpty: boolean;
|
||||
submitLabel: string;
|
||||
isCashierUser: boolean;
|
||||
}>();
|
||||
|
||||
const printAfterSave = defineModel<boolean>('printAfterSave', { required: true });
|
||||
@ -70,7 +70,7 @@ const isUploading = computed(() => photoState.value.pendingUploads > 0);
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Field v-if="canComplete">
|
||||
<Field v-if="canComplete && !isCashierUser">
|
||||
<div class="flex items-center gap-3">
|
||||
<Switch id="status-completed" :model-value="form.status === OrderStatus.COMPLETED"
|
||||
@update:model-value="form.status = $event ? OrderStatus.COMPLETED : OrderStatus.PENDING" />
|
||||
|
||||
@ -84,7 +84,7 @@ const form = useForm({
|
||||
discount: '',
|
||||
nego_price: '',
|
||||
notes: '',
|
||||
status: OrderStatus.PENDING as string,
|
||||
status: (isCashierUser.value ? OrderStatus.COMPLETED : OrderStatus.PENDING) as string,
|
||||
});
|
||||
|
||||
const isStoreChannel = computed(() => form.channel === 'store');
|
||||
@ -95,7 +95,7 @@ const showPhotoInput = computed(() =>
|
||||
|
||||
const customerFormOpen = ref(false);
|
||||
const cartDetailOpen = ref(false);
|
||||
const printAfterSave = ref(false);
|
||||
const printAfterSave = ref(isCashierUser.value);
|
||||
const selectedPaperSize = ref<'58mm' | '80mm'>(PaperSize.MM_80);
|
||||
const photoState = ref<MediaUploadState>(createMediaUploadState());
|
||||
|
||||
@ -203,7 +203,7 @@ function buildFormData(): FormData {
|
||||
if (isCashierUser.value) {
|
||||
formData.append('channel', 'store');
|
||||
formData.append('price_type', 'retail');
|
||||
formData.append('payment_type', OrderPaymentType.CASH);
|
||||
formData.append('payment_type', form.payment_type);
|
||||
} else {
|
||||
formData.append('channel', form.channel);
|
||||
formData.append('price_type', form.price_type);
|
||||
@ -227,13 +227,18 @@ 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);
|
||||
|
||||
if (isCashierUser.value) {
|
||||
formData.append('status', OrderStatus.COMPLETED);
|
||||
} else {
|
||||
formData.append('status', form.status);
|
||||
}
|
||||
|
||||
if (showPhotoInput.value) {
|
||||
appendRootPhotosToFormData(formData, photoState.value);
|
||||
}
|
||||
|
||||
if (isCreateMode.value && printAfterSave.value) {
|
||||
if (isCreateMode.value && (isCashierUser.value || printAfterSave.value)) {
|
||||
formData.append('print', '1');
|
||||
formData.append('paper_size', selectedPaperSize.value);
|
||||
}
|
||||
@ -340,6 +345,7 @@ function submit() {
|
||||
:can-create="can('orders.create')"
|
||||
:cart-empty="cart.length === 0"
|
||||
:submit-label="submitLabel"
|
||||
:is-cashier-user="isCashierUser"
|
||||
/>
|
||||
</FieldSet>
|
||||
</FieldGroup>
|
||||
|
||||
@ -107,7 +107,7 @@ const emit = defineEmits<{
|
||||
<FieldError :errors="formErrors(form, 'shopee_order_id')" />
|
||||
</Field>
|
||||
|
||||
<Field v-if="!isCashierUser">
|
||||
<Field>
|
||||
<FieldLabel for="payment_type" required>Tipe Pembayaran</FieldLabel>
|
||||
<Select v-model="form.payment_type" :disabled="isMarketplaceChannel">
|
||||
<SelectTrigger id="payment_type" class="w-full">
|
||||
@ -163,7 +163,7 @@ const emit = defineEmits<{
|
||||
<FieldError :errors="formErrors(form, 'customer_id')" />
|
||||
</Field>
|
||||
|
||||
<Field>
|
||||
<Field v-if="!isCashierUser">
|
||||
<FieldLabel for="marketing">Marketing</FieldLabel>
|
||||
<Select v-model="form.marketing_id" :disabled="isMarketingUser">
|
||||
<SelectTrigger id="marketing" class="w-full">
|
||||
|
||||
@ -248,6 +248,36 @@ function setupOrderDraftItems(User $user): ProductVariant
|
||||
|
||||
expect($variant->fresh()->stock)->toBe($initialStock - 5);
|
||||
});
|
||||
|
||||
test('cashier creates order automatically sets status to completed and unsets marketing and customer', function () {
|
||||
$user = User::factory()->create();
|
||||
$user->assignRole('cashier');
|
||||
$user->givePermissionTo(PermissionEnum::ORDERS_CREATE->value);
|
||||
$user->forgetCachedPermissions();
|
||||
|
||||
setupOrderDraftItems($user);
|
||||
|
||||
$marketing = User::factory()->create();
|
||||
$customer = Customer::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('admin.manage.orders.store'), [
|
||||
'customer_id' => $customer->id,
|
||||
'marketing_id' => $marketing->id,
|
||||
'channel' => OrderChannel::STORE->value,
|
||||
'price_type' => PriceType::RETAIL->value,
|
||||
'payment_type' => PaymentType::CASH->value,
|
||||
'status' => OrderStatus::PENDING->value,
|
||||
'discount' => 0,
|
||||
])
|
||||
->assertRedirect(route('admin.manage.orders.index'));
|
||||
|
||||
$order = Order::query()->latest()->first();
|
||||
expect($order)->not->toBeNull();
|
||||
expect($order->status)->toBe(OrderStatus::COMPLETED);
|
||||
expect($order->marketing_id)->toBeNull();
|
||||
expect($order->customer_id)->toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Show ─────────────────────────────────────────────────
|
||||
|
||||
Loading…
Reference in New Issue
Block a user