diff --git a/POS/src/components/sale/InvoiceCart.vue b/POS/src/components/sale/InvoiceCart.vue index d91835154..b78f63706 100644 --- a/POS/src/components/sale/InvoiceCart.vue +++ b/POS/src/components/sale/InvoiceCart.vue @@ -1372,7 +1372,10 @@ const { sortedItems, CART_SORT_OPTIONS, CART_SORT_ICONS, toggleCartSortDropdown, 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 89ca3e85e..5d86d7bb6 100644 --- a/POS/src/components/settings/POSSettings.vue +++ b/POS/src/components/settings/POSSettings.vue @@ -358,6 +358,11 @@ :label="__('Allow Partial Payment')" :description="__('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 @@ -100,7 +100,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 9d1c4af62..9f8e8cdeb 100644 --- a/POS/src/stores/posEvents.js +++ b/POS/src/stores/posEvents.js @@ -266,7 +266,8 @@ export const usePOSEventsStore = defineStore('posEvents', () => { 'allow_return', 'allow_write_off_change', 'allow_partial_payment', - 'silent_print' + '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 9278faf4e..654ef5a8a 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, @@ -149,6 +150,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => { const showVariantsAsItems = computed(() => Boolean(settings.value.show_variants_as_items), ) + const cartLifo = computed(() => Boolean(settings.value.cart_lifo)) // Computed - Operations const allowSalesOrder = computed(() => @@ -320,6 +322,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, @@ -435,6 +438,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 059c04ea0..d9058b781 100644 --- a/pos_next/api/constants.py +++ b/pos_next/api/constants.py @@ -40,6 +40,7 @@ "enable_session_lock", "session_lock_timeout", "show_variants_as_items", + "cart_lifo", ] # Default POS Settings values @@ -70,4 +71,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",