Skip to content

Move Develop changes to version-15 - #370

Open
MostafaKadry wants to merge 145 commits into
version-15from
develop
Open

MostafaKadry wants to merge 145 commits into
version-15from
develop

Conversation

@MostafaKadry

Copy link
Copy Markdown
Collaborator

No description provided.

harrishragavan and others added 30 commits March 11, 2026 16:13
Previously every payment method in the closing-shift reconciliation
started as null with _touched=false, forcing the cashier to click into
each row before the form could be submitted. Methods with no cash
collected still had to be touched manually.

Default closing_amount to 0 and mark rows as touched so the expected
amounts compute immediately and the shift can be closed without
manually zeroing untouched methods.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds a "LIFO Cart Order (Newest on Top)" POS setting. When enabled and
no explicit cart sort is active, the most recently added item is shown at
the top of the cart instead of the bottom — handy on long carts where the
cashier wants to see what was just scanned.

- New cart_lifo check field on POS Settings (default off) + backend
  constants (POS_SETTINGS_FIELDS / DEFAULT_POS_SETTINGS).
- posSettings store exposes a cartLifo computed.
- useCartSort accepts an optional lifoMode; reverses the list when LIFO is
  on and no sort column is selected. Explicit sorts are unaffected.
- InvoiceCart passes the setting through; toggle lives in the Sales
  Operations settings group so it takes effect live via reloadSettings().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Credit (Pay-on-Account) sales inflated the POS shift closing total.
`_process_invoice()` added the full `base_grand_total` of every invoice to
the sales summary (`grand_total`/`net_total`/`sales_total`) and the per-row
amount, regardless of how much was actually paid. The cash Payment
Reconciliation, however, is built only from real payment rows — so a pure
credit sale pushed Net Sales up by the full amount while contributing 0 to
the drawer, leaving the two figures inconsistent within a single shift.

For non-return invoices the money summaries and the per-row `grand_total`
now use the amount actually collected (`base_paid_amount`): a pure credit
sale contributes 0, a partial sale contributes only its down-payment, and
`net_total` is scaled by the paid ratio. The full invoice value is preserved
in `transaction_amount`; display-only `invoice_total` and
`outstanding_amount` are added for the dialog badge and stripped before the
child-table set. Returns, quantities and tax accrual are unchanged.

The Close Shift dialog now shows an "On Account" / "Partially Paid" badge and
an "Unpaid: {amount}" sub-line on rows collected for less than their invoice
value. Adds unit tests for the collected-money totals and an Arabic string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ft-default-zero

# Conflicts:
#	POS/src/components/ShiftClosingDialog.vue
…closing-total

# Conflicts:
#	POS/src/components/ShiftClosingDialog.vue
#	pos_next/pos_next/doctype/pos_closing_shift/pos_closing_shift.py
#	pos_next/pos_next/doctype/pos_closing_shift/test_pos_closing_shift.py
#	pos_next/translations/ar.csv
…rder

# Conflicts:
#	POS/src/components/sale/InvoiceCart.vue
#	POS/src/components/settings/POSSettings.vue
#	POS/src/composables/useCartSort.js
#	POS/src/stores/posEvents.js
#	POS/src/stores/posSettings.js
…nt-logic-pricing-rule

feat: implement min/max discount logic for pricing rules and promotional schemes
Updated the coupon validation logic to ensure a customer is selected before applying a coupon. Added a default empty string for the customer prop in the CouponDialog component and improved error handling to prompt the user if no customer is chosen.
…to-be-required

feat: make mobile number mandatory in CreateCustomerDialog
Leftover <<<<<<< HEAD marker (no matching ======= / >>>>>>>) broke the
Vite/vue-compiler-sfc build, failing CI.
…okups

POS Next's own price queries (search_by_barcode, get_item_variants, get_items
x2, get_items_bulk in pos_next/api/items.py) never respected Item Price's
valid_from/valid_upto window, unlike ERPNext core's own get_item_price. An
expired or not-yet-active price could still be served to the till.

Adds date-range filtering via one shared _item_price_validity_conditions()
predicate + _fetch_uom_prices_map()/_fetch_item_uom_prices() helpers reused
across all 5 call sites, instead of duplicating the check inline five times.
The predicate mirrors erpnext/stock/get_item_details.py's get_item_price
byte for byte (IfNull sentinel-date pattern, same valid_from-desc tie-break
for overlapping validity windows), verified directly against that source.

Deliberately does NOT import pos_next.promotions or anything else outside
this file — develop doesn't have that package yet, and an earlier attempt
to backport this by copying the whole file from staging (which does depend
on it) broke bench install-app for the entire branch. That attempt was
reverted; this is the same fix applied cleanly instead.

Verified: ruff clean, file + the doctype controller CI failed on both import
cleanly, and a live query against overlapping-validity Item Price rows on
the pos site returns the currently-valid rate, not the stale or future one.
…evelop.

Keep origin/develop baseline offers; GWP/auth Python stay in posnext_promotions. Free-bundle SI merge is no longer in the POS Next invoice class.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Updated App.vue to conditionally render AuthorizationDialog based on authGateInstalled.
- Modified SelectInput.vue to support multiple selections and improved UI for selected options.
- Refactored CreateCustomerDialog.vue to use requiresSplitCustomerName for customer name handling.
- Adjusted InvoiceCart.vue to utilize the new wallet API and removed Magento dependencies.
- Enhanced PromotionManagement.vue to include Gift Pool promotion type and related UI elements.
- Introduced applyOfflineGiftPool function in posCart.js for handling gift pool discounts.
- Updated various API endpoints to ensure compatibility with new promotional features.

