Skip to content

Commits from April to 30 June - #302

Open
Hassan8848 wants to merge 77 commits into
pre-prod-developfrom
cherry-pick-april
Open

Commits from April to 30 June#302
Hassan8848 wants to merge 77 commits into
pre-prod-developfrom
cherry-pick-april

Conversation

@Hassan8848

Copy link
Copy Markdown

No description provided.

MrAnshuVasist and others added 30 commits June 1, 2026 17:18
…set repair.

(cherry picked from commit 147a5ee953f91cc943f5e28f732b490cdb4af437)
(cherry picked from commit cdbe8b909b8e81af94cba05407cf6776f70a8a20)
…119) (#51146)

Co-authored-by: NaviN <118178330+Navin-S-R@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: use serial and batch bundle to fetch incoming rate (#51119)
…eing booked against the asset

(cherry picked from commit bcf6deec9a73c43d68e13890cb445d5dd5433ec5)
(cherry picked from commit 8c35a6ecddf141e3cf928f06ecffee086ec9553d)
…119) (#51146)

Co-authored-by: NaviN <118178330+Navin-S-R@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: use serial and batch bundle to fetch incoming rate (#51119)
(cherry picked from commit 49f1688a51c54d0011b877c991587e4fd8454949)
(cherry picked from commit c1d50c492b4b24d1dca28db60b85619cf197e0e4)
(cherry picked from commit 671610db1e3307b53d73ea4e1e9c4dfd8417e048)
…y if already cancelled

(cherry picked from commit b1704ccef15c4f36cf41197f781f571cec8f0f11)

# Conflicts:
#	erpnext/assets/doctype/asset_value_adjustment/asset_value_adjustment.py
(cherry picked from commit 500c44e3f51fcfa6b8463de5c73110e3a5b73094)
* fix: validate asset movement transaction date (#52340)

* fix: validate asset transaction date

* fix: validate asset transaction date

* fix: add translation in validate_transaction_date

* test: test_movement_transaction_date

* fix: to ensure test reliability

(cherry picked from commit e98b68c38f303dda754b3139f247e3865a423a40)

* chore: fix conflicts

Removed unused imports and cleaned up code.

---------

Co-authored-by: Poojashree T R <159940572+22-poojashree@users.noreply.github.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 56def01240a050f654419309e1b015327676075f)
nabinhait and others added 30 commits July 2, 2026 13:48
Resolve 4 conflicts from Phase 7 service/mapper extraction vs upstream:
- asset.py: take extraction; repoint dangling make_asset_movement JS to mapper
- job_card: port upstream field_no_map(naming_series) into mapper.make_subcontracting_po
- sales_order: port upstream rows-index fix into mapper.make_delivery_note
- sales_invoice (Phase 7): take service delegations; port upstream SQL->QB/ORM
  changes for get_warehouse, get_all_mode_of_payments, get_discounting_status,
  clear_unallocated_mode_of_payments, and set_pos_fields(POS DN skip) into services
Both patterns are unchanged from develop but newly appear in the diff
because the refactoring relocated them:

- purchase_order/mapper.make_purchase_invoice_from_portal: portal flow
  needs commit before redirect (matches develop behaviour)
- asset_repair.on_cancel: ignore_linked_doctypes is a runtime cancel flag,
  not a persisted field
frappe-modifying-but-not-comitting anchors on the method definition, so the
suppression must sit on the def line (matching the convention used elsewhere
in the codebase); inner-line comments did not suppress it.
Relocate get_voucher_details, check_expense_account and get_debit_field_precision
from StockController to BaseStockGLComposer, where they are only used (by compose()
and AssetCapitalizationGLComposer). Call sites flipped from doc.X to self.X.

Inventory-account resolution (get_inventory_account_map/_dict, etc.) stays on the
controller: it is a doc-contract method called as doc.X from non-stock-composer code
(PI controller/composer, accounts/utils, repost_accounting_ledger), so it cannot fold
into BaseStockGLComposer. make_gl_entries / make_gl_entries_on_cancel / add_gl_entry
likewise stay (contract entry points).

Behaviour-preserving: ledger snapshots, subcontracting receipt and asset
capitalization suites stay green.
…orts

Update erpnext's own importers (asset depreciation, invoice discounting and the
JE tests) to import the builders from mapper.py directly. Drop
make_inter_company_journal_entry and make_reverse_journal_entry from the
backward-compat re-export in journal_entry.py -- they are not part of the
custom-app call surface; only the payment-entry builders remain re-exported.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Convert the remaining raw frappe.db.sql in the Assets module to frappe.qb / ORM so
the queries run on PostgreSQL as well as MariaDB. Faithful 1:1 conversions -- no
MariaDB behaviour change:

- asset.py (gl-entry / bom-cost fetches), asset_maintenance.py (team members),
  asset_movement.py (latest location/custodian), location.py (get_children)
- fixed_asset_register.py: the depreciation-amount aggregate groups by asset.name
  (the primary key) selecting only asset.name + Sum(gle.debit), which is valid under
  Postgres strict GROUP BY (PK functional dependency)

Tests: existing asset (61), asset_maintenance, asset_movement and location suites
pass on both engines; adds a test for the previously-untested Fixed Asset Register
report (covers the GROUP BY aggregate on both engines).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- cancel_movement_entries: filter the parent Asset Movement's docstatus via a qb join
  (as the original SQL did), instead of the child Asset Movement Item.docstatus. Behaviour
  is identical in normal flows (child docstatus is synced) but this is exactly faithful.
- get_maintenance_log: add a both-engine test for this previously-untested whitelisted
  endpoint. Confirms the frappe v16 dict aggregate field spec ({"COUNT": ...}) runs and
  returns correct per-status counts (no runtime crash).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The repo-wide query audit fixed runtime/source queries, but test files carry their
own raw SQL helpers that were never swept and only fail when the suite runs on
Postgres. Port the staging branch's already-green fixes for them:

- timestamp(posting_date, posting_time) (raw + qb Timestamp) -> posting_datetime /
  CombineDatetime (test_stock_ledger_entry, test_stock_balance, test_utils)
- HAVING <select-alias> -> qb .having(<expr>) (test_asset_capitalization, test_purchase_order)
- capital-cased identifiers ("Status", "Name") -> lowercase (test_delivery_note,
  test_purchase_order, test_employee)
- raw GL/SLE select helpers -> frappe.get_all / qb, with order-independent
  comparisons where account ordering is collation-dependent across engines
  (test_purchase_invoice, test_sales_invoice, test_payment_entry, test_asset,
  test_purchase_receipt, test_payment_request, test_repost_accounting_ledger,
  test_journal_entry)

All changes are test-only and behaviour-identical on MariaDB (lowercase column names
resolve the same; posting_datetime == timestamp(posting_date, posting_time); HAVING on
the expression is the same computation). Verified: the heavy modules pass on both
MariaDB and Postgres, and MariaDB output is unchanged.
The Fixed Asset Register report had no test file. Add tests for asset value
(net purchase amount, reduced by opening accumulated depreciation), the
status (In Location) and asset category filters, and group-by-asset-category
value totals.
…t.py

Use frappe.parse_json instead of json.loads so the whitelisted endpoints
accept native JSON types (list/dict/bool) in addition to JSON strings.
…er.py

Use frappe.parse_json instead of json.loads so the whitelisted endpoints
accept native JSON types (list/dict/bool) in addition to JSON strings.
…talization/asset_capitalization.py

Use frappe.parse_json instead of json.loads so the whitelisted endpoints
accept native JSON types (list/dict/bool) in addition to JSON strings.
Conservative cleanup of frappe.throw/msgprint messages per the message style
guide; meaning, severity, and .format() arguments are unchanged:

- index bare {} placeholders as {0}/{1}/... so translators can reorder
- move f-strings / .format() / concatenation out of _() (they break gettext
  extraction and never translate)
- wrap translatable dynamic values (DocType/Select labels) in _()
- fix grammar and colloquialisms
- drop no-op _() wrapping runtime-built strings

Part of #53976.
…register

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A deeper re-audit (with an adversarial skeptic) of the queries left raw
in the prior commit found more that have exact ORM equivalents:

- scalar SUM/MAX  -> frappe.qb + Sum/Max .run()[0][0]
- SUM ... GROUP BY -> frappe.qb .groupby().select(Sum().as_()) run(as_dict)
- name IN (values) -> get_all(filters={'f': ['in', ...]})
- sql_list(select col) -> get_all(pluck='col')
- bulk UPDATE ... = NULL/value -> frappe.db.set_value(filters, field, val)
- positional as_list reads -> get_all(..., as_list=True) (+ sorted())

Note: get_value(dt, filters, 'sum(x)') and get_all(fields=['sum(x)'])
are rejected by frappe ('SQL functions are not allowed as strings'), so
aggregates go through frappe.qb. get_all(as_list=True) returns a tuple
(not a list), so consumers that mutate use sorted().

All affected test modules pass on MariaDB.
refactor: convert convertible raw frappe.db.sql to ORM
The "Is Fully Depreciated" field was hidden on the Asset form (hidden: 1),
so it could never be set for manually entered existing assets.

Make it visible based on context:
- Existing Asset with Calculate Depreciation off -> visible and editable
- Calculate Depreciation on -> visible but read-only and forced unchecked
  (it is only meaningful for manually entered assets)

The unchecked value is enforced in the form script (immediate feedback on
toggle and on load) and in server-side validate() so it can never be saved
as checked while depreciation is being calculated.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
get_latest_location_and_custodian ordered by transaction_date DESC only; equal-dated movements left the current location/custodian engine-dependent. Add asm.name DESC tiebreaker so both engines pick the same movement.
make_depreciation_entry posts a Journal Entry per schedule row in a loop; the except only stored the error, so the next row's je.save()/submit() ran on the Postgres-poisoned txn (InFailedSqlTransaction). Savepoint per iteration + rollback(save_point=) before storing the error; the final raise of the collected error is unchanged. No-op on MariaDB.
…visibility

fix(asset): conditionally show Is Fully Depreciated field
fix: Postgres transaction-abort savepoints + div0/tiebreaker convergence fixes
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.