Filter restricted products and add-ons based on customer attributes in POS components
- Introduced logic to filter out restricted products and add-ons using new utility methods (`isProductRestricted`, `isAddonRestricted`, `canBuyAdditionalServices`) based on customer attributes. - Updated relevant POS components to replace unfiltered lists with computed properties for restricted items. - Enhanced maintainability by centralizing restriction checks in `POSDepartmentProcess.vue`.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { setTransparency, setBackgroundColor, backgroundColors } from "@/components/viewport/page/headers/ViewportHeaderSettings.vue";
|
||||
import {onMounted, onUnmounted, ref, watch} from "vue";
|
||||
import {onMounted, onUnmounted, ref, watch, computed} from "vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import PosDepartmentStepMobile2Product
|
||||
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobile2Product.vue";
|
||||
@@ -19,7 +19,7 @@ import PosDepartmentStep2MobileVehicleSelection
|
||||
import PosDepartmentStepMobileButtonNextStep
|
||||
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobileButtonNextStep.vue";
|
||||
import { primaryItem } from "./objects/PosDepartmentStepMobileFlow.vue";
|
||||
import { order_id, order_notes, department_id, customer_id, getCustomerEmail, customer_name } from "@/components/shop/POSDepartmentProcess.vue";
|
||||
import { order_id, order_notes, department_id, customer_id, getCustomerEmail, customer_name, isAddonRestricted, canBuyAdditionalServices } from "@/components/shop/POSDepartmentProcess.vue";
|
||||
import { getOrderItems } from "@/components/shop/OrdersItems.vue";
|
||||
import { PosProduct } from "@/components/displays/department/pos/steps/mobile/objects/PosProduct.vue";
|
||||
import PosDepartmentStepMobileButtonClearAll
|
||||
@@ -499,7 +499,16 @@ watch(() => vehicles.vehicle_1.value.reference, (newValue, oldValue) => {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Computed property to filter out restricted addons based on customer attributes
|
||||
const filteredAddons = computed(() => {
|
||||
const addons = transactionItems.primaryItem.value?.addons || [];
|
||||
// If additional services are restricted, return empty array
|
||||
if (!canBuyAdditionalServices()) {
|
||||
return [];
|
||||
}
|
||||
// Filter out individually restricted addons
|
||||
return addons.filter((addon: any) => !isAddonRestricted(addon));
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@@ -545,8 +554,8 @@ watch(() => vehicles.vehicle_1.value.reference, (newValue, oldValue) => {
|
||||
v-show="lastOrders.get(1)"
|
||||
@click="lastOrders.select(1)"
|
||||
:classes="layout.classes" :label="'ordered on...'" :subtitle="'Subtitle'" :lastOrder="lastOrders.get(1)"/>
|
||||
<!-- Addons -->
|
||||
<PosDepartmentStepMobile2Addons :addons="transactionItems.primaryItem.value?.addons || []" :label="'Add-ons'" :compact="false"/>
|
||||
<!-- Addons (filtered based on customer restrictions) -->
|
||||
<PosDepartmentStepMobile2Addons :addons="filteredAddons" :label="'Add-ons'" :compact="false"/>
|
||||
<!-- Notes -->
|
||||
<ControlField>
|
||||
<ControlFieldInputLabel label="Notes" :classes="layout.classes" :optional="true"/>
|
||||
|
||||
+12
-1
@@ -22,6 +22,7 @@ import PosDepartmentStep2MobileVehicleSelection
|
||||
import GenericButton from "@/components/viewport/page/templates/generic/graphics/GenericButton.vue";
|
||||
import PosDepartmentStepMobile2FloatingCart
|
||||
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobile2FloatingCart.vue";
|
||||
import { isAddonRestricted, canBuyAdditionalServices } from "@/components/shop/POSDepartmentProcess.vue";
|
||||
|
||||
const props = defineProps({
|
||||
label: {
|
||||
@@ -117,6 +118,16 @@ const getAvailableAdditionalItems = () => {
|
||||
}));
|
||||
}
|
||||
const availableAdditionalItems = ref<Addon[]>(getAvailableAdditionalItems());
|
||||
|
||||
// Computed property to filter out restricted additional items based on customer attributes
|
||||
const filteredAdditionalItems = computed(() => {
|
||||
// If additional services are restricted, return empty array
|
||||
if (!canBuyAdditionalServices()) {
|
||||
return [];
|
||||
}
|
||||
// Filter out individually restricted addons
|
||||
return availableAdditionalItems.value.filter((addon: Addon) => !isAddonRestricted(addon));
|
||||
});
|
||||
const onClickAddOtherProduct = () => {
|
||||
pos.views.additionalItemSelection.value = !pos.views.additionalItemSelection.value;
|
||||
}
|
||||
@@ -184,7 +195,7 @@ const onClickAddProduct = async (product: PosProduct) => {
|
||||
<div v-if="!availableAdditionalItems || availableAdditionalItems.length === 0">
|
||||
<p>{{ SessionUser.objects.global.language.no_additional_items }}</p>
|
||||
</div>
|
||||
<PosDepartmentStepMobile2Addons :label="''" :addons="availableAdditionalItems" />
|
||||
<PosDepartmentStepMobile2Addons :label="''" :addons="filteredAdditionalItems" />
|
||||
</div>
|
||||
</template>
|
||||
<!-- Footer -->
|
||||
|
||||
+14
-5
@@ -1,12 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import {watch, defineEmits, defineProps, ref, defineSlots} from "vue";
|
||||
import {watch, defineEmits, defineProps, ref, defineSlots, computed} from "vue";
|
||||
import { pos } from "../objects/PosDepartmentStepMobileFlow.vue";
|
||||
import PosDepartmentStepMobile2CategoryProduct
|
||||
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobile2CategoryProduct.vue";
|
||||
import {PosCategory} from "@/components/displays/department/pos/steps/mobile/objects/PosCategory.vue";
|
||||
import { SessionUser } from "@/components/session/token/SessionUser.vue";
|
||||
import {PosProduct} from "@/components/displays/department/pos/steps/mobile/objects/PosProduct.vue";
|
||||
import { department_id, customer_id } from "@/components/shop/POSDepartmentProcess.vue";
|
||||
import { department_id, customer_id, isProductRestricted } from "@/components/shop/POSDepartmentProcess.vue";
|
||||
import PosDepartmentStepMobile2Addons
|
||||
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobile2Addons.vue";
|
||||
import {Addon} from "@/components/displays/department/pos/steps/mobile/objects/PosAddon.vue";
|
||||
@@ -79,8 +79,12 @@ const mergedAddons = ref<Addon[]>([]);
|
||||
// Function to merge the count of addons with the products
|
||||
const mergeCountAddons = (products: PosProduct[], addons: Addon[] | undefined) => {
|
||||
const tmpAddons = <Addon[]>[]; // Temporary array to hold the merged addons
|
||||
// Convert all products to addons
|
||||
// Convert all products to addons (only non-restricted products)
|
||||
for (let product of products) {
|
||||
// Skip restricted products
|
||||
if (isProductRestricted(product)) {
|
||||
continue;
|
||||
}
|
||||
let tmpAddon = pos.transactionItems.convertProductToAddon(product); // Convert product to addon (count = 0)
|
||||
tmpAddons.push(tmpAddon);
|
||||
}
|
||||
@@ -100,13 +104,18 @@ const mergeCountAddons = (products: PosProduct[], addons: Addon[] | undefined) =
|
||||
watch(() => props.addons, (newAddons) => {
|
||||
mergeCountAddons(pos.productList.get(), newAddons);
|
||||
}, { immediate: true });
|
||||
|
||||
// Computed property to filter out restricted products
|
||||
const filteredProducts = computed(() => {
|
||||
return pos.productList.get().filter(product => !isProductRestricted(product));
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<template v-if="pos.categories.isSelected()">
|
||||
<template v-if="!props.asAddons">
|
||||
<!-- Display of products, without a "basket" -->
|
||||
<template v-for="product in pos.productList.get()" :key="product.id">
|
||||
<!-- Display of products, without a "basket" (filtered for customer restrictions) -->
|
||||
<template v-for="product in filteredProducts" :key="product.id">
|
||||
<PosDepartmentStepMobile2CategoryProduct
|
||||
@addProduct="emits('addProduct', product)"
|
||||
:price="product.price"
|
||||
|
||||
@@ -671,6 +671,58 @@ export const canBuyTankCleaning = () => {
|
||||
return !hasAttribute('restrictTankCleaning');
|
||||
};
|
||||
|
||||
/** Check if the customer is allowed to buy additional services */
|
||||
export const canBuyAdditionalServices = () => {
|
||||
// Check if the customer has the attribute restrictAdditionalServices
|
||||
return !hasAttribute('restrictAdditionalServices');
|
||||
};
|
||||
|
||||
/** Check if the customer has the onlyTankCleaning attribute */
|
||||
export const hasOnlyTankCleaning = () => {
|
||||
return hasAttribute('onlyTankCleaning');
|
||||
};
|
||||
|
||||
/** Check if a product is restricted based on customer attributes */
|
||||
export const isProductRestricted = (product) => {
|
||||
if (!product) return false;
|
||||
const productName = (product.name || '').toLowerCase();
|
||||
|
||||
// Check if the product has "Spot Free" in the name
|
||||
if (!canBuySpotFree() && productName.includes('spot free')) {
|
||||
return true;
|
||||
}
|
||||
// Check if the product has "Indvendig vask" in the name
|
||||
if (!canBuyInteriorCleaning() && productName.includes('indvendig vask')) {
|
||||
return true;
|
||||
}
|
||||
// Check if the product category is 5 (Tank Cleaning)
|
||||
if (product.category === 5) {
|
||||
if (!canBuyTankCleaning()) {
|
||||
return true;
|
||||
}
|
||||
if (!hasOnlyTankCleaning()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/** Check if an addon is restricted based on customer attributes */
|
||||
export const isAddonRestricted = (addon) => {
|
||||
if (!addon) return false;
|
||||
const addonName = (addon.name || '').toLowerCase();
|
||||
|
||||
// Check if the addon has "Spot Free" in the name
|
||||
if (!canBuySpotFree() && addonName.includes('spot free')) {
|
||||
return true;
|
||||
}
|
||||
// Check if the addon has "Indvendig vask" in the name
|
||||
if (!canBuyInteriorCleaning() && addonName.includes('indvendig vask')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export function loadOrderDetails(onAfterSuccess = null) {
|
||||
getOrderDetails().then((response) => {
|
||||
console.log(response);
|
||||
|
||||
Reference in New Issue
Block a user