diff --git a/POS/src/components/sale/InvoiceCart.vue b/POS/src/components/sale/InvoiceCart.vue index aeefa004d..a1e05733f 100644 --- a/POS/src/components/sale/InvoiceCart.vue +++ b/POS/src/components/sale/InvoiceCart.vue @@ -1578,7 +1578,10 @@ const { handleCartSortToggle, getCartSortLabel, getCartSortIconState, -} = useCartSort(() => props.items); +} = useCartSort( + () => props.items, + computed(() => settingsStore.cartLifo), +); /** * ============================================================================ diff --git a/POS/src/components/settings/POSSettings.vue b/POS/src/components/settings/POSSettings.vue index c28c2d258..c4d8c8613 100644 --- a/POS/src/components/settings/POSSettings.vue +++ b/POS/src/components/settings/POSSettings.vue @@ -716,6 +716,11 @@ __('Enable partial payment for invoices') " /> + Array} itemsGetter - Getter (or ref) that returns the raw cart * items array. Typically `() => props.items`. */ -export function useCartSort(itemsGetter) { +export function useCartSort(itemsGetter, lifoMode = null) { // Normalise getter once — avoid typeof check on every access const getItems = typeof itemsGetter === "function" ? itemsGetter : () => itemsGetter.value; @@ -98,7 +98,15 @@ export function useCartSort(itemsGetter) { const items = getItems(); const field = cartSortBy.value; - if (!field) return items; + if (!field) { + // No explicit sort: honour the LIFO setting (newest added on top) + const lifo = lifoMode + ? typeof lifoMode === "function" + ? lifoMode() + : lifoMode.value + : false; + return lifo ? [...items].reverse() : items; + } const dir = cartSortOrder.value === "asc" ? 1 : -1; diff --git a/POS/src/stores/posEvents.js b/POS/src/stores/posEvents.js index d1df6518a..5149c95b7 100644 --- a/POS/src/stores/posEvents.js +++ b/POS/src/stores/posEvents.js @@ -273,6 +273,7 @@ export const usePOSEventsStore = defineStore("posEvents", () => { "allow_write_off_change", "allow_partial_payment", "silent_print", + "cart_lifo", ]; const salesChanges = salesFields.filter((field) => field in changes); if (salesChanges.length > 0) { diff --git a/POS/src/stores/posSettings.js b/POS/src/stores/posSettings.js index 49f4dcb43..b03a4fa63 100644 --- a/POS/src/stores/posSettings.js +++ b/POS/src/stores/posSettings.js @@ -35,6 +35,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => { display_discount_percentage: 0, display_discount_amount: 0, show_variants_as_items: 0, + cart_lifo: 0, // Operations allow_sales_order: 0, allow_select_sales_order: 0, @@ -113,6 +114,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => { ); const displayDiscountAmount = computed(() => Boolean(settings.value.display_discount_amount)); const showVariantsAsItems = computed(() => Boolean(settings.value.show_variants_as_items)); + const cartLifo = computed(() => Boolean(settings.value.cart_lifo)); // Computed - Operations const allowSalesOrder = computed(() => Boolean(settings.value.allow_sales_order)); @@ -258,6 +260,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => { display_discount_percentage: 0, display_discount_amount: 0, show_variants_as_items: 0, + cart_lifo: 0, allow_sales_order: 0, allow_select_sales_order: 0, create_only_sales_order: 0, @@ -373,6 +376,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => { displayDiscountPercentage, displayDiscountAmount, showVariantsAsItems, + cartLifo, // Computed - Operations allowSalesOrder, diff --git a/pos_next/api/constants.py b/pos_next/api/constants.py index 67ec4319f..1a292faa5 100644 --- a/pos_next/api/constants.py +++ b/pos_next/api/constants.py @@ -39,6 +39,7 @@ "enable_session_lock", "session_lock_timeout", "show_variants_as_items", + "cart_lifo", ] # Default POS Settings values @@ -69,4 +70,5 @@ "enable_session_lock": 0, "session_lock_timeout": 5, "show_variants_as_items": 0, + "cart_lifo": 0, } diff --git a/pos_next/pos_next/doctype/pos_settings/pos_settings.json b/pos_next/pos_next/doctype/pos_settings/pos_settings.json index 5aa983bbe..2f06bbc6e 100644 --- a/pos_next/pos_next/doctype/pos_settings/pos_settings.json +++ b/pos_next/pos_next/doctype/pos_settings/pos_settings.json @@ -37,6 +37,7 @@ "display_discount_percentage", "display_discount_amount", "show_variants_as_items", + "cart_lifo", "section_break_operations", "allow_sales_order", "allow_select_sales_order", @@ -303,6 +304,13 @@ "fieldtype": "Check", "label": "Show Variants as Items" }, + { + "default": "0", + "description": "Show most recently added item at the top of the cart", + "fieldname": "cart_lifo", + "fieldtype": "Check", + "label": "LIFO Cart Order (Newest on Top)" + }, { "collapsible": 1, "fieldname": "section_break_operations",