changes
This commit is contained in:
@@ -1,36 +1,45 @@
|
||||
<script setup>
|
||||
import { without } from "es-toolkit";
|
||||
import Address from "~/components/pos/Address.vue";
|
||||
import CartItem from "~/components/pos/CartItem.vue";
|
||||
import CartTabs from "~/components/pos/CartTabs.vue";
|
||||
import SearchBox from "~/components/SearchBox.vue";
|
||||
|
||||
const store = useStore();
|
||||
const { $getdata, $patchapi, $numtoString } = useNuxtApp();
|
||||
const cart = ref();
|
||||
const cartItems = ref();
|
||||
const { $findapi, $getapi, $getdata, $patchapi, $numtoString } = useNuxtApp();
|
||||
const carts = ref([]);
|
||||
const cartItems = ref([]);
|
||||
const customers = ref([]);
|
||||
const activeCartId = ref();
|
||||
const activeCart = computed(() => carts.value.find((c) => c.id === activeCartId.value));
|
||||
const activeCartItems = computed(() => cartItems.value.filter((ci) => ci.cart === activeCartId.value));
|
||||
const isUpdating = ref(false);
|
||||
|
||||
async function getCart() {
|
||||
try {
|
||||
isUpdating.value = true;
|
||||
const cartFetched = await $getdata("Cart", {
|
||||
first: true,
|
||||
});
|
||||
cart.value = cartFetched;
|
||||
async function getCarts() {
|
||||
const apis = $findapi(["Cart", "Cart_Item", "customer"]);
|
||||
const [cartsRes, cartItemsRes, customersRes] = await $getapi(apis);
|
||||
|
||||
const cartItemsFetched = await $getdata("Cart_Item", {
|
||||
filter: {
|
||||
cart: cartFetched.id,
|
||||
},
|
||||
});
|
||||
cartItems.value = cartItemsFetched;
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
} finally {
|
||||
isUpdating.value = false;
|
||||
}
|
||||
carts.value = cartsRes.data.rows || [];
|
||||
cartItems.value = cartItemsRes.data.rows || [];
|
||||
customers.value = customersRes.data.rows || [];
|
||||
}
|
||||
|
||||
onMounted(getCart);
|
||||
const customerIdsWithNoCart = computed(() => {
|
||||
const cusIds = customers.value.map((c) => c.id);
|
||||
const cusIdsWithCart = carts.value.filter((c) => c.customer).map((c) => c.customer);
|
||||
const cusIdsWithNoCart = without(cusIds, ...cusIdsWithCart);
|
||||
return cusIdsWithNoCart;
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
await getCarts();
|
||||
activeCartId.value = carts.value[0].id;
|
||||
});
|
||||
|
||||
watch(activeCartId, () => {
|
||||
orderInfo.value.deliveryMethod = null;
|
||||
orderInfo.value.paymentMethod = null;
|
||||
});
|
||||
|
||||
const showProductSelectionModal = ref();
|
||||
function openProductSelectionModal() {
|
||||
@@ -43,43 +52,45 @@ function openProductSelectionModal() {
|
||||
}
|
||||
|
||||
const orderInfo = ref({
|
||||
customer: null,
|
||||
address: null,
|
||||
deliveryMethod: null,
|
||||
paymentMethod: null,
|
||||
});
|
||||
const addresses = ref([]);
|
||||
const subtotal = computed(() => {
|
||||
return cartItems.value?.reduce((prev, curr) => prev + curr.imei__variant__price, 0);
|
||||
return activeCartItems.value?.reduce((prev, curr) => prev + curr.imei__variant__price, 0);
|
||||
});
|
||||
|
||||
async function getAddresses() {
|
||||
addresses.value = await $getdata("Customer_Address", {
|
||||
filter: { customer: orderInfo.value.customer.id },
|
||||
filter: { customer: activeCart.value.customer },
|
||||
});
|
||||
}
|
||||
|
||||
watch(
|
||||
() => orderInfo.value.customer,
|
||||
async (newVal, oldVal) => {
|
||||
const updatedCart = await $patchapi("Cart", {
|
||||
id: cart.value.id,
|
||||
customer: newVal?.id,
|
||||
});
|
||||
getCart();
|
||||
|
||||
if (newVal) {
|
||||
await getAddresses();
|
||||
if (oldVal === null || oldVal.id !== newVal.id) {
|
||||
const defaultAddress = addresses.value.find((add) => add.is_default);
|
||||
orderInfo.value.address = defaultAddress;
|
||||
}
|
||||
} else {
|
||||
addresses.value = null;
|
||||
orderInfo.value.address = null;
|
||||
watch(activeCart, async (newVal, oldVal) => {
|
||||
// set order info
|
||||
if (newVal.customer) {
|
||||
await getAddresses();
|
||||
if (!oldVal || !oldVal.customer || oldVal.customer !== newVal.customer) {
|
||||
const defaultAddress = addresses.value.find((add) => add.is_default);
|
||||
orderInfo.value.address = defaultAddress;
|
||||
}
|
||||
},
|
||||
);
|
||||
} else {
|
||||
addresses.value = null;
|
||||
orderInfo.value.address = null;
|
||||
}
|
||||
});
|
||||
|
||||
const isChangingCus = ref(false);
|
||||
async function changeCustomer(cusId) {
|
||||
isChangingCus.value = true;
|
||||
const updatedCart = await $patchapi("Cart", {
|
||||
id: activeCartId.value,
|
||||
customer: cusId,
|
||||
});
|
||||
await getCarts();
|
||||
isChangingCus.value = false;
|
||||
}
|
||||
|
||||
watch(
|
||||
() => orderInfo.value.deliveryMethod,
|
||||
@@ -92,8 +103,8 @@ watch(
|
||||
);
|
||||
|
||||
const isOrderValid = computed(() => {
|
||||
if (cartItems.value?.length === 0) return false;
|
||||
if (!orderInfo.value.customer) return false;
|
||||
if (activeCartItems.value?.length === 0) return false;
|
||||
if (!activeCart.value?.customer) return false;
|
||||
if (!orderInfo.value.deliveryMethod) return false;
|
||||
if (!orderInfo.value.paymentMethod) return false;
|
||||
if (orderInfo.value.deliveryMethod.code === "HOME_DELIVERY" && !orderInfo.value.address) return false;
|
||||
@@ -112,17 +123,34 @@ function openConfirmModal() {
|
||||
}
|
||||
|
||||
provide("pos", {
|
||||
cartItems,
|
||||
carts,
|
||||
activeCartId,
|
||||
activeCart,
|
||||
activeCartItems,
|
||||
isChangingCus,
|
||||
orderInfo,
|
||||
getCart,
|
||||
getCarts,
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="fixed-grid has-1-cols-mobile has-12-cols">
|
||||
<div class="grid">
|
||||
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-8']">
|
||||
<!-- <div class="fs-11">
|
||||
<pre>customerIdsWithNoCart: {{ customerIdsWithNoCart }}</pre>
|
||||
<pre>{{ customerIdsWithNoCart }}</pre>
|
||||
<pre>{{ activeCart }}</pre>
|
||||
<pre>{{ JSON.stringify(activeCartItems) }}</pre>
|
||||
<pre>{{ JSON.stringify(activeCart) }}</pre>
|
||||
<pre>activeCart?.customer: {{ JSON.stringify(activeCart?.customer) }}</pre>
|
||||
<pre>{{ orderInfo }}</pre>
|
||||
</div> -->
|
||||
<CartTabs />
|
||||
<div class="fixed-grid has-1-cols-mobile has-12-cols has-background-white is-clipped">
|
||||
<div
|
||||
class="grid"
|
||||
style="row-gap: 0"
|
||||
>
|
||||
<div :class="['cell', store.viewport < 3 ? 'is-col-span-12' : 'is-col-span-8']">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<div class="block is-flex is-justify-content-space-between">
|
||||
@@ -159,11 +187,11 @@ provide("pos", {
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
v-if="cartItems?.length > 0"
|
||||
v-if="activeCartItems?.length > 0"
|
||||
class="is-flex is-flex-direction-column is-gap-1"
|
||||
>
|
||||
<CartItem
|
||||
v-for="cartItem in cartItems"
|
||||
v-for="cartItem in activeCartItems"
|
||||
:key="cartItem.id"
|
||||
:cartItem="cartItem"
|
||||
deleteable
|
||||
@@ -173,12 +201,12 @@ provide("pos", {
|
||||
v-else
|
||||
class="py-4 fs-16 has-text-centered has-text-grey"
|
||||
>
|
||||
Không có sản phẩm nào trong giỏ hàng.
|
||||
Chưa có sản phẩm nào trong giỏ hàng.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div :class="['cell', store.viewport < 4 ? 'is-col-span-12' : 'is-col-span-4']">
|
||||
<div :class="['cell sidebar', store.viewport < 3 ? 'is-col-span-12' : 'is-col-span-4']">
|
||||
<div class="card">
|
||||
<div class="card-content">
|
||||
<p class="icon-text fs-16 font-semibold mb-4">
|
||||
@@ -194,12 +222,15 @@ provide("pos", {
|
||||
<SearchBox
|
||||
v-bind="{
|
||||
api: 'customer',
|
||||
// filter: { id__in: [...customerIdsWithNoCart, activeCart?.customer] },
|
||||
field: 'label',
|
||||
column: ['label'],
|
||||
first: true,
|
||||
optionid: cart?.customer,
|
||||
placeholder: 'Khách hàng',
|
||||
onOption: (e) => (orderInfo.customer = e),
|
||||
optionid: activeCart?.customer,
|
||||
onOption: (e) => {
|
||||
if (e?.id !== activeCart?.customer) changeCustomer(e?.id || null);
|
||||
},
|
||||
addon: {
|
||||
component: 'customer/CustomerQuickAdd',
|
||||
width: '50%',
|
||||
@@ -230,22 +261,23 @@ provide("pos", {
|
||||
column: ['name'],
|
||||
first: true,
|
||||
placeholder: 'Phương thức giao hàng',
|
||||
optionid: orderInfo.deliveryMethod?.id,
|
||||
onOption: (e) => (orderInfo.deliveryMethod = e),
|
||||
}"
|
||||
/>
|
||||
</div>
|
||||
<template v-if="orderInfo.deliveryMethod?.code === 'HOME_DELIVERY'">
|
||||
<div v-if="orderInfo.customer">
|
||||
<div v-if="activeCart.customer">
|
||||
<div class="block">
|
||||
<p class="mb-2">Thông tin người nhận</p>
|
||||
<div v-if="orderInfo.customer">
|
||||
<div v-if="activeCart.customer">
|
||||
<div class="field">
|
||||
<label class="label is-small">Tên</label>
|
||||
<p class="control">
|
||||
<input
|
||||
class="input is-small"
|
||||
type="email"
|
||||
:value="orderInfo.customer.fullname"
|
||||
:value="activeCart.customer__fullname"
|
||||
placeholder="Name"
|
||||
disabled
|
||||
/>
|
||||
@@ -257,7 +289,7 @@ provide("pos", {
|
||||
<input
|
||||
class="input is-small"
|
||||
type="email"
|
||||
:value="orderInfo.customer?.phone"
|
||||
:value="activeCart.customer__phone"
|
||||
placeholder="Phone"
|
||||
disabled
|
||||
/>
|
||||
@@ -311,6 +343,7 @@ provide("pos", {
|
||||
column: ['name'],
|
||||
first: true,
|
||||
placeholder: 'Phương thức thanh toán',
|
||||
optionid: orderInfo.paymentMethod?.id,
|
||||
onOption: (e) => (orderInfo.paymentMethod = e),
|
||||
}"
|
||||
/>
|
||||
@@ -326,7 +359,7 @@ provide("pos", {
|
||||
<tr>
|
||||
<td>
|
||||
<span>Tạm tính</span>
|
||||
<span> ({{ cartItems?.length || 0 }} sản phẩm)</span>
|
||||
<span> ({{ activeCartItems?.length || 0 }} sản phẩm)</span>
|
||||
</td>
|
||||
<td class="has-text-right">{{ $numtoString(subtotal, { hasUnit: true }) }}</td>
|
||||
</tr>
|
||||
@@ -363,3 +396,28 @@ provide("pos", {
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "bulma/sass/utilities/mixins.scss" as *;
|
||||
|
||||
.cell > .card {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.fixed-grid {
|
||||
border: 1px solid var(--bulma-border);
|
||||
border-bottom-left-radius: var(--bulma-radius);
|
||||
border-bottom-right-radius: var(--bulma-radius);
|
||||
}
|
||||
.sidebar {
|
||||
border-left: 1px solid var(--bulma-border);
|
||||
border-top: none;
|
||||
|
||||
@include touch {
|
||||
border-left: none;
|
||||
border-top: 1px solid var(--bulma-border);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user