Add handheld order handling and enhance transaction management with updated translations

- Introduced `handheld_pending_order` and `confirmation_needed` translations in `SessionUser.ObjectsGlobal.vue`.
- Added handheld status indicator and confirmation logic in `PosDepartmentStepMobileTransactionHistory.vue` and `PosDepartmentStepMobileButtonNextStep.vue`.
- Enhanced `nextStep` and `createOrder` functions across components to handle mobile-specific order creation.
- Updated order table visuals and logic in `ordersTable.vue` to display handheld status with warnings and confirmation prompts.
This commit is contained in:
Jeppe Bundgaard
2025-09-25 10:14:39 +02:00
parent c8e9fd820c
commit 9e4d238d4c
5 changed files with 38 additions and 8 deletions
@@ -116,6 +116,9 @@ const getOrderInvoiceStatusBarColor = (order) => {
: color_class = 'has-text-warning';
}
if (doesOrderHaveInvoiceCollection(order)) {
if (isPendingHandheld(order) && !order.completed_at) {
return 'has-text-warning'; // If the order is pending handheld, show a warning color
}
color_class = 'has-text-grey';
// Check if the invoice collection is closed
if (isOrderInvoiceCollectionClosed(order)) {
@@ -624,6 +627,10 @@ const isSystemOrder = (order) => {
return systemUserIds.includes(order?.cashier_id || -1);
};
const isPendingHandheld = (order) => {
return order.pending_handheld === true && order.completed_at === null;
};
</script>
<template>
@@ -779,6 +786,7 @@ const isSystemOrder = (order) => {
<td>
<ColorIndicator
v-bind:color_class="getOrderInvoiceStatusBarColor(order)"
v-bind:icon_class="isPendingHandheld(order) ? 'fas fa-mobile-alt' : 'fas fa-circle'"
v-bind:is_narrow="true"
v-bind:label="{
text: order.id,
@@ -829,6 +837,15 @@ const isSystemOrder = (order) => {
button_text: (order.completed_at !== null ? SessionUser.objects.global.language.yes : SessionUser.objects.global.language.no),
v_centered: true,
},
// Handheld status
...(isPendingHandheld(order) ? [{
text: SessionUser.objects.global.language.handheld_pending_order,
action: () => {},
button_classes: ['no-underline-text', 'is-text', 'has-text-warning'],
button: true,
button_text: SessionUser.objects.global.language.confirmation_needed,
v_centered: true,
}] : []),
],
buttons: [],
}"
@@ -209,7 +209,7 @@ const step2 = () => {
});
// If the customer is paying with a card, go to the payment step
if (isCustomerSelected() && getCustomerId() === 999) {
nextStep();
nextStep({isMobile: true});
return;
}
if (metadata.getBookingId() && metadata.getBookingId() > 0) {
@@ -264,7 +264,7 @@ const onClick = () => {
switch (step.value) {
case 1:
step1();
nextStep();
nextStep({isMobile: true});
break;
case 2:
step1();
@@ -1,5 +1,5 @@
<script setup lang="ts">
import {defineEmits, onMounted, onUnmounted} from "vue";
import {defineEmits, onMounted, onUnmounted, ref} from "vue";
import { setTransparency, setBackgroundColor, backgroundColors, setOverflow } from "@/components/viewport/page/headers/ViewportHeaderSettings.vue";
import { pos } from "../objects/PosDepartmentStepMobileFlow.vue";
import PosDepartmentStepMobileFixedBottomControl
@@ -8,6 +8,7 @@ import PosDepartmentStepMobileButtonNextStep
from "@/components/displays/department/pos/steps/mobile/elements/PosDepartmentStepMobileButtonNextStep.vue";
import SessionUser from "@/components/session/token/SessionUser.vue";
import {PosOrder} from "@/components/displays/department/pos/steps/mobile/objects/PosOrder.vue";
import ExpandableContentBox from "@/components/displays/boxes/ExpandableContentBox.vue";
// Define the close event to emit when the component is closed
const emit = defineEmits(["close"]);
onMounted(() => {
@@ -52,6 +53,8 @@ const refreshInterval = setInterval(() => {
onUnmounted(() => {
clearInterval(refreshInterval); // Clear the interval when the component is unmounted
});
const isExpanded = ref(false);
</script>
<template>
@@ -61,7 +64,14 @@ onUnmounted(() => {
<div v-for="(transaction, index) in pos.transactionHistory.get()" :key="index" class="column is-12">
<div class="box" @click="SessionUser.functions.redirectTo.department(transaction.department_id, 'modules/pos/orders/' + transaction.id)">
<div class="columns is-mobile is-vcentered">
<div class="column is-8">
<div class="column is-1">
<span class="icon" :class="transaction.pending_handheld ? 'has-text-warning' : 'has-text-success'">
<!-- If the pending_handheld is true, show a clock icon, else show a check icon -->
<i v-if="transaction.pending_handheld" class="fa-solid fa-clock"></i>
<i v-else class="fa-solid fa-check"></i>
</span>
</div>
<div class="column is-7">
<p class="is-size-6 has-text-weight-semibold">{{ transaction?.customer_name || transaction?.customer_id }}</p>
<p class="is-size-7 has-text-grey">{{ SessionUser.functions.date.toWordsWithTime(new Date(transaction.created_at)) }}</p>
@@ -28,6 +28,8 @@ export const ObjectsGlobal = {
add_other_product: "Tilføj andet produkt",
no_additional_items: "Ingen yderligere varer",
additional_items: "Yderligere varer",
handheld_pending_order: "Håndholdt",
confirmation_needed: "Bekræftelse nødvendig",
showing_of_separator: "af",
next: "Næste",
send_as_is: "Send som den er",
+5 -4
View File
@@ -59,7 +59,7 @@ export const setNextStepDelay = (delay) => {
};
/** Define the step functions */
export const nextStep = async () => {
export const nextStep = async (options = {isMobile: false}) => {
// Check if the delay has passed since the last step (To prevent double clicks)
if (nextStepDelay.value > 0) {
return;
@@ -70,7 +70,7 @@ export const nextStep = async () => {
clearErrors();
// If the current step is 1, create the order
if (step.value === 1) {
if (await createOrder()) {
if (await createOrder(options)) {
step.value++;
}
return;
@@ -209,7 +209,7 @@ export const getOrderReg1 = async (orderId) => {
};
/** Define the current order functions */
export const createOrder = () => {
export const createOrder = (options = {isMobile: false}) => {
const token = localStorage.getItem('token');
if (!token) {
return null;
@@ -221,7 +221,8 @@ export const createOrder = () => {
notes: order_notes.value,
reg_1: reg_1.value,
reg_2: reg_2.value,
reg_3: reg_3.value
reg_3: reg_3.value,
is_handheld: options.isMobile,
}, {
headers: {
Authorization: `Bearer ${token}`