Co-authored-by: Cursor <cursoragent@cursor.com>
MohamedAliSmk and others added 29 commits September 14, 2026 14:15
- Updated EditItemDialog.vue to prevent price-list refresh for locked free items and scale rates when changing UOM for promotional items.
- Modified InvoiceCart.vue to ensure free promotional rows remain promotion-owned, preventing unintended edits.
- Enhanced posCart.js to apply UOM changes while preserving rates for free promotional items, ensuring accurate pricing and user feedback.

This update aims to improve the handling of UOM changes and pricing integrity for promotional items in the sales process.
…ettings

- Added `merge_pos_settings` function to ensure runtime integration flags (`miraaya_installed`, `magento_loyalty_available`) are always present in POS settings, even when not defined in the database.
- Updated various modules to utilize the new function, ensuring that default settings are correctly merged with database values.
- Enhanced test cases to validate the behavior of merged settings, maintaining expected defaults and integration flags.

This update aims to improve the reliability of POS settings by ensuring critical flags are always available, enhancing integration capabilities.
… feature/thin-develop-split

Resolve CreateCustomerDialog JSDoc conflict; keep detailed ISD defaulting comment.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ofiles by creation date

feat(posCart): normalize pricing rules to prevent corruption from server responses
feat(authorization): prevent multiple gated requests from overwriting state
frappe-ui selects portal at z-100 behind the z-300 management dialog, so the option list never appears. Use SelectInput and raise portaled select menus so cashiers can filter and edit coupons.

Co-authored-by: Cursor <cursoragent@cursor.com>
…n-list

fix(promotions): show coupon filter dropdowns above the overlay
…not-reflected-in-pos-screen

Pn 111 item code settings not reflected in pos screen
…ify app behaviors

- Added a section on bootstrapping dependencies for the `pos_next` app, detailing commands to ensure required and optional apps are installed on a site.
- Included a table summarizing the behavior of `erpnext`, `posnext_promotions`, and `pos_next` during the bootstrap process.
- Removed redundant module entries from `modules.txt` for clarity.
pos.html referenced /assets/nexus_demo/...bundle.js directly. That URL never
changes and Frappe serves it with a 12-hour max-age, so any browser that had
already opened POS kept running the previous build for half a day — including
straight through the release that added the role switcher to the banner. The
Desk picked the change up immediately, which made it look like a POS bug rather
than a caching one.

bundled_asset() resolves the same file through assets.json, so the URL carries
the build hash and a new build is a new URL. include_style() also picks the
mirrored css-rtl build for an Arabic session, which the hardcoded path never did.

The tags moved to the end of <body>: vite parses <head>, and loose text there is
liable to be relocated into the body, which would separate these from the
conditional guarding them. That conditional keeps the tags off sites where
nexus_demo isn't installed, which is what the old onerror="this.remove()" was
for.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9wyGLvRjk5q4rjDRrmn6t
Load the demo banner by its hashed URL, not a fixed path
F4/F8/F9 only skipped when uiStore.isAnyDialogOpen was true, but the
session-lock screen and clear-cache overlay aren't registered in that
dialog tracker, so the shortcuts still fired underneath them. Also fix
F8 being a no-op when a customer is already assigned to the cart, since
the search input isn't rendered in that state.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
POSSale claimed the whole viewport with an inline height: 100vh; max-height:
100vh. Nothing above POS was accounted for, so when a host put chrome at the top
— Frappe's navbar, the Nexus demo countdown banner, anything that pads the body —
the page did not shrink, it moved. Its bottom ran off the screen by exactly the
height of that chrome, taking the cart's Checkout and Hold buttons with it.

On a desktop that is 48px and the buttons land underneath POSFooter, which is
position: fixed and therefore does not move with the rest of the page: they render,
they look enabled, and they swallow the click. On a phone the demo banner wraps to
two rows and it is 86px, which is more than the footer is tall, so the buttons go
off the bottom edge entirely. Either way the visitor cannot take a payment, which
on a point of sale is the whole job.

The page now sizes itself with flex — html/body/#app form a column and POSSale
fills what is left — so it is whatever the host actually leaves it, with no number
to keep in sync. 48px of banner, 86px of a two-row one, or nothing at all all work
out on their own.

The footer keeps position: fixed, and the integrity checks that enforce it are
untouched. It publishes its measured height as --pos-footer-h instead, and the page
reserves that band with padding-bottom, so the strip stays pinned and visible
without sitting on top of the buttons. The footer owns the number, so restyling it
moves the reservation with it rather than stranding a constant elsewhere.

Verified in a browser at 1280x900, 1440x800 and 390x844, in a demo session with
the banner up: Checkout on-screen, clear of the footer, no document overflow, and
a real click through to a submitted invoice (ACC-SINV-2026-00015). jsdom does no
layout, so there is no unit test that could have caught this.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ch-CLI-command-that-installs-dependency-apps-for-pos_next-on-a-given-site

docs: update README with bootstrap dependencies instructions and clarify app behaviors
…tcuts-f4-f8-f9

feat: implement F4/F8/F9 keyboard shortcuts
…-to-sales-invoice

[PN 118] feat(invoice): add sales person and coupon details to invoice display and print format
…ewport

fix(pos): the till hung off the bottom of the screen under host chrome
…invoice

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ries it in the GL

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
handleShiftOpened assigned the undeclared _initializedProfile (renamed to
_initializedKey in ecfddc6), so the ReferenceError skipped
startActivityTracking and the lock never fired until a page reload.
Starting tracking also went through the throttled resetTimer, so no idle
timer was armed until the first activity event.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Without it, migrate and install never create the POS Authorization tables,
so submitting any POS return raises TableMissingError.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ource

fix(credit): linked POS return credit booked on the wrong invoice; session lock after shift open

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants