Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion POS/src/components/sale/InvoiceCart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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),
);

/**
* ============================================================================
Expand Down
6 changes: 6 additions & 0 deletions POS/src/components/settings/POSSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,11 @@
:label="__('Allow Partial Payment')"
:description="__('Enable partial payment for invoices')"
/>
<CheckboxField
v-model="settings.cart_lifo"
:label="__('LIFO Cart Order (Newest on Top)')"
:description="__('Show the most recently added item at the top of the cart instead of the bottom.')"
/>
<CheckboxField
v-model="settings.silent_print"
:label="__('Silent Print')"
Expand Down Expand Up @@ -617,6 +622,7 @@ const settings = ref({
silent_print: 0,
allow_negative_stock: 0,
tax_inclusive: 0,
cart_lifo: 0,
})

// Stock Sync Settings (localStorage persisted)
Expand Down
12 changes: 10 additions & 2 deletions POS/src/composables/useCartSort.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const SORT_LABEL_MAP = Object.freeze(
* @param {() => 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
Expand Down Expand Up @@ -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

Expand Down
3 changes: 2 additions & 1 deletion POS/src/stores/posEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions POS/src/stores/posSettings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(() =>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -435,6 +438,7 @@ export const usePOSSettingsStore = defineStore("posSettings", () => {
displayDiscountPercentage,
displayDiscountAmount,
showVariantsAsItems,
cartLifo,

// Computed - Operations
allowSalesOrder,
Expand Down
2 changes: 2 additions & 0 deletions pos_next/api/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"enable_session_lock",
"session_lock_timeout",
"show_variants_as_items",
"cart_lifo",
]

# Default POS Settings values
Expand Down Expand Up @@ -70,4 +71,5 @@
"enable_session_lock": 0,
"session_lock_timeout": 5,
"show_variants_as_items": 0,
"cart_lifo": 0,
}
8 changes: 8 additions & 0 deletions pos_next/pos_next/doctype/pos_settings/pos_settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Loading