changes
This commit is contained in:
@@ -17,15 +17,17 @@ function openModal() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<button
|
||||
@click="openModal"
|
||||
class="button is-ghost fs-13"
|
||||
>
|
||||
Chọn IMEI
|
||||
</button>
|
||||
<Modal
|
||||
v-if="showmodal"
|
||||
v-bind="showmodal"
|
||||
@close="showmodal = null"
|
||||
/>
|
||||
<div>
|
||||
<button
|
||||
@click="openModal"
|
||||
class="button is-ghost fs-13"
|
||||
>
|
||||
Chọn IMEI
|
||||
</button>
|
||||
<Modal
|
||||
v-if="showmodal"
|
||||
v-bind="showmodal"
|
||||
@close="showmodal = null"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -70,86 +70,88 @@ onMounted(fetchImeis);
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="is-flex is-justify-content-center"
|
||||
>
|
||||
<Icon
|
||||
name="svg-spinners:180-ring-with-bg"
|
||||
:size="26"
|
||||
class="has-text-primary"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="imeis.length === 0">
|
||||
<p class="mt-6 mb-8 has-text-centered">Sản phẩm không có IMEI có sẵn nào.</p>
|
||||
<div class="block">
|
||||
<AddIMEIForm
|
||||
:variant="variant"
|
||||
@created="fetchImeis"
|
||||
<div>
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="is-flex is-justify-content-center"
|
||||
>
|
||||
<Icon
|
||||
name="svg-spinners:180-ring-with-bg"
|
||||
:size="26"
|
||||
class="has-text-primary"
|
||||
/>
|
||||
</div>
|
||||
<div class="block">
|
||||
<ImportData
|
||||
code="imeis"
|
||||
@close="fetchImeis"
|
||||
/>
|
||||
<div v-else-if="imeis.length === 0">
|
||||
<p class="mt-6 mb-8 has-text-centered">Sản phẩm không có IMEI có sẵn nào.</p>
|
||||
<div class="block">
|
||||
<AddIMEIForm
|
||||
:variant="variant"
|
||||
@created="fetchImeis"
|
||||
/>
|
||||
</div>
|
||||
<div class="block">
|
||||
<ImportData
|
||||
code="imeis"
|
||||
@close="fetchImeis"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
<table class="table is-hoverable is-fullwidth mb-2 fs-13">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>STT</th>
|
||||
<th>IMEI</th>
|
||||
<th>Trạng thái</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(imeiRec, i) in imeis"
|
||||
:key="imeiRec.id"
|
||||
class="is-clickable"
|
||||
:class="selectedImeis.find((i) => i.imei === imeiRec.imei) && 'is-selected'"
|
||||
@click="toggleSelected(imeiRec)"
|
||||
<template v-else>
|
||||
<table class="table is-hoverable is-fullwidth mb-2 fs-13">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>STT</th>
|
||||
<th>IMEI</th>
|
||||
<th>Trạng thái</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
v-for="(imeiRec, i) in imeis"
|
||||
:key="imeiRec.id"
|
||||
class="is-clickable"
|
||||
:class="selectedImeis.find((i) => i.imei === imeiRec.imei) && 'is-selected'"
|
||||
@click="toggleSelected(imeiRec)"
|
||||
>
|
||||
<td class="is-narrow">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selectedImeis.find((i) => i.imei === imeiRec.imei)"
|
||||
/>
|
||||
</label>
|
||||
</td>
|
||||
<td class="is-narrow">{{ i + 1 }}</td>
|
||||
<td class="is-family-monospace">{{ imeiRec.imei }}</td>
|
||||
<td>
|
||||
<span :class="['tag is-light', imeiRec.deleted ? 'is-danger' : 'is-success']">{{
|
||||
imeiRec.deleted ? "Không có sẵn" : "Có sẵn"
|
||||
}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="is-flex is-justify-content-end">
|
||||
<button
|
||||
@click="addToCart"
|
||||
:class="['button is-primary', isAdding && 'is-loading']"
|
||||
:disabled="selectedImeis.length === 0"
|
||||
>
|
||||
<td class="is-narrow">
|
||||
<label class="checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selectedImeis.find((i) => i.imei === imeiRec.imei)"
|
||||
/>
|
||||
</label>
|
||||
</td>
|
||||
<td class="is-narrow">{{ i + 1 }}</td>
|
||||
<td class="is-family-monospace">{{ imeiRec.imei }}</td>
|
||||
<td>
|
||||
<span :class="['tag is-light', imeiRec.deleted ? 'is-danger' : 'is-success']">{{
|
||||
imeiRec.deleted ? "Không có sẵn" : "Có sẵn"
|
||||
}}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="is-flex is-justify-content-end">
|
||||
<button
|
||||
@click="addToCart"
|
||||
:class="['button is-primary', isAdding && 'is-loading']"
|
||||
:disabled="selectedImeis.length === 0"
|
||||
>
|
||||
<span class="icon">
|
||||
<Icon
|
||||
name="material-symbols:add-rounded"
|
||||
:size="18"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<span>Thêm vào giỏ</span>
|
||||
<span v-if="selectedImeis.length > 0"> ({{ selectedImeis.length }})</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
<span class="icon">
|
||||
<Icon
|
||||
name="material-symbols:add-rounded"
|
||||
:size="18"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
<span>Thêm vào giỏ</span>
|
||||
<span v-if="selectedImeis.length > 0"> ({{ selectedImeis.length }})</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped>
|
||||
.table tr.is-selected {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import CartItem from "~/components/pos/CartItem.vue";
|
||||
|
||||
const emit = defineEmits(["close"]);
|
||||
const { $patchapi, $deleteapi, $insertapi, $dayjs, $snackbar } = useNuxtApp();
|
||||
const { $id, $patchapi, $deleteapi, $insertapi, $dayjs, $snackbar } = useNuxtApp();
|
||||
const id = "confirmOrder";
|
||||
const isPending = ref(false);
|
||||
const { activeCart, activeCartItems, orderInfo, getCarts } = inject("pos");
|
||||
@@ -19,10 +19,10 @@ async function createOrder() {
|
||||
isPending.value = true;
|
||||
const invoice = await $insertapi("Invoice", {
|
||||
data: {
|
||||
customer: "",
|
||||
customer_name: "",
|
||||
customer_phone: "",
|
||||
customer_email: "",
|
||||
customer: activeCart.value.customer,
|
||||
customer_name: activeCart.value.customer__fullname,
|
||||
customer_phone: activeCart.value.customer__phone,
|
||||
customer_email: activeCart.value.customer__email,
|
||||
shipping_address: shipping_address.value,
|
||||
product_amount: activeCartItems.value.length,
|
||||
shipping_fee: 0,
|
||||
@@ -32,7 +32,7 @@ async function createOrder() {
|
||||
order_type: "pos",
|
||||
status: "pending",
|
||||
ordered_at: new Date(),
|
||||
paid_at: new Date(),
|
||||
paid_at: null,
|
||||
delivery_method: orderInfo.value.deliveryMethod.id,
|
||||
},
|
||||
notify: false,
|
||||
@@ -64,6 +64,27 @@ async function createOrder() {
|
||||
notify: false,
|
||||
});
|
||||
|
||||
if (orderInfo.value.deliveryMethod.code === "HOME_DELIVERY") {
|
||||
const deliveryInfoPayload = {
|
||||
invoice: invoice.id,
|
||||
receiver_name: invoice.customer_name,
|
||||
receiver_phone: invoice.customer_phone,
|
||||
city: orderInfo.value.address.city,
|
||||
district: orderInfo.value.address.district,
|
||||
ward: orderInfo.value.address.ward,
|
||||
address: orderInfo.value.address.address_detail,
|
||||
shipping_fee: 0,
|
||||
carrier: orderInfo.value.deliveryMethod.id,
|
||||
tracking_code: $id(),
|
||||
status: "pending",
|
||||
};
|
||||
|
||||
const deliveryInfo = await $insertapi("Delivery_Info", {
|
||||
data: deliveryInfoPayload,
|
||||
notify: false,
|
||||
});
|
||||
}
|
||||
|
||||
$snackbar("Tạo đơn hàng thành công", "Success");
|
||||
|
||||
await Promise.all([
|
||||
|
||||
@@ -16,6 +16,24 @@ async function updateAddress() {
|
||||
isLoading.value = false;
|
||||
emit("modalevent", { name: "update" });
|
||||
}
|
||||
|
||||
const isDirty = computed(() => {
|
||||
if (props.address) {
|
||||
// edit
|
||||
return !isEqual(props.address, addressRef);
|
||||
} else {
|
||||
return true;
|
||||
// create
|
||||
// true if
|
||||
}
|
||||
});
|
||||
const isValid = computed(() => {
|
||||
if (!addressRef.value.city) return false;
|
||||
if (!addressRef.value.district) return false;
|
||||
if (!addressRef.value.ward) return false;
|
||||
if (!addressRef.value.address_detail) return false;
|
||||
return true;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -41,7 +59,7 @@ async function updateAddress() {
|
||||
v-model="addressRef.ward"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Text input"
|
||||
placeholder="Phường"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -54,7 +72,7 @@ async function updateAddress() {
|
||||
v-model="addressRef.district"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Text input"
|
||||
placeholder="Quận"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +85,7 @@ async function updateAddress() {
|
||||
v-model="addressRef.city"
|
||||
class="input"
|
||||
type="text"
|
||||
placeholder="Text input"
|
||||
placeholder="Thành phố"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,6 +112,9 @@ async function updateAddress() {
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<pre>address: {{ address }}</pre>
|
||||
<pre>addressRef: {{ addressRef }}</pre>
|
||||
<pre>isDirty: {{ isDirty.toString() }}</pre>
|
||||
<div class="field is-grouped is-grouped-right">
|
||||
<div class="control">
|
||||
<button
|
||||
@@ -108,16 +129,16 @@ async function updateAddress() {
|
||||
<button
|
||||
type="button"
|
||||
:class="['button is-link', isLoading && 'is-loading']"
|
||||
:disabled="isEqual(address, addressRef)"
|
||||
:disabled="!isDirty || !isValid"
|
||||
@click="updateAddress"
|
||||
>
|
||||
<span class="icon">
|
||||
<Icon
|
||||
name="material-symbols:edit-outline-rounded"
|
||||
:size="16"
|
||||
:name="address ? 'material-symbols:edit-outline-rounded' : 'material-symbols:add-rounded'"
|
||||
:size="18"
|
||||
/>
|
||||
</span>
|
||||
<span>Cập nhật</span>
|
||||
<span>{{ address ? "Cập nhật" : "Tạo" }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -49,6 +49,14 @@ function openConfirmModal() {
|
||||
};
|
||||
}
|
||||
|
||||
function openAddAddressModal() {
|
||||
showModal.value = {
|
||||
component: "pos/EditAddress",
|
||||
title: "Thêm địa chỉ",
|
||||
width: "50%",
|
||||
height: "auto",
|
||||
};
|
||||
}
|
||||
provide("pos", {
|
||||
carts,
|
||||
activeCartId,
|
||||
@@ -188,6 +196,7 @@ provide("pos", {
|
||||
column: ['name'],
|
||||
first: true,
|
||||
placeholder: 'Phương thức giao hàng',
|
||||
disabled: !activeCart?.customer,
|
||||
optionid: orderInfo.deliveryMethod?.id,
|
||||
onOption: (e) => (orderInfo.deliveryMethod = e),
|
||||
}"
|
||||
@@ -237,8 +246,23 @@ provide("pos", {
|
||||
@update="getAddresses"
|
||||
/>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p class="has-text-grey has-text-centered p-4">Khách hàng chưa có địa chỉ</p>
|
||||
<div
|
||||
v-else
|
||||
class="has-text-centered"
|
||||
>
|
||||
<p class="has-text-grey p-4">Khách hàng chưa có địa chỉ</p>
|
||||
<button
|
||||
@click="openAddAddressModal"
|
||||
class="button is-light is-primary"
|
||||
>
|
||||
<span class="icon">
|
||||
<Icon
|
||||
name="material-symbols:add-home-work-outline-rounded"
|
||||
:size="18"
|
||||
/>
|
||||
</span>
|
||||
<span>Thêm địa chỉ</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -270,6 +294,7 @@ provide("pos", {
|
||||
column: ['name'],
|
||||
first: true,
|
||||
placeholder: 'Phương thức thanh toán',
|
||||
disabled: !activeCart?.customer,
|
||||
optionid: orderInfo.paymentMethod?.id,
|
||||
onOption: (e) => (orderInfo.paymentMethod = e),
|
||||
}"
|
||||
|
||||
Reference in New Issue
Block a user