Develop to Main - #358
Closed
Muhayustrid wants to merge 20 commits into
Closed
Conversation
Ports the ownership model from the selling_additional app: a Price Group owns one generated Price List, the unscoped Item Price rows on it, and the POS Profiles matching its outlets. Owner fields are renamed to the custom_pos_next_* namespace since this is a different app. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Both child tables exist only to be referenced by the Price Group parent, so they land together. Outlet carries read-only pos_profile and status columns the controller fills in on save. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The controller owns one generated Price List (PG-<name>), the unscoped Item Price rows on it, and the POS Profiles matching its outlets. All writes are targeted db.set_value rather than document saves: saving a Price List runs PriceList.on_update, which rewrites every Item Price on the list and can claim the global Selling default. Disabling keeps managed rows for re-enable; deleting restores every owned profile and retains the Price List disabled. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
hooks.py:fixtures exports only Role and Custom DocPerm, so the four owner fields cannot ship as a fixture and are upserted idempotently instead. Validation is left on so CustomField.validate computes idx from insert_after and catches fieldname conflicts. uninstall removes the same four. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
custom/*.json is a review mirror only, never applied. The pos_profile.json entries are additive: the bench exporter drops custom_brands_table because its module is unset, so the two new fields were merged into the committed file by hand instead. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
python -m unittest imports test modules before frappe.init, and bench run-tests dies on ERPNext bootstrap, so neither can run this app's tests. This inits and connects to the site first. sys.path[0] is rewritten to the app root because the nested pos_next/pos_next package would otherwise shadow pos_next.pos_next. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
31 tests ported from selling_additional covering enable/disable, ownership claim and restore, managed vs unmanaged Item Price rows, stock-UOM identity moves, lock ordering, and concurrent claims. They live outside the doctype folder on purpose: inside it frappe derives cls.doctype and generates test records, which imports ERPNext test utils and dies on a DuplicateEntryError for Standard Buying. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The modified timestamp is bumped because import_file_by_path skips any workspace file whose modified is not newer than the row in the database, which silently drops workspace edits on migrate. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The sidebar previously existed only as an auto-generated database row from after_app_install, which runs once and never updates. Shipping it as a standard app-level file makes frappe sync it on every migrate. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Replaces the computed quick-amount row with fixed banknote face values (2K/5K/10K/20K/50K/100K) plus a Pas button for the exact remaining, shown only when the selected method is cash and the currency is IDR. Cashiers tender physical notes, so face values match the workflow better than derived round-ups. Non-IDR and non-cash keep the existing quick amounts. Applied to both the desktop and mobile layouts. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Master carries base_price + non-stock parent item; child tables model mandatory items, choice groups (min_qty..max_qty units across options), per-option price adjustments, and outlet scoping. Replaces the pick-count-only promo model from selling_additional so optional mixed selections (e.g. up to 3 vouchers of any mix) are expressible. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
get_packages serves full definitions for offline caching; quote_package prices a selection. validate_invoice_packages re-quotes every package on Sales Invoice validate and recalculates totals, since Frappe runs the controller's validate before app hooks — otherwise a tampered payload is repriced but still charged the old grand_total. Returns are mirrored against the original invoice: package membership is re-derived through sales_invoice_item because the POS return payload strips the package fields, so a credit note cannot refund the priced parent while dropping the components. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Register validate_invoice_packages on Sales Invoice validate and manage the four pos_package* custom fields on Sales Invoice Item through the install.py contract (fixtures do not export Custom Field) and uninstall.py cleanup. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Client-side quote mirrors the Python pricing deterministically and is authoritative for offline previews; definitions are cached in IndexedDB via the offline worker so included items, per-option is_stock and UOM travel offline. Tests lock the mixed-max-3 and per-option-cap rules. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Package items carry a badge in the catalog and open a styled selection dialog: single-pick groups as toggles, multi-pick groups as steppers honoring min/max with live running total. Each instance owns its cart lines via package_instance (never merged with loose items), renders nested under the priced parent in the cart, and emits the pos_package fields for server re-quoting. Components use their real Item stock flag; batch/serial auto-pick at submission. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
feat: POS Package (paket bundling)
…d server quote In-session POS profile switches kept showing the previous outlet's packages (global hasFetched), and a server rejection (wrong outlet, expired, edited definition) fell back to a locally-valid quote — which the invoice later refuses at sync. The store is now keyed by profile and surfaces the rejection as an error the dialog can show. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
…ash denominations)
Forward-port from 9212350; resolved 3 conflicts by keeping both sides: - pos_next/_pn_run_tests.py: SITES_PATH env + sys.path/bench-root fixes - pos_next/install.py: pos_package + Price Group custom-field syncs - pos_next/uninstall.py: both cleanup lists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.