Compare commits

...

736 Commits

Author SHA1 Message Date
Frappe PR Bot
a7eb24488e chore(release): Bumped to Version 16.8.3
## [16.8.3](https://github.com/frappe/erpnext/compare/v16.8.2...v16.8.3) (2026-03-10)

### Bug Fixes

* patch failing ([7149630](7149630eff))
2026-03-10 06:45:58 +00:00
rohitwaghchaure
0b30967556 Merge pull request #53274 from frappe/mergify/bp/version-16/pr-53273
fix: patch failing (backport #53272) (backport #53273)
2026-03-10 12:14:29 +05:30
Rohit Waghchaure
7149630eff fix: patch failing
(cherry picked from commit 6024c4a077)
(cherry picked from commit 1a62d324fd)
2026-03-10 06:42:47 +00:00
Frappe PR Bot
c39ee76946 chore(release): Bumped to Version 16.8.2
## [16.8.2](https://github.com/frappe/erpnext/compare/v16.8.1...v16.8.2) (2026-03-06)

### Bug Fixes

* stock balance report qty ([9e185b7](9e185b7ea9))
2026-03-06 08:35:12 +00:00
rohitwaghchaure
94a02b05fa Merge pull request #53211 from frappe/mergify/bp/version-16/pr-53208
fix: stock balance report qty (backport #53200) (backport #53208)
2026-03-06 14:03:44 +05:30
Rohit Waghchaure
9e185b7ea9 fix: stock balance report qty
(cherry picked from commit a15e5fdc4e)
(cherry picked from commit 699a683b8e)
2026-03-06 07:45:18 +00:00
Frappe PR Bot
0ab7a6e904 chore(release): Bumped to Version 16.8.1
## [16.8.1](https://github.com/frappe/erpnext/compare/v16.8.0...v16.8.1) (2026-03-05)

### Bug Fixes

* balance qty for inv dimension ([354723d](354723d3d5))
2026-03-05 11:58:55 +00:00
rohitwaghchaure
519657fe3e Merge pull request #53188 from frappe/mergify/bp/version-16/pr-53181
fix: balance qty for inv dimension (backport #52745) (backport #53181)
2026-03-05 17:27:21 +05:30
Rohit Waghchaure
354723d3d5 fix: balance qty for inv dimension
(cherry picked from commit a3eafe5b18)
(cherry picked from commit fb17a00fb6)
2026-03-05 11:40:41 +00:00
Frappe PR Bot
78aa4cf9f9 chore(release): Bumped to Version 16.8.0
# [16.8.0](https://github.com/frappe/erpnext/compare/v16.7.3...v16.8.0) (2026-03-03)

### Bug Fixes

* `Trial Balance` and `Consolidated Trial Balance` total row calculation (backport [#53014](https://github.com/frappe/erpnext/issues/53014)) ([#53015](https://github.com/frappe/erpnext/issues/53015)) ([8658956](865895649e))
* **accounts receivable:** include invoice payment terms template (backport [#51940](https://github.com/frappe/erpnext/issues/51940)) ([#53106](https://github.com/frappe/erpnext/issues/53106)) ([7e09bf3](7e09bf306a))
* **accounts:** add transaction time field ([2526876](2526876eaa))
* **accounts:** compute tax net_amount in JS controller ([429bd24](429bd245d1))
* **accounts:** round and convert net_amount to company currency in JS tax controller ([3f284f0](3f284f0c55))
* **accounts:** set posting time to get incoming rate ([8b3c5ba](8b3c5baa9e))
* allow allowed roles to bypass over billing validation ([c274b7c](c274b7cc2e))
* avoid circular dependency ([#53109](https://github.com/frappe/erpnext/issues/53109)) ([7d950f7](7d950f71da))
* broekn link of docs in asset onboarding ([5c48f74](5c48f74d4c))
* **budget-variance-report:** validate 'budget_against' filter ([f2ff0de](f2ff0de296))
* correct sle voucher_type comparison in get_ref_doctype ([788cd82](788cd82b4b))
* ensure cache is cleared on fiscal year update and trash ([2495cb8](2495cb8b2a))
* ensure contacts are processed only if present in create_prospect_against_crm_deal ([58fbb2f](58fbb2f4d7))
* handle html email template separately in RFQ to avoid jinja context error ([3178736](317873621a))
* **manufacturing:** ignore sales order validation for subassembly item ([2daf9f4](2daf9f4ce7))
* old stock reco entries causing issue in the stock balance report ([ea5ad31](ea5ad3179c))
* opening qty in stock balance ([1f2342c](1f2342cf4b))
* pass company in test case using make_quality_inspections ([417e8a4](417e8a4371))
* patch to complete onboarding stpes for existing records ([941a78e](941a78e1a8))
* **payment entry:** round unallocated amount ([b76e0c6](b76e0c645b))
* **payment_entry:** fix precision for `total_allocated_amount` and `base_total_allocated_amount` ([c61c748](c61c748cbd))
* populate mr owner and set po owner as fallback ([acdb8f2](acdb8f2b78))
* **postgres:** avoid UNSIGNED cast in customer autoname ([d922213](d922213dd7))
* **pricing_rule:** strict validation of `transaction_type` ([396727e](396727e26f))
* remove read-only property from Sales Invoice Timesheet Table ([f632c5c](f632c5c796))
* reposting creation slow for GL entries ([ab7e33f](ab7e33f83d))
* same reposting entry picked by multiple rq jobs ([c28568f](c28568f4fd))
* **selling:** handle selling price validation for FG item ([c7928a0](c7928a0749))
* serial no status for Disassemble entry ([dc0592a](dc0592a905))
* set company based expense account ([25c134d](25c134d11c))
* **stock:** pass company to avoid document naming rule issue in QI ([d61ad3b](d61ad3bd95))
* **stock:** validate company for receipt documents and expense accounts ([c6e0eb6](c6e0eb6d17))
* use conversion factor when creating stock entry from pick list ([f939e98](f939e980a6))
* use stock qty instead of qty when creating stock entry from MR ([1e44787](1e4478765a))
* use the correct precision value in stock reco ([c92fd26](c92fd26e1b))
* validate warehouse of SABB for draft entry ([b8de82f](b8de82f0e4))
* voucher detail no in SABB ([744d7a2](744d7a2793))

### Features

* UOM query filter for opportunity items ([6727c86](6727c86d0a))

### Performance Improvements

* add index on reference_purchase_receipt column ([664f1f1](664f1f1675))
2026-03-03 17:57:53 +00:00
diptanilsaha
28c5fbdb78 Merge pull request #53116 from frappe/version-16-hotfix 2026-03-03 23:26:23 +05:30
Mihir Kandoi
282d8b1b28 Merge pull request #53138 from frappe/mergify/bp/version-16-hotfix/pr-52784
fix(stock): validate company for receipt documents and expense accounts (backport #52784)
2026-03-03 21:41:25 +05:30
Mihir Kandoi
6eed4df7d9 Merge pull request #53136 from frappe/mergify/bp/version-16-hotfix/pr-53132
fix(selling): handle selling price validation for FG item  (backport #53132)
2026-03-03 21:41:03 +05:30
Mihir Kandoi
e2824e1dc5 Merge pull request #53134 from frappe/mergify/bp/version-16-hotfix/pr-53070
fix: handle html email template separately in RFQ to avoid jinja cont… (backport #53070)
2026-03-03 21:25:04 +05:30
Sudharsanan11
4350c6b9e3 test(stock): add test to validate company for receipts and expense accounts
(cherry picked from commit d58171987c)
2026-03-03 15:47:20 +00:00
Sudharsanan11
25c134d11c fix: set company based expense account
(cherry picked from commit d54d0c25a2)
2026-03-03 15:47:20 +00:00
Sudharsanan11
c6e0eb6d17 fix(stock): validate company for receipt documents and expense accounts
(cherry picked from commit 15dfc08a31)
2026-03-03 15:47:19 +00:00
Mihir Kandoi
41b9566dec Merge pull request #53125 from frappe/mergify/bp/version-16-hotfix/pr-53123
fix: serial no status for Disassemble entry (backport #53123)
2026-03-03 21:12:42 +05:30
Mihir Kandoi
8a13522590 Merge pull request #53131 from frappe/mergify/bp/version-16-hotfix/pr-53084
fix(manufacturing): ignore sales order validation for subassembly item (backport #53084)
2026-03-03 21:11:52 +05:30
kavin-114
7713d25b7e test: add unit test for FG Item selling price validation
(cherry picked from commit 723993fdf6)
2026-03-03 15:40:48 +00:00
kavin-114
c7928a0749 fix(selling): handle selling price validation for FG item
System checks valuation rate in incoming_rate field, since SO has it in valuation_rate field of item row,
need to handle the field name dynamically based upon the doctype name in Selling Controller.

(cherry picked from commit 4335318482)
2026-03-03 15:40:48 +00:00
Mihir Kandoi
bffb7cfef3 Merge pull request #53129 from frappe/mergify/bp/version-16-hotfix/pr-53037
fix(stock): pass company to avoid document naming rule issue in QI (backport #53037)
2026-03-03 21:08:14 +05:30
Pugazhendhi Velu
317873621a fix: handle html email template separately in RFQ to avoid jinja context error
(cherry picked from commit 49d363b174)
2026-03-03 15:36:53 +00:00
Mihir Kandoi
a399b8522d Merge pull request #53127 from frappe/mergify/bp/version-16-hotfix/pr-53099
fix: populate mr owner and set po owner as fallback (backport #53099)
2026-03-03 20:55:54 +05:30
Mihir Kandoi
3e8ebf8c14 chore: resolve conflicts 2026-03-03 20:44:40 +05:30
Sudharsanan11
2daf9f4ce7 fix(manufacturing): ignore sales order validation for subassembly item
(cherry picked from commit 6b1aac4aee)
2026-03-03 15:11:58 +00:00
kavin-114
417e8a4371 fix: pass company in test case using make_quality_inspections
(cherry picked from commit 397de1274f)
2026-03-03 15:10:48 +00:00
kavin-114
3844982824 test: add unit test to handle company condition in naming rule
(cherry picked from commit 4c39cf2d65)
2026-03-03 15:10:47 +00:00
kavin-114
d61ad3bd95 fix(stock): pass company to avoid document naming rule issue in QI
When a Document Naming Rule is configured in QI with a condition based on the company,
the system was not passing the company value properly. As a result, the naming rule
condition was skipped and the document name was generated using the default series.

This fix ensures that the company is passed correctly so that the configured
Document Naming Rule is evaluated and applied as expected.

(cherry picked from commit 74def423ed)

# Conflicts:
#	erpnext/controllers/stock_controller.py
2026-03-03 15:10:47 +00:00
kavin-114
acdb8f2b78 fix: populate mr owner and set po owner as fallback
(cherry picked from commit bdf4e51da3)
2026-03-03 15:09:33 +00:00
Rohit Waghchaure
dc0592a905 fix: serial no status for Disassemble entry
(cherry picked from commit 81acefa8ad)
2026-03-03 13:24:22 +00:00
Shariq Ansari
d74833d9fc Merge pull request #53122 from frappe/mergify/bp/version-16-hotfix/pr-53119
fix: do not create contact if not passed from crm (backport #53119)
2026-03-03 03:59:41 -08:00
shariquerik
58fbb2f4d7 fix: ensure contacts are processed only if present in create_prospect_against_crm_deal
(cherry picked from commit 800810d23d)
2026-03-03 11:43:45 +00:00
diptanilsaha
3217defaf5 Merge pull request #53055 from frappe/pot_version-16-hotfix_2026-03-01
chore: update POT file
2026-03-03 16:08:53 +05:30
diptanilsaha
e6704f4b73 Merge pull request #52998 from frappe/mergify/bp/version-16-hotfix/pr-52997
fix(payment_entry): set precision for `total_allocated_amount` and `base_total_allocated_amount` (backport #52997)
2026-03-03 15:48:16 +05:30
diptanilsaha
32c33631a6 chore: fix onboarding doctype merge conflicts (#53118) 2026-03-03 10:16:34 +00:00
diptanilsaha
0787c62cbc Merge branch 'version-16' into version-16-hotfix 2026-03-03 15:24:26 +05:30
diptanilsaha
a35521c14d Merge pull request #53114 from frappe/mergify/bp/version-16-hotfix/pr-53110
fix(pricing_rule): strict validation of `transaction_type` (backport #53110)
2026-03-03 15:19:54 +05:30
diptanilsaha
e4ce6e4e6f refactor: renamed args to pricing_ctx in set_transaction_type for clarity
(cherry picked from commit 6342e78305)
2026-03-03 09:30:51 +00:00
diptanilsaha
396727e26f fix(pricing_rule): strict validation of transaction_type
(cherry picked from commit 7ec0354a79)
2026-03-03 09:30:50 +00:00
diptanilsaha
ad3411ba01 Merge pull request #53111 from frappe/mergify/bp/version-16-hotfix/pr-53109
fix: avoid circular dependency (backport #53109)
2026-03-03 15:00:44 +05:30
Vishnu Priya Baskaran
7d950f71da fix: avoid circular dependency (#53109)
(cherry picked from commit d2e04750b5)
2026-03-03 09:03:25 +00:00
mergify[bot]
7e09bf306a fix(accounts receivable): include invoice payment terms template (backport #51940) (#53106)
Co-authored-by: Ravibharathi <131471282+ravibharathi656@users.noreply.github.com>
2026-03-03 12:07:57 +05:30
rohitwaghchaure
109433f37a Merge pull request #53086 from frappe/mergify/bp/version-16-hotfix/pr-53072
fix(accounts): set posting time to get incoming rate (backport #53072)
2026-03-02 21:58:09 +05:30
rohitwaghchaure
35336350ca Merge pull request #53098 from frappe/mergify/bp/version-16-hotfix/pr-53093
fix: opening qty in stock balance (backport #53093)
2026-03-02 21:43:29 +05:30
rohitwaghchaure
97f6b3a3b5 Merge pull request #53092 from frappe/mergify/bp/version-16-hotfix/pr-53087
perf: add index on reference_purchase_receipt column (backport #53087)
2026-03-02 21:38:02 +05:30
Rohit Waghchaure
1f2342cf4b fix: opening qty in stock balance
(cherry picked from commit d7fdab99cb)
2026-03-02 15:19:56 +00:00
rohitwaghchaure
3ec3cd512c Merge pull request #53090 from frappe/mergify/bp/version-16-hotfix/pr-53082
fix: validate warehouse of SABB for draft entry (backport #53082)
2026-03-02 17:43:51 +05:30
rohitwaghchaure
bf44f466ad chore: fix conflicts 2026-03-02 14:38:55 +05:30
kavin-114
664f1f1675 perf: add index on reference_purchase_receipt column
(cherry picked from commit 8c94396ad9)
2026-03-02 09:08:44 +00:00
rohitwaghchaure
b4a5bbc7e2 chore: fix conflicts 2026-03-02 14:38:28 +05:30
Rohit Waghchaure
b8de82f0e4 fix: validate warehouse of SABB for draft entry
(cherry picked from commit 9b8f685c82)
2026-03-02 08:53:09 +00:00
Sudharsanan11
8b3c5baa9e fix(accounts): set posting time to get incoming rate
(cherry picked from commit c5b3673a30)
2026-03-02 08:16:32 +00:00
Sudharsanan11
2526876eaa fix(accounts): add transaction time field
(cherry picked from commit 9538a9870c)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.json
#	erpnext/selling/doctype/sales_order/sales_order.json
2026-03-02 08:16:32 +00:00
Diptanil Saha
fe721f48fc Merge pull request #53081 from frappe/mergify/bp/version-16-hotfix/pr-53079
fix(budget-variance-report): validate 'budget_against' filter (backport #53079)
2026-03-02 12:17:52 +05:30
rohitwaghchaure
11b22d4d95 Merge pull request #53077 from frappe/mergify/bp/version-16-hotfix/pr-53050
fix: voucher detail no in SABB (backport #53050)
2026-03-02 12:09:34 +05:30
diptanilsaha
f2ff0de296 fix(budget-variance-report): validate 'budget_against' filter
(cherry picked from commit 79d0708ea7)
2026-03-02 06:31:35 +00:00
Mihir Kandoi
2ed795bc9c Merge pull request #53078 from frappe/mergify/bp/version-16-hotfix/pr-53047
fix: remove read-only property from Sales Invoice Timesheet Table (backport #53047)
2026-03-02 11:37:32 +05:30
trustedcomputer
f632c5c796 fix: remove read-only property from Sales Invoice Timesheet Table
(cherry picked from commit b9d95711a2)
2026-03-02 05:25:05 +00:00
Rohit Waghchaure
744d7a2793 fix: voucher detail no in SABB
(cherry picked from commit c37a56ec89)
2026-03-02 04:24:00 +00:00
Mihir Kandoi
88b4699025 Merge pull request #53069 from frappe/mergify/bp/version-16-hotfix/pr-53067
fix: use the correct precision value in stock reco (backport #53067)
2026-03-01 21:37:18 +05:30
Mihir Kandoi
c92fd26e1b fix: use the correct precision value in stock reco
(cherry picked from commit 36726b0f7b)
2026-03-01 15:52:17 +00:00
Mihir Kandoi
746ca73006 Merge pull request #53066 from frappe/mergify/bp/version-16-hotfix/pr-53062
fix: correct sle voucher_type comparison in get_ref_doctype (backport #53062)
2026-03-01 21:03:52 +05:30
Sanjesh
788cd82b4b fix: correct sle voucher_type comparison in get_ref_doctype
(cherry picked from commit cffb59ae73)
2026-03-01 15:16:44 +00:00
Mihir Kandoi
8ed2d45729 Merge pull request #53061 from frappe/mergify/bp/version-16-hotfix/pr-53057
fix: allow allowed roles to bypass over billing validation (backport #53057)
2026-03-01 16:03:42 +05:30
Mihir Kandoi
8752b2f767 Merge pull request #53059 from frappe/mergify/bp/version-16-hotfix/pr-53052
fix: use stock qty instead of qty when creating stock entry from MR (backport #53052)
2026-03-01 15:50:24 +05:30
Mihir Kandoi
c274b7cc2e fix: allow allowed roles to bypass over billing validation
(cherry picked from commit 04127019f9)
2026-03-01 10:18:22 +00:00
Mihir Kandoi
1c4e20f5ed Merge pull request #53054 from frappe/mergify/bp/version-16-hotfix/pr-53051
fix: use conversion factor when creating stock entry from pick list (backport #53051)
2026-03-01 15:26:44 +05:30
Mihir Kandoi
1e4478765a fix: use stock qty instead of qty when creating stock entry from MR
(cherry picked from commit 30c3ff2efe)
2026-03-01 09:51:54 +00:00
frappe-pr-bot
b26631d8b1 chore: update POT file 2026-03-01 09:43:26 +00:00
Mihir Kandoi
f939e980a6 fix: use conversion factor when creating stock entry from pick list
(cherry picked from commit 5f12b0db3f)
2026-03-01 09:40:37 +00:00
rohitwaghchaure
31a28ed570 Merge pull request #53034 from frappe/mergify/bp/version-16-hotfix/pr-52988
fix: same reposting entry picked by multiple rq jobs (backport #52988)
2026-02-28 09:04:49 +05:30
Rohit Waghchaure
c28568f4fd fix: same reposting entry picked by multiple rq jobs
(cherry picked from commit 4dfbacfd92)
2026-02-28 02:06:33 +00:00
rohitwaghchaure
8b7692db57 Merge pull request #53021 from frappe/mergify/bp/version-16-hotfix/pr-53013
fix: old stock reco entries causing issue in the stock balance report (backport #53013)
2026-02-27 15:31:32 +05:30
Rohit Waghchaure
ea5ad3179c fix: old stock reco entries causing issue in the stock balance report
(cherry picked from commit 0874cbc268)
2026-02-27 09:27:00 +00:00
Mihir Kandoi
41ff3191f5 Merge pull request #53018 from frappe/mergify/bp/version-16-hotfix/pr-53012 2026-02-27 13:59:07 +05:30
Thomas antony
6727c86d0a feat: UOM query filter for opportunity items
Add UOM query filter based on item code in opportunity form.

(cherry picked from commit b33f06701c)
2026-02-27 08:23:48 +00:00
mergify[bot]
865895649e fix: Trial Balance and Consolidated Trial Balance total row calculation (backport #53014) (#53015)
Co-authored-by: diptanilsaha <diptanil@frappe.io>
2026-02-27 07:40:41 +00:00
diptanilsaha
c61c748cbd fix(payment_entry): fix precision for total_allocated_amount and base_total_allocated_amount
Co-authored-by: Ahuahuachi <Ahuahuachi@users.noreply.github.com>
(cherry picked from commit d82a0a9455)
2026-02-26 09:25:01 +00:00
ruthra kumar
862659e396 Merge pull request #52996 from frappe/mergify/bp/version-16-hotfix/pr-52630
fix(account): compute tax net_amount in JS controller (backport #52630)
2026-02-26 14:00:06 +05:30
Frappe PR Bot
e671f5a3ac chore(release): Bumped to Version 16.7.3
## [16.7.3](https://github.com/frappe/erpnext/compare/v16.7.2...v16.7.3) (2026-02-26)

### Bug Fixes

* **payment entry:** round unallocated amount ([e7e5285](e7e52851d6))
2026-02-26 08:29:46 +00:00
ruthra kumar
0d0014c872 Merge pull request #52994 from frappe/mergify/bp/version-16/pr-52188
fix(payment entry): round unallocated amount (backport #52188)
2026-02-26 13:58:15 +05:30
Luis Mendoza
3f284f0c55 fix(accounts): round and convert net_amount to company currency in JS tax controller
(cherry picked from commit b10b205394)
2026-02-26 08:18:12 +00:00
Luis Mendoza
adb4023ba4 style: prettier formatting
(cherry picked from commit 485166b668)
2026-02-26 08:18:12 +00:00
Luis Mendoza
429bd245d1 fix(accounts): compute tax net_amount in JS controller
(cherry picked from commit 153ad99f85)
2026-02-26 08:18:11 +00:00
ravibharathi656
e7e52851d6 fix(payment entry): round unallocated amount
(cherry picked from commit b0d6751777)
2026-02-26 08:06:09 +00:00
ruthra kumar
fc7d9de979 Merge pull request #52993 from frappe/mergify/bp/version-16-hotfix/pr-52188
fix(payment entry): round unallocated amount (backport #52188)
2026-02-26 13:25:03 +05:30
ravibharathi656
b76e0c645b fix(payment entry): round unallocated amount
(cherry picked from commit b0d6751777)
2026-02-26 07:38:22 +00:00
Frappe PR Bot
e1782901e4 chore(release): Bumped to Version 16.7.2
## [16.7.2](https://github.com/frappe/erpnext/compare/v16.7.1...v16.7.2) (2026-02-26)

### Bug Fixes

* broekn link of docs in asset onboarding ([5d2822d](5d2822df97))
2026-02-26 06:48:40 +00:00
rohitwaghchaure
7c8e071d24 Merge pull request #52986 from frappe/mergify/bp/version-16/pr-52985
fix: broken link of docs in asset onboarding (backport #52983) (backport #52985)
2026-02-26 12:16:36 +05:30
Frappe PR Bot
5d86e9697a chore(release): Bumped to Version 16.7.1
## [16.7.1](https://github.com/frappe/erpnext/compare/v16.7.0...v16.7.1) (2026-02-26)

### Bug Fixes

* patch to complete onboarding stpes for existing records ([c3700f1](c3700f1b31))
2026-02-26 06:03:21 +00:00
rohitwaghchaure
19143bfe9b Merge branch 'version-16' into mergify/bp/version-16/pr-52985 2026-02-26 11:33:03 +05:30
rohitwaghchaure
2b664387d7 Merge pull request #52984 from frappe/mergify/bp/version-16/pr-52969
fix: patch to complete onboarding stpes for existing records (backport #52967) (backport #52969)
2026-02-26 11:31:45 +05:30
rohitwaghchaure
38c49dfed6 chore: fix conflicts
Updated the modified date in learn_asset.json.
2026-02-26 11:31:16 +05:30
rohitwaghchaure
6bebf51087 chore: fix conflicts 2026-02-26 11:30:57 +05:30
Rohit Waghchaure
5d2822df97 fix: broekn link of docs in asset onboarding
(cherry picked from commit 1cdf439e38)
(cherry picked from commit 5c48f74d4c)

# Conflicts:
#	erpnext/assets/module_onboarding/asset_onboarding/asset_onboarding.json
#	erpnext/assets/onboarding_step/learn_asset/learn_asset.json
2026-02-26 05:54:16 +00:00
rohitwaghchaure
72a5528b56 Merge pull request #52985 from frappe/mergify/bp/version-16-hotfix/pr-52983
fix: broken link of docs in asset onboarding (backport #52983)
2026-02-26 11:24:00 +05:30
Rohit Waghchaure
5c48f74d4c fix: broekn link of docs in asset onboarding
(cherry picked from commit 1cdf439e38)
2026-02-26 05:36:06 +00:00
rohitwaghchaure
76d27877c2 chore: fix conflicts
(cherry picked from commit 8f922382e4)
2026-02-26 05:21:53 +00:00
Rohit Waghchaure
c3700f1b31 fix: patch to complete onboarding stpes for existing records
(cherry picked from commit d90ec49241)

# Conflicts:
#	erpnext/patches.txt
(cherry picked from commit 941a78e1a8)
2026-02-26 05:21:53 +00:00
rohitwaghchaure
44c9fccd34 Merge pull request #52969 from frappe/mergify/bp/version-16-hotfix/pr-52967
fix: patch to complete onboarding stpes for existing records (backport #52967)
2026-02-26 10:51:05 +05:30
ruthra kumar
0732f741cc Merge pull request #52975 from frappe/mergify/bp/version-16-hotfix/pr-52973
fix: ensure cache is cleared on fiscal year update and trash (backport #52973)
2026-02-26 10:00:19 +05:30
mergify[bot]
2349ebbb29 Merge pull request #52977 from frappe/mergify/bp/version-16-hotfix/pr-52952
fix: customer field made mandatory for sales invoice (backport #52952)
2026-02-25 15:47:17 +00:00
ljain112
2495cb8b2a fix: ensure cache is cleared on fiscal year update and trash
(cherry picked from commit 39b0e3522a)
2026-02-25 14:36:08 +00:00
rohitwaghchaure
8f922382e4 chore: fix conflicts 2026-02-25 18:13:42 +05:30
rohitwaghchaure
a864ca5c17 Merge pull request #52962 from frappe/mergify/bp/version-16-hotfix/pr-52957
fix: reposting creation slow for GL entries (backport #52957)
2026-02-25 18:09:10 +05:30
Rohit Waghchaure
941a78e1a8 fix: patch to complete onboarding stpes for existing records
(cherry picked from commit d90ec49241)

# Conflicts:
#	erpnext/patches.txt
2026-02-25 12:30:24 +00:00
ruthra kumar
cd465e1dbd refactor: Journal Entry form cleanup (backport #52780) (#52961)
refactor: Journal Entry form cleanup

(cherry picked from commit 73d5aa35a1)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2026-02-25 16:27:03 +05:30
Rohit Waghchaure
ab7e33f83d fix: reposting creation slow for GL entries
(cherry picked from commit d9ac198bad)
2026-02-25 10:34:25 +00:00
ruthra kumar
0f59da89cf refactor: Journal Entry form cleanup
(cherry picked from commit 73d5aa35a1)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json
2026-02-25 15:51:58 +05:30
ruthra kumar
5cc95a32c2 Merge pull request #52959 from frappe/mergify/bp/version-16-hotfix/pr-51558
fix(postgres): avoid UNSIGNED cast in customer autoname (backport #51558)
2026-02-25 15:10:50 +05:30
ruthra kumar
c98263cd77 Merge pull request #52950 from frappe/mergify/bp/version-16-hotfix/pr-52507
refactor: toggle for UTM parameters (backport #52507)
2026-02-25 15:10:30 +05:30
Matt Howard
d922213dd7 fix(postgres): avoid UNSIGNED cast in customer autoname
(cherry picked from commit 323636b396)
2026-02-25 09:21:10 +00:00
ruthra kumar
270b09f936 chore: resolve conflicts 2026-02-25 14:42:52 +05:30
ruthra kumar
4acf404ae5 refactor: better description on toggle
(cherry picked from commit 20af546b26)
2026-02-25 06:54:16 +00:00
ruthra kumar
0433f73b03 refactor: utm analytics section delivery note
(cherry picked from commit 578783af8e)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/delivery_note.json
2026-02-25 06:54:16 +00:00
ruthra kumar
2bb8c7c74e refactor: utm section in opportunity
(cherry picked from commit 223d560b32)
2026-02-25 06:54:16 +00:00
ruthra kumar
3a8967b2a7 refactor: utm analytics section in lead
(cherry picked from commit 71e8941285)
2026-02-25 06:54:16 +00:00
ruthra kumar
fc0a07b3b1 refactor: utm analytics section in pos profile
(cherry picked from commit 7de0ca164d)

# Conflicts:
#	erpnext/accounts/doctype/pos_profile/pos_profile.json
2026-02-25 06:54:15 +00:00
ruthra kumar
08df2a755e refactor: utm section pos invoice
(cherry picked from commit 0bafa347a5)
2026-02-25 06:54:15 +00:00
ruthra kumar
964d75bd3e refactor: utm section in sales invoice
(cherry picked from commit 678d261f40)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
2026-02-25 06:54:15 +00:00
ruthra kumar
774aa2b78f refactor: utm section in sales order
(cherry picked from commit c00bf7df6a)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.json
2026-02-25 06:54:14 +00:00
ruthra kumar
6539e443a5 refactor: hide UTM parameters
(cherry picked from commit aaf5f923b0)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.json
2026-02-25 06:54:14 +00:00
Frappe PR Bot
ca9f9de39f chore(release): Bumped to Version 16.7.0
# [16.7.0](https://github.com/frappe/erpnext/compare/v16.6.1...v16.7.0) (2026-02-25)

### Bug Fixes

* **`fiscal_year_company`:** made `company` field mandatory ([54bed64](54bed64356))
* **`fiscal_year`:** `Fiscal Year` auto-generation and notification ([92c2c7b](92c2c7bf82))
* Add handling for Sales Invoice Item quantity field ([f6a1ea8](f6a1ea804a))
* add missing property_type ([dd41f2c](dd41f2ceb7))
* add purchase invoice as well ([2d864bb](2d864bb599))
* addresses portal (backport [#52712](https://github.com/frappe/erpnext/issues/52712)) ([#52786](https://github.com/frappe/erpnext/issues/52786)) ([d7b61b9](d7b61b945f))
* **asset:** handle partial asset sales by splitting remaining quantity (backport [#51363](https://github.com/frappe/erpnext/issues/51363)) ([#52394](https://github.com/frappe/erpnext/issues/52394)) ([10be8f1](10be8f19e2))
* avoid duplicate taxes and charges rows in payment entry (backport [#52178](https://github.com/frappe/erpnext/issues/52178)) ([#52319](https://github.com/frappe/erpnext/issues/52319)) ([e6f7a7e](e6f7a7e979))
* better permissions on make payment request ([a5c83dd](a5c83dd11e))
* bug with comparison regarding `None` values and empty string ([66d1b7c](66d1b7c837))
* check gl account of an associated bank account in bank transaction ([746b5d9](746b5d96de))
* enfore permission on make_payment_request ([8184599](81845992a6))
* fiscal year notification subject ([e8c5d57](e8c5d5710d))
* get employee email with priority if preferred is not set ([116361c](116361c1dc))
* ignore permissions instead of saving parent ([715dbc0](715dbc0093))
* inconsistent label name between parent and child ([b56c444](b56c444f18))
* item code shows undefined ([0fd9fc4](0fd9fc48f3))
* link field displays incorrect value when empty ([b67d42e](b67d42ee58))
* **manufacturing:** remove delete query of job card & batch and serial no  ([#52840](https://github.com/frappe/erpnext/issues/52840)) ([9ff924e](9ff924e831))
* **manufacturing:** set pick list purpose while creating it from work order ([131e279](131e279a0c))
* **manufacturing:** update status for work order before calculating planned qty ([61d339c](61d339cfa7))
* material request on receive notification condition ([785773b](785773b0ac))
* permission issue for quotation item during update item ([bccca6f](bccca6f58e))
* populate doctypes to be ignored table in validate ([237e458](237e4583e2))
* prevent precision errors in  discount distribution with inclusive tax ([0e2e89c](0e2e89c355))
* **Purchase Receipt:** copy project from first row when adding items ([77da330](77da3306b5))
* remove form tour for sales and purchase order ([aac7fc3](aac7fc30d5))
* remove supplier invoice date/posting date validation ([cfad7e1](cfad7e17f1))
* reservation based on field should be read only in SRE ([a499b7e](a499b7e046))
* sales and purchase modules forms clean-up (backport [#52875](https://github.com/frappe/erpnext/issues/52875)) ([#52911](https://github.com/frappe/erpnext/issues/52911)) ([2177098](217709836b))
* **sales-order:** update quotation status while cancelling sales order ([#52822](https://github.com/frappe/erpnext/issues/52822)) ([3a0f90c](3a0f90c433))
* sensible insufficient stock message in pick list ([dbe2a87](dbe2a87a84))
* setup fails to set abbr to departments ([b15db05](b15db05ef8))
* skip empty dimension values in exchange gain loss ([780b626](780b626ae5))
* standalone sales invoice return should not fallback to item master for valuation rate ([6e1a808](6e1a8083a5))
* supplier_type appears multiple times ([9a2eb91](9a2eb91eec))
* test cases related to default letterhead change ([1e64dea](1e64dea6a0))
* typo ([d0c2cc8](d0c2cc848c))
* typo ([0c4b9ea](0c4b9ea9ca))
* unable to submit subcontracting order if created from material request ([c5bc92d](c5bc92d50e))
* unhide book_advance_payments_in_separate_party_account check field in Payment Entry doctype ([13d153c](13d153c196))
* update items fetches wrong item code ([3355c60](3355c60c79))
* update modified timestamp in json ([74a3965](74a3965a12))
* use stock qty instead of qty when updating transferred qty in WO ([90e61ab](90e61abff4))
* user permission on reports (backport [#52709](https://github.com/frappe/erpnext/issues/52709)) ([#52757](https://github.com/frappe/erpnext/issues/52757)) ([893683a](893683a512))
* **work_order:** update returned qty ([c4ba3c9](c4ba3c9c4b))

### Features

* default letterhead and print format ([4adcc1c](4adcc1c521))
* **Journal Entry Account:** add Bank Transaction as Reference Type (backport [#52760](https://github.com/frappe/erpnext/issues/52760)) ([#52816](https://github.com/frappe/erpnext/issues/52816)) ([2c5bdef](2c5bdefd13))
* module onboarding ([858119f](858119f907))
* **payment request:** create payment request as per payment schedules ([751a081](751a081253))
* **payment_request:** add option to calculate request amount using payment schedule ([298ea33](298ea33922))
* retrieve employee basic contact information ([f701407](f701407e23))
* retrieve employee contact details ([94f9f8b](94f9f8b30a))
* standard print format for Sales Order and Purchase Invoice ([222f51b](222f51b4d0))
2026-02-25 06:34:28 +00:00
ruthra kumar
44b935b845 Merge pull request #52925 from frappe/version-16-hotfix
chore: release v16
2026-02-25 12:01:35 +05:30
Mihir Kandoi
16e29d8571 Merge pull request #52944 from frappe/mergify/bp/version-16-hotfix/pr-52942 2026-02-25 11:04:43 +05:30
Mihir Kandoi
5db413d802 Merge pull request #52946 from frappe/mergify/bp/version-16-hotfix/pr-52945
fix: item code shows undefined (backport #52945)
2026-02-25 10:49:46 +05:30
Mihir Kandoi
0fd9fc48f3 fix: item code shows undefined
(cherry picked from commit 9ef7f05712)
2026-02-25 04:55:59 +00:00
Mihir Kandoi
265342d40a chore: clearer description for internal transfer at arms length
(cherry picked from commit bd9e5e97d7)
2026-02-25 04:43:22 +00:00
Khushi Rawat
cc604d4921 Merge pull request #52938 from frappe/mergify/bp/version-16-hotfix/pr-52889
feat: default letterhead and print format (backport #52889)
2026-02-25 00:39:54 +05:30
Khushi Rawat
1311664f52 Merge pull request #52939 from frappe/mergify/bp/version-16-hotfix/pr-52861
feat: standard print format for Sales Order and Purchase Invoice (backport #52861)
2026-02-25 00:37:37 +05:30
khushi8112
f4ec356dfb refactor: add translation and fix typo
(cherry picked from commit cbea4493c1)
2026-02-24 15:53:41 +00:00
khushi8112
222f51b4d0 feat: standard print format for Sales Order and Purchase Invoice
(cherry picked from commit 371efce88a)
2026-02-24 15:53:41 +00:00
khushi8112
1e64dea6a0 fix: test cases related to default letterhead change
(cherry picked from commit 8a2cb96c2a)
2026-02-24 15:52:54 +00:00
khushi8112
b21acec711 test: debugging the issue
(cherry picked from commit 570f574758)
2026-02-24 15:52:54 +00:00
khushi8112
dd41f2ceb7 fix: add missing property_type
(cherry picked from commit fbf5529ddd)
2026-02-24 15:52:54 +00:00
khushi8112
4adcc1c521 feat: default letterhead and print format
(cherry picked from commit 0ea22f9796)
2026-02-24 15:52:53 +00:00
Mihir Kandoi
6975fa185c Merge pull request #52937 from frappe/mergify/bp/version-16-hotfix/pr-52724 2026-02-24 20:57:08 +05:30
ljain112
6902fd6b33 refactor: use postprocess in mapped_doc to update items in subcontracting controller
(cherry picked from commit 1d3d09f48c)
2026-02-24 15:07:59 +00:00
ruthra kumar
9336f1f9a4 Merge pull request #52934 from frappe/mergify/bp/version-16-hotfix/pr-51777
feat: making payment requests based on payment schedule (backport #51777)
2026-02-24 18:55:13 +05:30
ruthra kumar
aaba93bd03 Merge pull request #52933 from frappe/mergify/bp/version-16-hotfix/pr-52824
refactor: separate construction of chart related data from `get_columns()` (backport #52824)
2026-02-24 18:46:27 +05:30
Jatin3128
751a081253 feat(payment request): create payment request as per payment schedules
(cherry picked from commit e476dff842)
2026-02-24 13:09:27 +00:00
Jatin3128
298ea33922 feat(payment_request): add option to calculate request amount using payment schedule
(cherry picked from commit 60108590b0)
2026-02-24 13:09:26 +00:00
ruthra kumar
807463e90c Merge pull request #52929 from frappe/mergify/bp/version-16-hotfix/pr-52029
fix: prevent precision errors in  discount distribution with inclusive tax (backport #52029)
2026-02-24 18:39:16 +05:30
Harsh Patadia
27c03fee1c refactor: separate construction of chart related data from get_columns() (#52824)
* fix: avoid hardcoded column slicing for Profit & Loss chart data

* refactor: improve parameter naming and reduce code repetion by using same function get_period_columns()

* refactor: improved parameter naming in get_data() and get_chart_data()

(cherry picked from commit bdcb2c1512)
2026-02-24 12:37:51 +00:00
rohitwaghchaure
ffe77ba1e7 Merge pull request #52931 from frappe/mergify/bp/version-16-hotfix/pr-52930
fix: remove form tour for sales and purchase order (backport #52930)
2026-02-24 17:45:33 +05:30
Rohit Waghchaure
aac7fc30d5 fix: remove form tour for sales and purchase order
(cherry picked from commit ed7315d78e)
2026-02-24 11:53:56 +00:00
ljain112
0e2e89c355 fix: prevent precision errors in discount distribution with inclusive tax
(cherry picked from commit 2068299766)
2026-02-24 11:29:05 +00:00
rohitwaghchaure
d8f6a007a0 Merge pull request #52922 from frappe/mergify/bp/version-16-hotfix/pr-52839
feat: module onboarding (backport #52839)
2026-02-24 16:09:40 +05:30
Rohit Waghchaure
858119f907 feat: module onboarding
(cherry picked from commit 792a1a7ab7)
2026-02-24 07:20:09 +00:00
ruthra kumar
033c9fc57d Merge pull request #52920 from frappe/mergify/bp/version-16-hotfix/pr-52363
fix: unhide book_advance_payments_in_separate_party_account check fie… (backport #52363)
2026-02-24 12:21:48 +05:30
ruthra kumar
d743ee9e1c Merge pull request #52919 from frappe/mergify/bp/version-16-hotfix/pr-52822
fix(sales-order): update quotation status while cancelling sales order (backport #52822)
2026-02-24 12:11:58 +05:30
Shllokkk
13d153c196 fix: unhide book_advance_payments_in_separate_party_account check field in Payment Entry doctype
(cherry picked from commit 5793322c30)
2026-02-24 06:26:55 +00:00
Sowmya
3a0f90c433 fix(sales-order): update quotation status while cancelling sales order (#52822)
* fix(sales-order): update quotation status while cancelling sales order

* test: validate quotation status

* chore: remove submit

(cherry picked from commit d638f3e033)
2026-02-24 06:18:37 +00:00
mergify[bot]
217709836b fix: sales and purchase modules forms clean-up (backport #52875) (#52911)
* fix: sales and purchase modules forms clean-up

(cherry picked from commit 0e356dc2e3)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
#	erpnext/buying/doctype/purchase_order/purchase_order.json
#	erpnext/selling/doctype/sales_order/sales_order.json
#	erpnext/stock/doctype/delivery_note/delivery_note.json

* chore: fix conflicts

* chore: fix conflicts

Removed unnecessary fields and updated the modified date.

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

Removed UTM Analytics section and column break from delivery note JSON configuration. Updated the modified timestamp.

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2026-02-24 11:28:34 +05:30
ruthra kumar
3663fc4f64 Merge pull request #52908 from frappe/mergify/bp/version-16-hotfix/pr-52896
fix: skip empty dimension values in exchange gain loss (backport #52896)
2026-02-23 21:24:31 +05:30
ravibharathi656
780b626ae5 fix: skip empty dimension values in exchange gain loss
(cherry picked from commit 7df9d951c6)
2026-02-23 15:36:47 +00:00
Mihir Kandoi
bbf1a94024 Merge pull request #52906 from frappe/mergify/bp/version-16-hotfix/pr-52544
fix(stock): improve error message when serial no is reserved via SRE (backport #52544)
2026-02-23 21:03:12 +05:30
Mihir Kandoi
8a44638939 Merge pull request #52904 from frappe/mergify/bp/version-16-hotfix/pr-52764
fix: populate doctypes to be ignored table in validate (backport #52764)
2026-02-23 20:45:09 +05:30
Imesha Sudasingha
fb8f085885 Merge pull request #52544 from one-highflyer/fix/improve-reserved-serial-no-error-message
fix(stock): improve error message when serial no is reserved via SRE

(cherry picked from commit 71248ff40b)
2026-02-23 15:13:17 +00:00
l0gesh29
237e4583e2 fix: populate doctypes to be ignored table in validate
(cherry picked from commit 60d2f2d304)
2026-02-23 14:51:15 +00:00
Diptanil Saha
d71a0d76e6 Merge pull request #52902 from frappe/mergify/bp/version-16-hotfix/pr-52891
fix: notifications (backport #52891)
2026-02-23 19:53:07 +05:30
diptanilsaha
e8c5d5710d fix: fiscal year notification subject
(cherry picked from commit 3e87059939)
2026-02-23 14:08:13 +00:00
diptanilsaha
785773b0ac fix: material request on receive notification condition
(cherry picked from commit 96aa37eff5)
2026-02-23 14:08:13 +00:00
Mihir Kandoi
c51bc69d58 Merge pull request #52901 from frappe/mergify/bp/version-16-hotfix/pr-52892
fix: link field displays incorrect value when empty (backport #52892)
2026-02-23 19:11:48 +05:30
Mihir Kandoi
b67d42ee58 fix: link field displays incorrect value when empty
(cherry picked from commit db00860662)
2026-02-23 13:37:44 +00:00
Mihir Kandoi
62f587318c Merge pull request #52898 from frappe/mergify/bp/version-16-hotfix/pr-52878
fix: standalone sales invoice return should not fallback to item mast… (backport #52878)
2026-02-23 19:07:01 +05:30
Mihir Kandoi
6e1a8083a5 fix: standalone sales invoice return should not fallback to item master for valuation rate
(cherry picked from commit a85a0aef52)
2026-02-23 13:19:55 +00:00
ruthra kumar
407bf7ec2e Merge pull request #52895 from frappe/mergify/bp/version-16-hotfix/pr-52812
fix: bank account mismatch error on reverse transaction reconciliation (backport #52812)
2026-02-23 18:28:38 +05:30
Diptanil Saha
4ac4292de4 Merge pull request #52893 from frappe/mergify/bp/version-16-hotfix/pr-50301
refactor:  fetch employee contact details in realtime in Payment Entry (backport #50301)
2026-02-23 18:11:21 +05:30
ervishnucs
746b5d96de fix: check gl account of an associated bank account in bank transaction
(cherry picked from commit 8fe0bf4ba3)
2026-02-23 12:36:45 +00:00
Abdeali Chharchhoda
5c9f9517d6 refactor: method to get employee contact without permission check
(cherry picked from commit 58cdb9503b)
2026-02-23 12:22:57 +00:00
Abdeali Chharchhoda
63975c8c00 refactor: use common method to get employee contacts
(cherry picked from commit ec1eb6d222)
2026-02-23 12:22:57 +00:00
Abdeali Chharchhoda
116361c1dc fix: get employee email with priority if preferred is not set
(cherry picked from commit 7b89c12470)
2026-02-23 12:22:57 +00:00
Abdeali Chharchhoda
0f8f8c2066 refactor: add validation for missing employee parameter
(cherry picked from commit b8e06b9636)
2026-02-23 12:22:56 +00:00
Abdeali Chharchhoda
123b7191fc refactor: fetch employee contact details in realtime
(cherry picked from commit 2ea6508fa5)
2026-02-23 12:22:56 +00:00
Abdeali Chharchhoda
94f9f8b30a feat: retrieve employee contact details
(cherry picked from commit a41297d841)
2026-02-23 12:22:56 +00:00
Abdeali Chharchhoda
f701407e23 feat: retrieve employee basic contact information
(cherry picked from commit 4ad1474e32)
2026-02-23 12:22:56 +00:00
Abdeali Chharchhoda
2b9af6a641 chore: Removing unused import
(cherry picked from commit 87c59f471c)
2026-02-23 12:22:55 +00:00
ruthra kumar
79cf614118 Merge pull request #52887 from frappe/mergify/bp/version-16-hotfix/pr-52840
fix(manufacturing): remove delete query of job card & batch and serial no  (backport #52840)
2026-02-23 17:39:28 +05:30
Sudharsanan Ashok
9ff924e831 fix(manufacturing): remove delete query of job card & batch and serial no (#52840)
* fix(manufacturing): remove delete query of batch and serial no

* fix(manufacturing): remove delete query of job card

* fix: remove delete function call for work order

(cherry picked from commit 8b2a971019)
2026-02-23 11:29:36 +00:00
mergify[bot]
8437355072 Merge pull request #52876 from frappe/mergify/bp/version-16-hotfix/pr-52399
refactor: Better organizing of the fields in various doctypes (backport #52399)
2026-02-23 16:54:54 +05:30
Khushi Rawat
1f82be4383 Merge pull request #52881 from frappe/mergify/bp/version-16-hotfix/pr-52879
fix: typo (backport #52879)
2026-02-23 16:04:05 +05:30
mergify[bot]
e6f7a7e979 fix: avoid duplicate taxes and charges rows in payment entry (backport #52178) (#52319)
Co-authored-by: Dharanidharan S <dharanidharans1328@gmail.com>
fix: avoid duplicate taxes and charges rows in payment entry (#52178)
2026-02-23 10:21:06 +00:00
Mihir Kandoi
c2666bbcac Merge pull request #52883 from frappe/mergify/bp/version-16-hotfix/pr-52880
fix(work_order): update returned qty on work order (backport #52880)
2026-02-23 15:49:48 +05:30
Khushi Rawat
74a3965a12 fix: update modified timestamp in json 2026-02-23 15:44:59 +05:30
Pandiyan37
c4ba3c9c4b fix(work_order): update returned qty
(cherry picked from commit b7f45e6963)
2026-02-23 10:04:09 +00:00
mahsem
d0c2cc848c fix: typo
(cherry picked from commit 2b72aab671)
2026-02-23 09:54:15 +00:00
Mihir Kandoi
af4c626238 Merge pull request #52874 from frappe/mergify/bp/version-16-hotfix/pr-52871
fix: use stock qty instead of qty when updating transferred qty in WO (backport #52871)
2026-02-23 14:55:47 +05:30
rohitwaghchaure
aab7759afc Merge pull request #52872 from frappe/mergify/bp/version-16-hotfix/pr-52504
refactor: form cleanup for sales order (backport #52504)
2026-02-23 14:01:39 +05:30
Mihir Kandoi
90e61abff4 fix: use stock qty instead of qty when updating transferred qty in WO
(cherry picked from commit 8e14249335)
2026-02-23 07:53:20 +00:00
ruthra kumar
d1c142cce8 refactor: form cleanup for sales order
(cherry picked from commit 93d1716eb5)
2026-02-23 07:49:58 +00:00
rohitwaghchaure
54e2fa0231 Merge pull request #52868 from frappe/mergify/bp/version-16-hotfix/pr-52534
refactor: supplier form cleanup (backport #52534)
2026-02-23 12:12:57 +05:30
rohitwaghchaure
ddfdc1a4e7 Merge pull request #52867 from frappe/mergify/bp/version-16-hotfix/pr-52508
refactor: form cleanup for stock and manufacturing doctypes (backport #52508)
2026-02-23 12:12:43 +05:30
rohitwaghchaure
4b0d2558d7 chore: fix conflicts
Refactor purchase order JSON structure by cleaning up field order and removing unnecessary fields.
2026-02-23 11:30:53 +05:30
rohitwaghchaure
7223acf266 Merge pull request #52866 from frappe/mergify/bp/version-16-hotfix/pr-52469
refactor: form cleanup for master doctypes related to stock module (backport #52469)
2026-02-23 11:27:27 +05:30
rohitwaghchaure
5b30e6e96b Merge pull request #52865 from frappe/mergify/bp/version-16-hotfix/pr-52392
refactor: Cleanup buying module related doctypes (backport #52392)
2026-02-23 11:26:51 +05:30
rohitwaghchaure
8cd12e37cd chore: fix conflicts 2026-02-23 11:26:31 +05:30
rohitwaghchaure
9a2eb91eec fix: supplier_type appears multiple times 2026-02-23 11:24:13 +05:30
rohitwaghchaure
7a680e6070 chore: fix conflicts
Refactored supplier form by reorganizing field order and removing unnecessary fields.
2026-02-23 11:05:07 +05:30
rohitwaghchaure
5e31eb3d77 chore: fix conflicts 2026-02-23 10:58:12 +05:30
Rohit Waghchaure
3eb838a6a2 refactor: supplier form cleanup
(cherry picked from commit bd521d9089)

# Conflicts:
#	erpnext/buying/doctype/supplier/supplier.json
2026-02-23 05:28:09 +00:00
Rohit Waghchaure
575fd4988b refactor: form cleanup for stock and manufacturing doctypes
(cherry picked from commit bf20ecca60)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.json
2026-02-23 05:27:39 +00:00
Rohit Waghchaure
24fbd8add9 refactor: form cleanup for master doctypes related to stock module
(cherry picked from commit 6c49d5dc7d)
2026-02-23 05:27:10 +00:00
Rohit Waghchaure
91e9867fb1 refactor: Cleanup buying module forms
(cherry picked from commit f3ea1863ae)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2026-02-23 05:26:46 +00:00
Mihir Kandoi
069d6d5269 Merge pull request #52863 from frappe/mergify/bp/version-16-hotfix/pr-52803
fix(manufacturing): update closed status for current work order before calculating planned qty (backport #52803)
2026-02-23 07:47:08 +05:30
Sudharsanan11
d9d76fceeb test(manufacturing): add test to validate the planned qty
(cherry picked from commit cfbdfcf515)
2026-02-23 02:01:42 +00:00
Sudharsanan11
61d339cfa7 fix(manufacturing): update status for work order before calculating planned qty
(cherry picked from commit 4d40c84a31)
2026-02-23 02:01:41 +00:00
MochaMind
843c0d4acf chore: update POT file (#52858) 2026-02-22 13:19:38 +01:00
mergify[bot]
2c5bdefd13 feat(Journal Entry Account): add Bank Transaction as Reference Type (backport #52760) (#52816)
* feat: add Bank Transaction as Reference Type to Journal Entry Account (#52760)

* feat: add Bank Transaction as Reference Type to Journal Entry Account

* fix: take care of existing property setters

* fix: cancelling Bank Transactions should still be possible

* fix: handle blank options in patch

* fix: hide Reference Due Date for Bank Transaction

(cherry picked from commit 387fb1b202)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry_account/journal_entry_account.json

* chore: resolve conflicts

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2026-02-21 15:43:47 +01:00
Diptanil Saha
a4ee85e89c Merge pull request #52848 from frappe/mergify/bp/version-16-hotfix/pr-52842
refactor: `Fiscal Year` cleanup (backport #52842)
2026-02-21 13:00:22 +05:30
diptanilsaha
92c2c7bf82 fix(fiscal_year): Fiscal Year auto-generation and notification
(cherry picked from commit 4c76786ce4)
2026-02-21 07:13:05 +00:00
diptanilsaha
54bed64356 fix(fiscal_year_company): made company field mandatory
(cherry picked from commit 94fb7e11b4)
2026-02-21 07:13:05 +00:00
diptanilsaha
82170dfd07 refactor: Fiscal Year DocType cleanup
(cherry picked from commit 74ac28fc70)
2026-02-21 07:13:04 +00:00
Mihir Kandoi
595b5e7dae Merge pull request #52847 from frappe/mergify/bp/version-16-hotfix/pr-52845 2026-02-21 12:41:15 +05:30
Mihir Kandoi
cfad7e17f1 fix: remove supplier invoice date/posting date validation
(cherry picked from commit 7cff0ba626)
2026-02-21 06:55:30 +00:00
Mihir Kandoi
00ebeec94e Merge pull request #52837 from frappe/mergify/bp/version-16-hotfix/pr-52835
fix: inconsistent label name between parent and child (backport #52835)
2026-02-20 17:17:01 +05:30
Mihir Kandoi
b56c444f18 fix: inconsistent label name between parent and child
(cherry picked from commit d6e1ca0f10)
2026-02-20 11:28:53 +00:00
Mihir Kandoi
9d2ccd7246 Merge pull request #52827 from frappe/mergify/bp/version-16-hotfix/pr-52821
fix: sensible insufficient stock message in pick list (backport #52821)
2026-02-20 14:40:55 +05:30
Mihir Kandoi
d06e611c72 Merge pull request #52829 from frappe/mergify/bp/version-16-hotfix/pr-52825
fix: update items fetches wrong item code (backport #52825)
2026-02-20 14:27:47 +05:30
Mihir Kandoi
3355c60c79 fix: update items fetches wrong item code
(cherry picked from commit ba96d37c11)
2026-02-20 08:54:31 +00:00
Mihir Kandoi
dbe2a87a84 fix: sensible insufficient stock message in pick list
(cherry picked from commit 1352dc79bb)
2026-02-20 08:53:52 +00:00
Mihir Kandoi
f78317a79a Merge pull request #52819 from frappe/mergify/bp/version-16-hotfix/pr-52811
fix: permission issue for quotation item during update item (backport #52811)
2026-02-19 23:22:37 +05:30
Mihir Kandoi
0c4b9ea9ca fix: typo
(cherry picked from commit 732c98b72f)
2026-02-19 17:28:53 +00:00
Mihir Kandoi
715dbc0093 fix: ignore permissions instead of saving parent
(cherry picked from commit 6342e9a3e2)
2026-02-19 17:28:53 +00:00
Nishka Gosalia
bccca6f58e fix: permission issue for quotation item during update item
(cherry picked from commit 58b8af0fa8)
2026-02-19 17:28:53 +00:00
Mihir Kandoi
72a0d82147 Merge pull request #52806 from frappe/mergify/bp/version-16-hotfix/pr-52804
fix(Purchase Receipt): copy project from first row when adding items (backport #52804)
2026-02-19 14:03:27 +05:30
Marc Ramser
77da3306b5 fix(Purchase Receipt): copy project from first row when adding items
Adds `items_add` method to copy expense_account, cost_center and project from first row to newly added items, matching Purchase Invoice behavior.

(cherry picked from commit 21423676c9)
2026-02-19 08:32:20 +00:00
Mihir Kandoi
636414c0e4 Merge pull request #52798 from frappe/mergify/bp/version-16-hotfix/pr-52792
fix: unable to submit subcontracting order if created from material r… (backport #52792)
2026-02-19 13:59:24 +05:30
Mihir Kandoi
c5bc92d50e fix: unable to submit subcontracting order if created from material request
(cherry picked from commit 37323480dd)
2026-02-19 13:44:30 +05:30
Mihir Kandoi
c669387b82 Merge pull request #52796 from frappe/mergify/bp/version-16-hotfix/pr-52794
fix: reservation based on field should be read only in SRE (backport #52794)
2026-02-19 12:57:07 +05:30
Mihir Kandoi
a499b7e046 fix: reservation based on field should be read only in SRE
(cherry picked from commit 21452b4c6e)
2026-02-19 05:10:44 +00:00
Frappe PR Bot
9a0b54c649 chore(release): Bumped to Version 16.6.1
## [16.6.1](https://github.com/frappe/erpnext/compare/v16.6.0...v16.6.1) (2026-02-19)

### Bug Fixes

* better permissions on make payment request ([78fc942](78fc9424d9))
2026-02-19 05:04:10 +00:00
ruthra kumar
1f78a9fa6c Merge pull request #52790 from frappe/mergify/bp/version-16/pr-52763
fix: better permissions on make payment request (backport #52763)
2026-02-19 10:32:36 +05:30
Mihir Kandoi
17062e0154 Merge pull request #52788 from frappe/mergify/bp/version-16-hotfix/pr-52490
fix: Add handling for Sales Invoice Item quantity field (backport #52490)
2026-02-19 10:15:48 +05:30
ruthra kumar
78fc9424d9 fix: better permissions on make payment request
(cherry picked from commit f36962fc58)
2026-02-19 04:32:31 +00:00
Mihir Kandoi
2d864bb599 fix: add purchase invoice as well
(cherry picked from commit 1fc2eddf6f)
2026-02-19 04:13:06 +00:00
Thomas antony
f6a1ea804a fix: Add handling for Sales Invoice Item quantity field
Add handling for Sales Invoice Item quantity field

(cherry picked from commit edfcaee99b)
2026-02-19 04:13:05 +00:00
mergify[bot]
d7b61b945f fix: addresses portal (backport #52712) (#52786)
* fix: addresses portal

(cherry picked from commit e317ab1479)

# Conflicts:
#	erpnext/patches.txt

* chore: resolve conflicts

---------

Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
2026-02-19 04:11:04 +00:00
Mihir Kandoi
b6a2284003 Merge pull request #52775 from frappe/mergify/bp/version-16-hotfix/pr-52628
fix(manufacturing): set pick list purpose while creating it from work order (backport #52628)
2026-02-18 15:32:12 +05:30
Sudharsanan11
131e279a0c fix(manufacturing): set pick list purpose while creating it from work order
(cherry picked from commit 23ccc2a8c5)
2026-02-18 09:46:02 +00:00
ruthra kumar
cc7de7e66e Merge pull request #52768 from frappe/mergify/bp/version-16-hotfix/pr-52763
fix: better permissions on make payment request (backport #52763)
2026-02-18 12:46:20 +05:30
ruthra kumar
a5c83dd11e fix: better permissions on make payment request
(cherry picked from commit f36962fc58)
2026-02-18 06:58:42 +00:00
ruthra kumar
f5fa1ba02b Merge pull request #52766 from frappe/mergify/bp/version-16-hotfix/pr-52419
fix: enfore permission on make_payment_request (backport #52419)
2026-02-18 12:26:45 +05:30
ruthra kumar
81845992a6 fix: enfore permission on make_payment_request
(cherry picked from commit b755ca12ca)
2026-02-18 06:32:44 +00:00
mergify[bot]
893683a512 fix: user permission on reports (backport #52709) (#52757)
* fix: user permission on reports (#52709)

(cherry picked from commit c6a292f6a9)

# Conflicts:
#	erpnext/accounts/report/purchase_register/purchase_register.py
#	erpnext/accounts/report/sales_register/sales_register.py

* chore: resolve conflict

---------

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2026-02-17 23:07:41 +05:30
Mihir Kandoi
59e2dbb435 Merge pull request #52754 from frappe/mergify/bp/version-16-hotfix/pr-52750
fix: setup fails to set abbr to departments (backport #52750)
2026-02-17 21:50:51 +05:30
Mihir Kandoi
35e9ca64ce Merge pull request #52752 from frappe/mergify/bp/version-16-hotfix/pr-52743
bug: fix comparison regarding `None` values (backport #52743)
2026-02-17 21:39:33 +05:30
Mihir Kandoi
b15db05ef8 fix: setup fails to set abbr to departments
(cherry picked from commit debe868950)
2026-02-17 15:57:50 +00:00
Markus Lobedann
66d1b7c837 fix: bug with comparison regarding None values and empty string
In their default state, the fields can be `None`. When a user enters something and deletes it afterwards, the fields contain an empty string.

This fixes the comparison.

(cherry picked from commit 3fd5a0f100)
2026-02-17 15:52:09 +00:00
mergify[bot]
10be8f19e2 fix(asset): handle partial asset sales by splitting remaining quantity (backport #51363) (#52394)
* fix(asset): handle partial asset sales by splitting remaining quantity

(cherry picked from commit 9a2710b9d7)

* fix: refactor older testcases

(cherry picked from commit a88fe2ecab)

* test: validate asset partial sales

(cherry picked from commit 9eeccb765d)

# Conflicts:
#	erpnext/assets/doctype/asset/test_asset.py

* fix(asset): skip purchase document validation while splitting existing asset

(cherry picked from commit e7e6567792)

* fix(asset): handle same asset being sold in multiple line items in sales invoice

(cherry picked from commit 23b094f151)

* test: validate asset split for auto created asset from purchase voucher

(cherry picked from commit 4adeaedfde)

# Conflicts:
#	erpnext/assets/doctype/asset/test_asset.py

* fix: use new_asset instead of asset_doc when checking values after splitting

(cherry picked from commit ca97f34092)

* fix: remove the redundant purchase receipt submit

(cherry picked from commit eeb6d0e9bf)

* chore: fix conflict

---------

Co-authored-by: Navin-S-R <navin@aerele.in>
2026-02-17 14:32:08 +00:00
Frappe PR Bot
372b0119bb chore(release): Bumped to Version 16.6.0
# [16.6.0](https://github.com/frappe/erpnext/compare/v16.5.0...v16.6.0) (2026-02-17)

### Bug Fixes

* allow non-stock items while updating items ([e2183eb](e2183ebde9))
* allow sequence id edit in BOM if routing is not set ([6f812cc](6f812ccaf5))
* better validation for negative batch ([e46e874](e46e8741b4))
* cancel SABB if SLE cancelled from LCV ([ac90975](ac90975f43))
* consider sle for negative stock validation ([ca8f324](ca8f324b51))
* consider table multiselect in delete transaction ([38679d6](38679d6d14))
* correct typos in marketing campaign custom fields function ([531bdbc](531bdbc727))
* do not allow plant floor company and warehouse to be updated ([a039c17](a039c176c8))
* ensure layout has Bootstrap row and column (backport [#52649](https://github.com/frappe/erpnext/issues/52649)) ([#52719](https://github.com/frappe/erpnext/issues/52719)) ([53e400c](53e400cca1))
* log changes made to accounts settings ([2200b9a](2200b9aa67))
* **manufacturing:** add sales order fields in subassembly child table ([605c0db](605c0db976))
* **manufacturing:** set sales order references in subassembly child table ([f4b0e64](f4b0e646b4))
* **pos_invoice:** add correct depends on condition ([#52689](https://github.com/frappe/erpnext/issues/52689)) ([28592d0](28592d0180))
* prevent rows from being added to sub_assembly_items and mr_items ([80c98cd](80c98cdcf4))
* production plan status ([62ea18f](62ea18f1cc))
* removed lost reason detail ([3c33a19](3c33a19634))
* **selling-workspace-sidebar:** changed order of pos profile ([1820c35](1820c35880))
* standalone credit/debit notes should not fetch any serial or batch by default ([dd4e186](dd4e1867f5))
* **stock:** remove hardcoded letter_head from report ([1d444e5](1d444e53eb)), closes [#52569](https://github.com/frappe/erpnext/issues/52569)
* total weight does not update when updating items ([46b5884](46b5884420))
* wrong display_depends_on condition for item group and brand child tables ([6ae1b18](6ae1b18616))

### Features

* Negative Batch report ([8649543](8649543ae0))
* show formatted currency symbol on ledger preview ([b844afe](b844afe0ec))
2026-02-17 14:10:20 +00:00
ruthra kumar
7a46fad6e7 Merge pull request #52731 from frappe/version-16-hotfix
chore: release v16
2026-02-17 19:38:48 +05:30
rohitwaghchaure
2ccb8c839d Merge pull request #52740 from frappe/mergify/bp/version-16-hotfix/pr-52729
feat: Negative Batch report (backport #52729)
2026-02-17 17:23:50 +05:30
Rohit Waghchaure
8649543ae0 feat: Negative Batch report
(cherry picked from commit 34edbed00b)
2026-02-17 11:04:33 +00:00
Mihir Kandoi
bed2c83272 Merge pull request #52736 from frappe/mergify/bp/version-16-hotfix/pr-52733
fix: allow sequence ID edit in BOM if routing is not set (backport #52733)
2026-02-17 16:28:39 +05:30
Mihir Kandoi
5461945d00 Merge pull request #52738 from frappe/mergify/bp/version-16-hotfix/pr-52677
fix: standalone credit/debit notes should not fetch any serial or bat… (backport #52677)
2026-02-17 16:25:36 +05:30
Mihir Kandoi
dd4e1867f5 fix: standalone credit/debit notes should not fetch any serial or batch by default
(cherry picked from commit 2017edca88)
2026-02-17 10:40:32 +00:00
Mihir Kandoi
6f812ccaf5 fix: allow sequence id edit in BOM if routing is not set
(cherry picked from commit 08529964b4)
2026-02-17 10:36:17 +00:00
ruthra kumar
6c4bba3992 Merge pull request #52727 from frappe/mergify/bp/version-16-hotfix/pr-52679
fix: log changes made to accounts settings (backport #52679)
2026-02-17 14:15:25 +05:30
ruthra kumar
eda479a917 Merge pull request #52725 from frappe/mergify/bp/version-16-hotfix/pr-52648
fix: correct typos in marketing campaign custom fields function (backport #52648)
2026-02-17 13:59:19 +05:30
AarDG10
2200b9aa67 fix: log changes made to accounts settings
(cherry picked from commit 45febbabd7)
2026-02-17 08:25:47 +00:00
Mihir Kandoi
af15050acc Merge pull request #52723 from frappe/mergify/bp/version-16-hotfix/pr-52720
fix: wrong display_depends_on condition for item group and brand chil… (backport #52720)
2026-02-17 13:43:00 +05:30
Abdeali Chharchhoda
531bdbc727 fix: correct typos in marketing campaign custom fields function
(cherry picked from commit 6b7fed7f59)
2026-02-17 08:12:00 +00:00
ruthra kumar
53e400cca1 fix: ensure layout has Bootstrap row and column (backport #52649) (#52719)
Merge pull request #52649 from aerele/fix-sales-funnel-layout

fix: ensure layout has Bootstrap row and column
(cherry picked from commit ae0be7f6ce)

Co-authored-by: Vishnu Priya Baskaran <145791817+ervishnucs@users.noreply.github.com>
2026-02-17 13:04:21 +05:30
Shllokkk
6ae1b18616 fix: wrong display_depends_on condition for item group and brand child tables
(cherry picked from commit de2843d9f1)
2026-02-17 07:30:21 +00:00
Mihir Kandoi
a8f21dbc07 Merge pull request #52718 from frappe/mergify/bp/version-16-hotfix/pr-52716
fix: do not allow plant floor company and warehouse to be updated (backport #52716)
2026-02-17 12:32:45 +05:30
Vishnu Priya Baskaran
1dd471fb18 Merge pull request #52649 from aerele/fix-sales-funnel-layout
fix: ensure layout has Bootstrap row and column
(cherry picked from commit ae0be7f6ce)
2026-02-17 06:55:51 +00:00
Mihir Kandoi
a039c176c8 fix: do not allow plant floor company and warehouse to be updated
(cherry picked from commit fd72132743)
2026-02-17 06:42:33 +00:00
Mihir Kandoi
cf141045ba Merge pull request #52715 from frappe/mergify/bp/version-16-hotfix/pr-52713
fix: production plan status (backport #52713)
2026-02-17 11:41:43 +05:30
Mihir Kandoi
62ea18f1cc fix: production plan status
(cherry picked from commit b3e6b304e4)
2026-02-17 05:54:10 +00:00
Mihir Kandoi
302ae382f1 Merge pull request #52697 from frappe/mergify/bp/version-16-hotfix/pr-52678
chore: do not show stock details if update stock is disabled (backport #52678)
2026-02-17 10:55:49 +05:30
Mihir Kandoi
98ff54a871 chore: resolve conflicts 2026-02-17 10:40:34 +05:30
rohitwaghchaure
41b089ab51 Merge pull request #52705 from frappe/mergify/bp/version-16-hotfix/pr-52620
fix: prevent rows from being added to sub_assembly_items and mr_items (backport #52620)
2026-02-17 10:16:09 +05:30
Diptanil Saha
46acd328a9 Merge pull request #52707 from frappe/mergify/bp/version-16-hotfix/pr-52706
fix(selling-workspace-sidebar): changed order of pos profile (backport #52706)
2026-02-17 00:55:44 +05:30
diptanilsaha
1820c35880 fix(selling-workspace-sidebar): changed order of pos profile
(cherry picked from commit 72f4fd08ee)
2026-02-16 19:11:27 +00:00
Shllokkk
80c98cdcf4 fix: prevent rows from being added to sub_assembly_items and mr_items
(cherry picked from commit 25f979a825)
2026-02-16 18:43:01 +00:00
Mihir Kandoi
4a8363e7da Merge pull request #52703 from frappe/mergify/bp/version-16-hotfix/pr-52626
fix(manufacturing): add sales order fields in subassembly child table (backport #52626)
2026-02-16 23:58:13 +05:30
rohitwaghchaure
dcbc1e1303 Merge pull request #52701 from frappe/mergify/bp/version-16-hotfix/pr-52699
fix: consider sle for negative stock validation (backport #52699)
2026-02-16 23:56:30 +05:30
Sudharsanan11
ecfd193002 test(manufacturing): add test to validate the sales order references for sub assembly items
(cherry picked from commit 341dc4be7a)
2026-02-16 18:11:53 +00:00
Sudharsanan11
f4b0e646b4 fix(manufacturing): set sales order references in subassembly child table
(cherry picked from commit 0f2ed28ab7)
2026-02-16 18:11:52 +00:00
Sudharsanan11
605c0db976 fix(manufacturing): add sales order fields in subassembly child table
(cherry picked from commit c2282eaf08)
2026-02-16 18:11:52 +00:00
Rohit Waghchaure
ca8f324b51 fix: consider sle for negative stock validation
(cherry picked from commit 38f35acffe)
2026-02-16 17:56:51 +00:00
Mihir Kandoi
7677b2f573 chore: do not show serial batch selector if not needed
(cherry picked from commit cdc62e7327)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
2026-02-16 17:01:48 +00:00
Mihir Kandoi
f08964683a chore: do not show stock details if update stock is disabled
(cherry picked from commit 4499e974a0)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
2026-02-16 17:01:48 +00:00
rohitwaghchaure
d2eabcbf74 Merge pull request #52696 from frappe/mergify/bp/version-16-hotfix/pr-52691
fix: cancel SABB if SLE cancelled from LCV (backport #52691)
2026-02-16 21:52:33 +05:30
Diptanil Saha
7d8bbac5fd Merge pull request #52694 from frappe/mergify/bp/version-16-hotfix/pr-52689
fix(pos_invoice): add correct depends on condition (backport #52689)
2026-02-16 21:23:24 +05:30
Rohit Waghchaure
ac90975f43 fix: cancel SABB if SLE cancelled from LCV
(cherry picked from commit f23a49a25e)
2026-02-16 15:42:23 +00:00
Soham Kulkarni
28592d0180 fix(pos_invoice): add correct depends on condition (#52689)
* fix(pos_invoice): add correct depends on condition

* fix: show field in sales order

* refactor: eval condition

(cherry picked from commit 219cf6bc57)
2026-02-16 15:37:25 +00:00
rohitwaghchaure
de5e8a6e6b Merge pull request #52684 from frappe/mergify/bp/version-16-hotfix/pr-52681
fix: better validation for negative batch (backport #52681)
2026-02-16 16:02:55 +05:30
Rohit Waghchaure
e46e8741b4 fix: better validation for negative batch
(cherry picked from commit a8636e4f59)
2026-02-16 09:47:05 +00:00
MochaMind
4a4e9956e2 chore: update POT file (#52674) 2026-02-15 14:00:35 +01:00
Mihir Kandoi
8ec83f2080 Merge pull request #52672 from frappe/mergify/bp/version-16-hotfix/pr-52670 2026-02-15 14:30:52 +05:30
Mihir Kandoi
46b5884420 fix: total weight does not update when updating items
(cherry picked from commit 63323a2611)
2026-02-15 08:45:19 +00:00
Mihir Kandoi
3548073a07 Merge pull request #52669 from frappe/mergify/bp/version-16-hotfix/pr-52658
fix: allow non-stock items while updating items (backport #52658)
2026-02-15 13:07:37 +05:30
ervishnucs
e2183ebde9 fix: allow non-stock items while updating items
(cherry picked from commit 07db5941aa)
2026-02-15 07:28:48 +00:00
Mihir Kandoi
37f740caa6 Merge pull request #52668 from frappe/revert-52578-mergify/bp/version-16-hotfix/pr-51594
Revert "fix: Workspace sidebar links for Debit/Credit Notes (backport #51594)"
2026-02-15 12:44:37 +05:30
Mihir Kandoi
485c1b025a Revert "fix: Workspace sidebar links for Debit/Credit Notes (backport #51594)" 2026-02-15 12:29:28 +05:30
ruthra kumar
880cc50ae4 Merge pull request #52659 from frappe/mergify/bp/version-16-hotfix/pr-52643
fix: consider table multiselect in delete transaction (backport #52643)
2026-02-13 15:12:54 +05:30
SowmyaArunachalam
3c33a19634 fix: removed lost reason detail
(cherry picked from commit 9bb60405e7)

# Conflicts:
#	erpnext/patches.txt
2026-02-13 14:11:58 +05:30
SowmyaArunachalam
38679d6d14 fix: consider table multiselect in delete transaction
(cherry picked from commit be3d2422a7)
2026-02-13 08:37:46 +00:00
ruthra kumar
3744c32950 Merge pull request #52646 from frappe/mergify/bp/version-16-hotfix/pr-52644
refactor: use query builder for profitability analysis (backport #52644)
2026-02-12 14:40:46 +05:30
ruthra kumar
543e0131b5 refactor: use query builder for profitability analysis
(cherry picked from commit 5e34325604)
2026-02-12 08:55:03 +00:00
ruthra kumar
eb5ffcdc88 Merge pull request #52642 from frappe/mergify/bp/version-16-hotfix/pr-52640
refactor: use query builder for sales person commission summary (backport #52640)
2026-02-12 12:53:24 +05:30
ruthra kumar
f98e53692e refactor: use query builder for sales person commission summary
(cherry picked from commit 7105e3fb69)
2026-02-12 07:07:42 +00:00
ruthra kumar
e778eabcb0 Merge pull request #52639 from frappe/mergify/bp/version-16-hotfix/pr-52571
fix(stock): remove hardcoded letter_head from report (backport #52571)
2026-02-12 12:04:57 +05:30
Roxxane
1d444e53eb fix(stock): remove hardcoded letter_head from report
The 'Incorrect Serial and Batch Bundle' report had a hardcoded
letter_head value of 'Test', preventing users from deleting a
Letter Head named 'Test' due to link check.

Standard reports should not reference specific Letter Head names.

Fixes #52569

(cherry picked from commit 99cd29d88f)
2026-02-12 06:19:37 +00:00
ruthra kumar
3bf9aff67e Merge pull request #52638 from frappe/mergify/bp/version-16-hotfix/pr-52619
feat: show formatted currency symbol on ledger preview (backport #52619)
2026-02-12 11:48:49 +05:30
Navin-S-R
b844afe0ec feat: show formatted currency symbol on ledger preview
(cherry picked from commit 5c8cb1e7ec)
2026-02-12 05:59:06 +00:00
Frappe PR Bot
6e7e219f71 chore(release): Bumped to Version 16.5.0
# [16.5.0](https://github.com/frappe/erpnext/compare/v16.4.1...v16.5.0) (2026-02-11)

### Bug Fixes

* Added a missing option to the currency field (backport [#52528](https://github.com/frappe/erpnext/issues/52528)) ([#52587](https://github.com/frappe/erpnext/issues/52587)) ([1c3fe00](1c3fe000ba))
* Added validation for quality inspection in job card ([a1ec68c](a1ec68cd1e))
* apply composite asset logic only in draft ([d2387a3](d2387a3af8))
* **balance sheet:** removed the extra labels from the chart ([6a9a28b](6a9a28b4ae))
* **buying:** add supplier group link filters in field level ([9886b46](9886b46cb4))
* correctly calculate running balances for financial report ([7df18af](7df18af799))
* do not show update stock flag unneccessarily ([c0c6cc5](c0c6cc58ed))
* email campaign timeout issue (backport [#51994](https://github.com/frappe/erpnext/issues/51994)) ([#52556](https://github.com/frappe/erpnext/issues/52556)) ([e753df8](e753df8ff0))
* enabling skip delivery option for order type maintenance ([7a78e97](7a78e9705c))
* **gross profit report:** translate column Sales Invoice ([6ff8820](6ff8820732))
* **gross-profit:** handle item group filters ([0d02bbb](0d02bbb01a))
* **gross-profit:** handle returns outside sale period ([9b32c84](9b32c84462))
* handle gross profit and percentage for return invoices ([d081a26](d081a26608))
* item code is tuple with operation id ([9d14c0b](9d14c0b60e))
* **manufacturing:** fix chart period keys ([b99ca48](b99ca486d7))
* **manufacturing:** handle None value for actual_end_date ([b1b75ec](b1b75eca3d))
* **map_current_doc:** prevent mutation of query args in get_query (backport [#52202](https://github.com/frappe/erpnext/issues/52202)) ([#52584](https://github.com/frappe/erpnext/issues/52584)) ([b8256e5](b8256e5f31))
* move company field to first position in sales invoice, purchase invoice, sales order, purchase order and journal entry ([e53ccd0](e53ccd0745))
* not able to complete job card ([c5ff534](c5ff534d58))
* operation status and bom validation ([1122265](11222653ce))
* Period Closing Voucher doesn't exist for GL Entry ([921584c](921584c769))
* process loss error incorrectly thrown even when semi FG BOM does not have any process loss ([4a7ffce](4a7ffce320))
* **quotation:** ignore zero ordered_qty ([cf7c127](cf7c127dc6))
* rate comparison in stock reco ([1f78f45](1f78f45aee))
* remove customer_pos_id reference ([#52396](https://github.com/frappe/erpnext/issues/52396)) ([ab59f73](ab59f73064))
* remove incorrect validation from email digest throwing spurious error (backport [#51827](https://github.com/frappe/erpnext/issues/51827)) ([#52579](https://github.com/frappe/erpnext/issues/52579)) ([dffb6ac](dffb6ac4cf))
* return None instead of 0 if valuation rate is falsy ([64a7956](64a7956a4a))
* stock balance report issue ([62616ad](62616ad9e1))
* stock reservation created against job card ([305483e](305483e074))
* **stock:** add is group filter for warehouse fields ([23a26b5](23a26b540b))
* **stock:** ignore pos reserved batches for stock levels ([e2c1204](e2c12043ae))
* **stock:** inward stock for pick list test record ([801a26a](801a26ae67))
* **stock:** set source warehouse for issue type ([53e512c](53e512ceaf))
* **stock:** update target field attribute ([96dfecf](96dfecf0d5))
* test cases ([ece8d00](ece8d00415))
* validate asset movement transaction date ([#52340](https://github.com/frappe/erpnext/issues/52340)) ([898d2e3](898d2e3c9a))
* Workspace sidebar links for Debit/Credit Notes ([29d33b3](29d33b3139))

### Features

* **accounts:** expand Journal Entry Template to support dimensions and party ([#51621](https://github.com/frappe/erpnext/issues/51621)) ([d06a46a](d06a46ae85))
* allow negative stock for the batch item ([b6afe7f](b6afe7f4da))

### Reverts

* "fix: allow sales invoice to be renamed" ([abef910](abef9109b0))
2026-02-11 06:03:37 +00:00
ruthra kumar
ce225d87f3 Merge pull request #52597 from frappe/version-16-hotfix
chore: release v16
2026-02-11 11:32:00 +05:30
ruthra kumar
0d831aad41 Merge pull request #52605 from frappe/mergify/bp/version-16-hotfix/pr-52593
refactor: update labels for tax withholding reports columns to improve clarity (backport #52593)
2026-02-10 18:30:52 +05:30
ruthra kumar
00caebe90c Merge pull request #52397 from frappe/mergify/bp/version-16-hotfix/pr-52396
fix: remove customer_pos_id reference (backport #52396)
2026-02-10 18:28:49 +05:30
ruthra kumar
0ee97ffbbf Merge pull request #52414 from frappe/mergify/bp/version-16-hotfix/pr-51745
fix(gross profit report): translate column Sales Invoice (backport #51745)
2026-02-10 18:27:54 +05:30
ruthra kumar
4a6c428848 Merge pull request #52604 from frappe/mergify/bp/version-16-hotfix/pr-52017
fix(gross-profit): handle returns outside the given sale period (backport #52017)
2026-02-10 18:27:38 +05:30
Kavin
3e3daa50b1 Merge pull request #52542 from frappe/mergify/bp/version-16-hotfix/pr-52516
fix(stock): ignore pos reserved batches for stock levels (backport #52516)
2026-02-10 18:21:37 +05:30
ljain112
ac7a25fff9 refactor: update labels for tax withholding reports columns to improve clarity
(cherry picked from commit 2cfdcc1af4)
2026-02-10 12:43:06 +00:00
Navin-S-R
0d02bbb01a fix(gross-profit): handle item group filters
(cherry picked from commit 047b278791)
2026-02-10 12:41:30 +00:00
Navin-S-R
d01ea27f2f test: fix test assertions to use index-based totals
(cherry picked from commit fdfa7bc963)
2026-02-10 12:41:29 +00:00
Navin-S-R
345d25bdf1 test: validate sales person wise gross profit
(cherry picked from commit 3ab978ab46)
2026-02-10 12:41:29 +00:00
Navin-S-R
e8eaae4120 test: validate return invoice profit and profit percentage
(cherry picked from commit 4da3d43013)
2026-02-10 12:41:29 +00:00
Navin-S-R
d081a26608 fix: handle gross profit and percentage for return invoices
(cherry picked from commit 51709f032f)
2026-02-10 12:41:29 +00:00
Navin-S-R
9b32c84462 fix(gross-profit): handle returns outside sale period
(cherry picked from commit 67d8223f73)
2026-02-10 12:41:28 +00:00
Diptanil Saha
22c9b26a24 Merge pull request #52450 from frappe/mergify/bp/version-16-hotfix/pr-52360
fix: correctly calculate running balances for financial report (backport #52360)
2026-02-10 02:37:22 +05:30
mergify[bot]
1c3fe000ba fix: Added a missing option to the currency field (backport #52528) (#52587)
fix: Added a missing option to the currency field (#52528)

(cherry picked from commit da07f84e44)

Co-authored-by: El-Shafei H. <el.shafei.developer@gmail.com>
2026-02-09 21:01:04 +00:00
mergify[bot]
ffd9b248f6 refactor: drop usages of db_query (backport #52559) (#52565)
refactor: drop usages of db_query


(cherry picked from commit 1e45195ef9)

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
Co-authored-by: Akhil Narang <me@akhilnarang.dev>
2026-02-10 01:47:17 +05:30
mergify[bot]
b8256e5f31 fix(map_current_doc): prevent mutation of query args in get_query (backport #52202) (#52584)
fix(map_current_doc): prevent mutation of query args in get_query (#52202)

(cherry picked from commit 23a73c9cdb)

Co-authored-by: V Shankar <shankarv292002@gmail.com>
2026-02-10 01:26:00 +05:30
Trusted Computer
dffb6ac4cf fix: remove incorrect validation from email digest throwing spurious error (backport #51827) (#52579) 2026-02-09 18:26:57 +00:00
mergify[bot]
e753df8ff0 fix: email campaign timeout issue (backport #51994) (#52556)
fix: email campaign timeout issue (#51994)

* fix: email campaign timeout issue

* refactor: email campaign backend logic

* refactor: use sendmail instead of manually batching

(cherry picked from commit 22123dd955)

Co-authored-by: Pratik Badhe <badhepd@gmail.com>
2026-02-09 23:45:02 +05:30
Mihir Kandoi
560fd2e0d1 Merge pull request #52581 from frappe/mergify/bp/version-16-hotfix/pr-52527
fix(stock): correct warehouse mapping for material issue (backport #52527)
2026-02-09 21:22:27 +05:30
Mihir Kandoi
327719a0fd Merge pull request #52578 from frappe/mergify/bp/version-16-hotfix/pr-51594
fix: Workspace sidebar links for Debit/Credit Notes (backport #51594)
2026-02-09 21:19:00 +05:30
Pandiyan37
801a26ae67 fix(stock): inward stock for pick list test record
(cherry picked from commit f22b9e297b)
2026-02-09 15:36:44 +00:00
Pandiyan37
8c4a9040b7 test(stock): add test to check from warehouse for issue type
(cherry picked from commit da0322e994)
2026-02-09 15:36:44 +00:00
Pandiyan37
53e512ceaf fix(stock): set source warehouse for issue type
(cherry picked from commit a34e8c99cd)
2026-02-09 15:36:43 +00:00
Mihir Kandoi
e9212c6a32 chore: resolve conflicts 2026-02-09 21:03:37 +05:30
Nabin Hait
29d33b3139 fix: Workspace sidebar links for Debit/Credit Notes
(cherry picked from commit 8acf373e68)

# Conflicts:
#	erpnext/workspace_sidebar/invoicing.json
2026-02-09 15:32:25 +00:00
rohitwaghchaure
7e0dc2ff86 Merge pull request #52561 from frappe/mergify/bp/version-16-hotfix/pr-52340
fix: validate asset movement transaction date (backport #52340)
2026-02-09 19:52:15 +05:30
Poojashree T R
898d2e3c9a 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 e98b68c38f)
2026-02-09 11:52:19 +00:00
rohitwaghchaure
4c562b2903 Merge pull request #52558 from frappe/mergify/bp/version-16-hotfix/pr-52550
feat: allow negative stock for the batch item (backport #52550)
2026-02-09 16:40:12 +05:30
Mihir Kandoi
04d6273713 Merge pull request #52554 from frappe/mergify/bp/version-16-hotfix/pr-52501
fix(quotation): ignore zero ordered_qty (backport #52501)
2026-02-09 16:25:45 +05:30
Rohit Waghchaure
b6afe7f4da feat: allow negative stock for the batch item
(cherry picked from commit 376ab0e346)
2026-02-09 10:50:46 +00:00
ravibharathi656
cf7c127dc6 fix(quotation): ignore zero ordered_qty
(cherry picked from commit 32ea37035e)
2026-02-09 10:39:04 +00:00
Sudharsanan11
59f6012c57 test(stock): add test to ignore pos reserved batches for stock levels
(cherry picked from commit 47ac67f7a2)
2026-02-09 06:28:58 +00:00
Sudharsanan11
e2c12043ae fix(stock): ignore pos reserved batches for stock levels
(cherry picked from commit 277ba9cb79)
2026-02-09 06:28:58 +00:00
Mihir Kandoi
3e0a7f2400 Merge pull request #52539 from frappe/mergify/bp/version-16-hotfix/pr-52538
revert: "fix: allow sales invoice to be renamed" (backport #52538)
2026-02-09 10:47:42 +05:30
Mihir Kandoi
abef9109b0 revert: "fix: allow sales invoice to be renamed"
This reverts commit 95fdbe55f9.

(cherry picked from commit 2660907ac8)
2026-02-09 05:00:36 +00:00
MochaMind
9766361c07 chore: update POT file (#52530) 2026-02-08 17:49:45 +01:00
Mihir Kandoi
6bcd311214 Merge pull request #52524 from frappe/mergify/bp/version-16-hotfix/pr-52497
fix: add is_group filter for supplier_group and warehouse fields (backport #52497)
2026-02-07 21:58:58 +05:30
Mihir Kandoi
dd45bb5664 chore: resolve conflicts 2026-02-07 21:44:42 +05:30
Sudharsanan11
23a26b540b fix(stock): add is group filter for warehouse fields
(cherry picked from commit a9829f5f7b)
2026-02-07 16:11:32 +00:00
Sudharsanan11
9886b46cb4 fix(buying): add supplier group link filters in field level
(cherry picked from commit cfdc554a19)

# Conflicts:
#	erpnext/buying/doctype/supplier/supplier.json
2026-02-07 16:11:32 +00:00
Mihir Kandoi
32d5cedafc Merge pull request #52486 from frappe/mergify/bp/version-16-hotfix/pr-52000
fix: Added validation for quality inspection in job card (backport #52000)
2026-02-06 14:49:10 +05:30
Nishka Gosalia
ece8d00415 fix: test cases 2026-02-06 14:34:08 +05:30
Khushi Rawat
c171b9a184 Merge pull request #52492 from frappe/mergify/bp/version-16-hotfix/pr-52491
fix: apply composite asset logic only in draft (backport #52491)
2026-02-06 13:10:24 +05:30
khushi8112
d2387a3af8 fix: apply composite asset logic only in draft
(cherry picked from commit ee501e884a)
2026-02-06 07:36:31 +00:00
rohitwaghchaure
79e0e07446 Merge pull request #52482 from frappe/mergify/bp/version-16-hotfix/pr-52476
fix: stock reservation created against job card (backport #52476)
2026-02-06 12:52:43 +05:30
Mihir Kandoi
4caca08b90 Merge pull request #52488 from frappe/mergify/bp/version-16-hotfix/pr-52219
fix: enabling skip delivery option for order type maintenance (backport #52219)
2026-02-06 12:44:47 +05:30
Mihir Kandoi
738cb6847e Merge pull request #52484 from frappe/mergify/bp/version-16-hotfix/pr-52475
fix: do not show update stock flag unneccessarily (backport #52475)
2026-02-06 12:28:36 +05:30
Nishka Gosalia
7a78e9705c fix: enabling skip delivery option for order type maintenance
(cherry picked from commit 1a22e3cb61)
2026-02-06 06:40:03 +00:00
Nishka Gosalia
a1ec68cd1e fix: Added validation for quality inspection in job card
(cherry picked from commit 46b4cf3add)
2026-02-06 06:38:32 +00:00
Mihir Kandoi
4847a76cb8 chore: resolve conflicts 2026-02-06 12:00:47 +05:30
Mihir Kandoi
f56c6f93a1 chore: resolve conflicts 2026-02-06 12:00:23 +05:30
Mihir Kandoi
c0c6cc58ed fix: do not show update stock flag unneccessarily
(cherry picked from commit 5fb5b7b30e)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
2026-02-06 06:27:46 +00:00
rohitwaghchaure
8c372faf50 chore: fix linter issue
Removed duplicate import of get_bom_items_as_dict from BOM module.
2026-02-06 11:29:45 +05:30
Diptanil Saha
ae4cf27f4f Merge pull request #52471 from frappe/mergify/bp/version-16-hotfix/pr-51621
feat(accounts): expand Journal Entry Template to support dimensions and party (backport #51621)
2026-02-06 11:07:27 +05:30
Rohit Waghchaure
305483e074 fix: stock reservation created against job card
(cherry picked from commit dca2cfd009)
2026-02-05 23:05:19 +00:00
rohitwaghchaure
86dd2e786c Merge pull request #52474 from frappe/mergify/bp/version-16-hotfix/pr-52467
fix: operation status and bom validation (backport #52467)
2026-02-05 21:06:23 +05:30
Rohit Waghchaure
11222653ce fix: operation status and bom validation
(cherry picked from commit 95baf953a8)
2026-02-05 14:16:38 +00:00
Nikhil Kothari
d06a46ae85 feat(accounts): expand Journal Entry Template to support dimensions and party (#51621)
* feat(accounts): expand Journal Entry Template to support dimensions and party

* fix: do not update standard row values

(cherry picked from commit ef44528ba5)
2026-02-05 12:55:13 +00:00
rohitwaghchaure
8c536df5f2 Merge pull request #52428 from frappe/mergify/bp/version-16-hotfix/pr-52422
fix: not able to complete job card (backport #52422)
2026-02-05 17:05:16 +05:30
Frappe PR Bot
d74a649016 chore(release): Bumped to Version 16.4.1
## [16.4.1](https://github.com/frappe/erpnext/compare/v16.4.0...v16.4.1) (2026-02-05)

### Bug Fixes

* stock balance report issue ([e009319](e0093199b1))
2026-02-05 10:52:48 +00:00
rohitwaghchaure
bc9928b32b Merge pull request #52464 from frappe/mergify/bp/version-16/pr-52461
fix: stock balance report issue (backport #52459) (backport #52461)
2026-02-05 16:20:53 +05:30
rohitwaghchaure
4305415ed9 chore: fix issue
(cherry picked from commit 1d24abf5dd)
2026-02-05 10:20:46 +00:00
Rohit Waghchaure
e0093199b1 fix: stock balance report issue
(cherry picked from commit 7e584dd84a)
(cherry picked from commit 62616ad9e1)
2026-02-05 10:20:45 +00:00
rohitwaghchaure
4dec567421 Merge pull request #52461 from frappe/mergify/bp/version-16-hotfix/pr-52459
fix: stock balance report issue (backport #52459)
2026-02-05 15:49:58 +05:30
rohitwaghchaure
1d24abf5dd chore: fix issue 2026-02-05 15:02:47 +05:30
Rohit Waghchaure
62616ad9e1 fix: stock balance report issue
(cherry picked from commit 7e584dd84a)
2026-02-05 09:20:01 +00:00
Jatin3128
6bffdbce56 Merge pull request #52455 from frappe/mergify/bp/version-16-hotfix/pr-52438
fix(balance sheet): removed the extra labels from the chart (backport #52438)
2026-02-05 13:39:41 +05:30
Jatin3128
6a9a28b4ae fix(balance sheet): removed the extra labels from the chart
(cherry picked from commit a64b5f2c5d)
2026-02-05 07:54:14 +00:00
Mihir Kandoi
66d0ab6380 Merge pull request #52454 from frappe/mergify/bp/version-16-hotfix/pr-52452
fix: process loss error incorrectly thrown even when semi FG BOM does… (backport #52452)
2026-02-05 13:15:53 +05:30
ruthra kumar
5913d5f14e Merge pull request #52351 from frappe/mergify/bp/version-16-hotfix/pr-52346
fix: move company field to first position in sales invoice, purchase … (backport #52346)
2026-02-05 13:11:28 +05:30
Mihir Kandoi
4a7ffce320 fix: process loss error incorrectly thrown even when semi FG BOM does not have any process loss
(cherry picked from commit 99ddc36c26)
2026-02-05 07:27:41 +00:00
Smit Vora
2994ba1b41 test: further tests for query builder
(cherry picked from commit 12f8bb2937)
2026-02-05 06:53:30 +00:00
Smit Vora
55eb631116 test: correct error message
(cherry picked from commit a29710dc07)
2026-02-05 06:53:30 +00:00
Smit Vora
77693b12a4 test: revert original pcv setting
(cherry picked from commit f45a5a63a7)
2026-02-05 06:53:29 +00:00
Smit Vora
8caf609f8d test: add tests for query builder
(cherry picked from commit 61d8308e81)
2026-02-05 06:53:29 +00:00
Smit Vora
921584c769 fix: Period Closing Voucher doesn't exist for GL Entry
(cherry picked from commit b41c1858a3)
2026-02-05 06:53:29 +00:00
Smit Vora
7df18af799 fix: correctly calculate running balances for financial report
(cherry picked from commit ee2f8d8ebc)
2026-02-05 06:53:29 +00:00
Mihir Kandoi
64d82a811f Merge pull request #52446 from frappe/mergify/bp/version-16-hotfix/pr-52445
fix: item code is tuple with operation id (backport #52445)
2026-02-05 12:12:35 +05:30
Mihir Kandoi
9d14c0b60e fix: item code is tuple with operation id
(cherry picked from commit 481deee4b2)
2026-02-05 06:29:11 +00:00
ruthra kumar
0a285523a8 Merge pull request #52426 from frappe/mergify/bp/version-16-hotfix/pr-51990
refactor: use https over http while saving website link (backport #51990)
2026-02-05 11:30:16 +05:30
ruthra kumar
ce695ebdd0 refactor: patch partner_website for old data
(cherry picked from commit 8db29b0a81)

# Conflicts:
#	erpnext/patches.txt
2026-02-05 11:00:58 +05:30
Mihir Kandoi
9f31910226 Merge pull request #52441 from frappe/mergify/bp/version-16-hotfix/pr-52416
fix(stock): update target field attribute (backport #52416)
2026-02-05 10:40:29 +05:30
Pandiyan37
f8405e4ca4 test(stock): testcase for different inventory dimension
(cherry picked from commit 21d0ee8db1)
2026-02-05 04:54:39 +00:00
Pandiyan37
96dfecf0d5 fix(stock): update target field attribute
(cherry picked from commit 7e08154217)
2026-02-05 04:54:38 +00:00
Mihir Kandoi
b5b8032ce0 Merge pull request #52430 from frappe/mergify/bp/version-16-hotfix/pr-52427 2026-02-04 20:17:43 +05:30
archielister
5298e26a11 fix for obtaining bom_no
(cherry picked from commit e4df0a393a)
2026-02-04 14:33:24 +00:00
Rohit Waghchaure
c5ff534d58 fix: not able to complete job card
(cherry picked from commit 175fe9279c)
2026-02-04 13:13:27 +00:00
Mihir Kandoi
1dc44691db Merge pull request #52421 from frappe/mergify/bp/version-16-hotfix/pr-51773
fix(manufacturing): refactor production analytics report (backport #51773)
2026-02-04 18:06:40 +05:30
ruthra kumar
91043de352 refactor: scrub http and use https in sales partner
(cherry picked from commit 8cf31548f2)
2026-02-04 12:32:42 +00:00
Sudharsanan11
b99ca486d7 fix(manufacturing): fix chart period keys
(cherry picked from commit 27091e5168)
2026-02-04 17:51:53 +05:30
Sudharsanan11
b1b75eca3d fix(manufacturing): handle None value for actual_end_date
(cherry picked from commit 16f09141da)
2026-02-04 17:51:53 +05:30
Mihir Kandoi
33305550b7 Merge pull request #52408 from frappe/mergify/bp/version-16-hotfix/pr-52383
fix: rate comparison in stock reco (backport #52383)
2026-02-04 17:42:06 +05:30
Mihir Kandoi
e86ab97b7e chore: add line in the end so linter check passes 2026-02-04 17:26:01 +05:30
elshafei-developer
6ff8820732 fix(gross profit report): translate column Sales Invoice
(cherry picked from commit 3e39d13172)
2026-02-04 09:18:31 +00:00
Mihir Kandoi
64a7956a4a fix: return None instead of 0 if valuation rate is falsy
(cherry picked from commit e8d1e9d946)
2026-02-04 06:48:33 +00:00
Mihir Kandoi
1f78f45aee fix: rate comparison in stock reco
(cherry picked from commit f1b4fe12a2)
2026-02-04 06:48:32 +00:00
Diptanil Saha
ab59f73064 fix: remove customer_pos_id reference (#52396)
(cherry picked from commit 036f64013d)
2026-02-04 05:18:56 +00:00
Frappe PR Bot
0312d58dca chore(release): Bumped to Version 16.4.0
# [16.4.0](https://github.com/frappe/erpnext/compare/v16.3.0...v16.4.0) (2026-02-04)

### Bug Fixes

* add precision to rejected batch no qty calculation ([b365444](b365444027))
* allow sales invoice to be renamed ([f7b915d](f7b915dfe6))
* **barcode:** failing request when item has both batch and serial ([e4cdd97](e4cdd971c8))
* batch selector not working if Use Legacy (Client side) Reactivity disabled ([2a3642b](2a3642b55a))
* better fix for aac39b2671 ([b8ab55f](b8ab55fee8))
* correct exchange gain loss in ppr ([e09406d](e09406d085))
* correct Sales Tax Template sidebar link to proper DocType ([4c14e74](4c14e74a12))
* correct spelling of Payment Reconciliation in Accounting ([c80b554](c80b554cd7))
* **credit-note:** set incoming rate as zero for expired batch ([0f9bf08](0f9bf08685))
* **demo:** removed toolbar eventlistener (backport [#52171](https://github.com/frappe/erpnext/issues/52171)) ([#52172](https://github.com/frappe/erpnext/issues/52172)) ([6608601](66086010fc))
* duplicate account number (Indonesia COA) (backport [#52080](https://github.com/frappe/erpnext/issues/52080)) ([#52317](https://github.com/frappe/erpnext/issues/52317)) ([81e6575](81e65757ee))
* failing test cases ([136b2cf](136b2cfba5))
* group item wise tax details by tax row ([45e4c04](45e4c04830))
* hide close button on WO if WO is completed ([0d1c30f](0d1c30f3f0))
* hide item_wise_tax_details table from print ([c619be9](c619be989b))
* include credit notes in project gross margin calculation ([e755a4a](e755a4ad98))
* item code not showing in report view ([af167f9](af167f91fe))
* journal auditing voucher print date to use posting_date ([7e5eab2](7e5eab261c))
* **journal-entry:** normalize exchange rate to float ([3f0032d](3f0032d793))
* js error if user does not have write permission for date field ([3944dfd](3944dfde31))
* lead time calculation for FG item ([5595602](5595602f24))
* make item name editable in RFQ ([dbe5846](dbe5846908))
* merge taxes in purchase receipt when get items from multiple purchase invoices ([#51422](https://github.com/frappe/erpnext/issues/51422)) ([d80c8d1](d80c8d14b0))
* missing depr_series causing error on jv creation (backport [#52085](https://github.com/frappe/erpnext/issues/52085)) ([#52206](https://github.com/frappe/erpnext/issues/52206)) ([78c4f01](78c4f01733))
* negative stock for purchase return ([220a528](220a528d7f))
* populate contact fields when creating quotation from customer ([55129e6](55129e697d))
* production plan not considering planning datetime when creating WO ([7e7b16b](7e7b16b23e))
* **profit and loss statement:** exclude non period columns ([28e8c40](28e8c40bfc))
* reset incoming rate in selling controller if there are changes in item ([024e7b0](024e7b01ac))
* **RFQ:** render email templates for preview and sending ([687a80d](687a80d74c))
* **stock:** add stock recon opening stock condition ([f9a8fc1](f9a8fc1f2d))
* **stock:** fetch batch wise valuation rate in get_items ([b132e3f](b132e3f22a))
* **stock:** ignore packing slip while cancelling the sales invoice ([f425f89](f425f89a26))
* **stock:** include subcontracting order qty while calculating the bin qty ([de244e0](de244e0af7))
* **stock:** remove is_return condition on pos batch qty calculation ([9dcaf38](9dcaf38142))
* **stock:** set incoming_rate with lcv rate for internal purchase ([f462639](f462639aa0))
* **subcontracting:** include item bom in supplied items grouping key ([95c4b8d](95c4b8de06))
* test cases ([e74389f](e74389f01c))
* validate over ordering of quotation ([e7ace8e](e7ace8e620))
* validation when more than one FG items in repack stock entry ([a2d302b](a2d302b3fa))
* zero valuation rate if returning from different warehouse ([8ce51b2](8ce51b2f80))

### Features

* clear demo data from desktop screen (backport [#52128](https://github.com/frappe/erpnext/issues/52128)) ([#52147](https://github.com/frappe/erpnext/issues/52147)) ([05e30dc](05e30dc011))
* **credit-note:** add checkbox to set valuation rate as zero for expired batch ([b84fd46](b84fd46841))
* **delivery-note:** add status indicator when document is partially billed ([6048add](6048add4c0))
* document naming rule will now use posting date of the document ([b03494b](b03494bb67))
* **Transaction Deletion Record:** Editable "DocTypes To Delete" List with CSV import/export ([#50592](https://github.com/frappe/erpnext/issues/50592)) ([4963261](4963261dc8))
2026-02-04 04:29:22 +00:00
ruthra kumar
e8e9fb25fe Merge pull request #52347 from frappe/version-16-hotfix
chore: release v16
2026-02-04 09:57:57 +05:30
rohitwaghchaure
4a7e2742ec Merge pull request #52388 from frappe/mergify/bp/version-16-hotfix/pr-51422
fix: merge taxes in purchase receipt when get items from multiple purchase invoices (backport #51422)
2026-02-03 22:53:40 +05:30
rohitwaghchaure
55d5d6535b Merge pull request #52391 from frappe/mergify/bp/version-16-hotfix/pr-51898
fix: group item wise tax details by tax row (backport #51898)
2026-02-03 22:52:37 +05:30
rohitwaghchaure
b8ac04fb54 Merge branch 'version-16' into version-16-hotfix 2026-02-03 22:50:07 +05:30
ravibharathi656
45e4c04830 fix: group item wise tax details by tax row
(cherry picked from commit 57bd1facf5)
2026-02-03 15:38:48 +00:00
NaviN
d80c8d14b0 fix: merge taxes in purchase receipt when get items from multiple purchase invoices (#51422)
* fix: merge taxes in purchase receipt when get items from multiple purchase invoices

* fix: make merge tax configurable

* chore: follow standard merge taxes method

* chore: follow standard merge taxes method

(cherry picked from commit 6fde0a6261)
2026-02-03 15:34:03 +00:00
mergify[bot]
66e47f5651 Merge pull request #52380 from frappe/mergify/bp/version-16-hotfix/pr-52278 2026-02-03 15:32:58 +00:00
ruthra kumar
a3e8af19a6 Merge pull request #52379 from frappe/mergify/bp/version-16-hotfix/pr-51651
fix: correct exchange gain loss in ppr (backport #51651)
2026-02-03 20:59:41 +05:30
Mihir Kandoi
9b498a8da8 Merge pull request #52385 from frappe/mergify/bp/version-16-hotfix/pr-52259
fix(stock): include subcontracting order qty while calculating the bin qty (backport #52259)
2026-02-03 20:48:37 +05:30
Mihir Kandoi
25389be340 Merge pull request #52382 from frappe/mergify/bp/version-16-hotfix/pr-52374
fix(stock): fetch batch wise valuation rate in get_items (backport #52374)
2026-02-03 20:34:37 +05:30
Sudharsanan11
de244e0af7 fix(stock): include subcontracting order qty while calculating the bin qty
(cherry picked from commit de8f8ef9f4)
2026-02-03 14:55:27 +00:00
kavin-114
b132e3f22a fix(stock): fetch batch wise valuation rate in get_items
(cherry picked from commit c5df570262)
2026-02-03 14:47:52 +00:00
ruthra kumar
670fd79e38 Merge pull request #52377 from frappe/mergify/bp/version-16-hotfix/pr-52314
fix(journal-entry): normalize exchange rate to float (backport #52314)
2026-02-03 20:10:03 +05:30
ravibharathi656
e09406d085 fix: correct exchange gain loss in ppr
(cherry picked from commit 02e96039ac)
2026-02-03 14:35:58 +00:00
rohitwaghchaure
3bc348d6f0 Merge pull request #52376 from frappe/mergify/bp/version-16-hotfix/pr-52375
fix: zero valuation rate if returning from different warehouse (backport #52369) (backport #52375)
2026-02-03 20:04:39 +05:30
Dharanidharan2813
3f0032d793 fix(journal-entry): normalize exchange rate to float
(cherry picked from commit be0040ddc7)
2026-02-03 14:17:24 +00:00
ruthra kumar
163b848455 Merge pull request #52368 from frappe/mergify/bp/version-16-hotfix/pr-52320
fix: correct Sales Tax Template sidebar link to proper DocType (backport #52320)
2026-02-03 19:44:26 +05:30
Rohit Waghchaure
8ce51b2f80 fix: zero valuation rate if returning from different warehouse
(cherry picked from commit 28929df0e8)
(cherry picked from commit eb2119e292)
2026-02-03 13:59:59 +00:00
ruthra kumar
422b37332e Merge pull request #52367 from frappe/mergify/bp/version-16-hotfix/pr-52279
fix(profit and loss statement): exclude non period columns (backport #52279)
2026-02-03 17:47:37 +05:30
Luis Mendoza
4c14e74a12 fix: correct Sales Tax Template sidebar link to proper DocType
(cherry picked from commit 06a7c85c93)
2026-02-03 12:05:37 +00:00
ravibharathi656
28e8c40bfc fix(profit and loss statement): exclude non period columns
(cherry picked from commit 6180e5eb53)
2026-02-03 12:00:00 +00:00
ruthra kumar
660fc8f76a Merge pull request #52365 from frappe/mergify/bp/version-16-hotfix/pr-52160
fix(stock): remove is_return condition on pos batch qty calculation (backport #52160)
2026-02-03 17:19:50 +05:30
ruthra kumar
22456a5857 Merge pull request #52362 from frappe/mergify/bp/version-16-hotfix/pr-51997
Add partially billed status indicator (backport #51997)
2026-02-03 17:19:31 +05:30
kavin-114
76e0eb00a5 test: add unit test case for pos reserved with return qty
(cherry picked from commit 12ec997027)
2026-02-03 11:11:50 +00:00
kavin-114
9dcaf38142 fix(stock): remove is_return condition on pos batch qty calculation
(cherry picked from commit 2c19c1fd06)
2026-02-03 11:11:50 +00:00
Dharanidharan2813
6048add4c0 feat(delivery-note): add status indicator when document is partially billed
(cherry picked from commit 7767000ccf)
2026-02-03 10:59:20 +00:00
rohitwaghchaure
0552b48328 Merge pull request #52356 from frappe/mergify/bp/version-16-hotfix/pr-52338
fix: negative stock for purchase return (backport #52338)
2026-02-03 16:16:28 +05:30
ruthra kumar
193b29d5fc Merge pull request #52350 from frappe/mergify/bp/version-16-hotfix/pr-52339
chore: rename icons (backport #52339)
2026-02-03 16:13:06 +05:30
Rohit Waghchaure
220a528d7f fix: negative stock for purchase return
(cherry picked from commit 77893933a2)
2026-02-03 10:25:10 +00:00
ruthra kumar
e087a8b179 Merge pull request #52353 from frappe/mergify/bp/version-16-hotfix/pr-52345
ci: skip svg (backport #52345)
2026-02-03 15:41:53 +05:30
ruthra kumar
d7067f6b7a ci: skip svg
(cherry picked from commit e565d2283e)
2026-02-03 10:11:12 +00:00
Shllokkk
e53ccd0745 fix: move company field to first position in sales invoice, purchase invoice, sales order, purchase order and journal entry
(cherry picked from commit 8e9365eb3b)
2026-02-03 10:04:56 +00:00
sokumon
e264d8e2d6 chore: rename icons
(cherry picked from commit 2d312bcfe8)
2026-02-03 10:02:54 +00:00
ruthra kumar
8b2559ab0c Merge pull request #52337 from frappe/mergify/bp/version-16-hotfix/pr-52280
fix(stock): ignore packing slip while cancelling the sales invoice (backport #52280)
2026-02-03 13:58:59 +05:30
Sudharsanan11
f425f89a26 fix(stock): ignore packing slip while cancelling the sales invoice
(cherry picked from commit c58887b44a)
2026-02-03 08:25:04 +00:00
ruthra kumar
e3bf84c572 Merge pull request #52321 from frappe/mergify/bp/version-16-hotfix/pr-50592
feat(Transaction Deletion Record): Editable "DocTypes To Delete" List with CSV import/export (backport #50592)
2026-02-03 13:50:00 +05:30
ruthra kumar
e2b88218ec Merge pull request #52330 from frappe/mergify/bp/version-16-hotfix/pr-51655
fix: include credit notes in project gross margin calculation (backport #51655)
2026-02-03 12:19:28 +05:30
ravibharathi656
e755a4ad98 fix: include credit notes in project gross margin calculation
(cherry picked from commit a378fee8e0)
2026-02-03 06:07:49 +00:00
ruthra kumar
d2ea428030 chore: resolve conflict 2026-02-03 10:38:39 +05:30
Mihir Kandoi
496956f08f Merge pull request #52324 from frappe/mergify/bp/version-16-hotfix/pr-52184
fix(subcontracting): include item bom in supplied items grouping key (backport #52184)
2026-02-03 09:24:00 +05:30
Sudharsanan11
a3190dd556 test(subcontracting): add test for consumed_qty calculation with similar finished goods
(cherry picked from commit 4d9412181c)
2026-02-03 03:40:18 +00:00
Sudharsanan11
95c4b8de06 fix(subcontracting): include item bom in supplied items grouping key
(cherry picked from commit 0d372a62a1)
2026-02-03 03:40:18 +00:00
Henning Wendtland
4963261dc8 feat(Transaction Deletion Record): Editable "DocTypes To Delete" List with CSV import/export (#50592)
* feat: add editable DocTypes To Delete list with import/export

Add user control over transaction deletion with reviewable and reusable deletion templates.

- New "DocTypes To Delete" table allows users to review and customize what will be deleted before submission
- Import/Export CSV templates for reusability across environments
- Company field rule: only filter by company if field is specifically named "company", otherwise delete all records
- Child tables (istable=1) automatically excluded from selection
- "Remove Zero Counts" helper button to clean up list
- Backward compatible with existing deletion records

* refactor: improve Transaction Deletion Record code quality

- Remove unnecessary chatty comments from AI-generated code
- Add concise docstrings to all new methods
- Remove redundant @frappe.whitelist() decorators from internal methods
- Improve CSV import validation (header check, child table filtering)
- Add better error feedback with consolidated skip messages
- Reorder form fields: To Delete list now appears before Excluded list
- Add conditional visibility for Summary table (legacy records only)
- Improve architectural clarity: single API entry point per feature

Technical improvements:
- export_to_delete_template_method and import_to_delete_template_method
  are now internal helpers without whitelist decorators
- CSV import now validates format and provides detailed skip reasons
- Summary table only shows for submitted records without To Delete list
- Maintains backward compatibility for existing deletion records

* fix: field order

* test: fix broken tests and add new ones

* fix: adapt create_transaction_deletion_request

* test: fix assertRaises trigger

* fix: conditionally execute Transaction Deletion pre-tasks based on selected DocTypes

* refactor: replace boolean task flags with status fields

* fix: remove UI comment

* fix: don't allow virtual doctype selection and improve protected Doctype List

* fix: replace outdated frappe.db.sql by frappe.qb

* feat: add support for multiple company fields

* fix: autofill comapny field, add docstrings, filter for company_field

* fix: add edge case handling for update_naming_series and add tests for prefix extraction

* fix: use redis for running deletion validation, check per doctype instead of company

(cherry picked from commit 0fb37ad792)

# Conflicts:
#	erpnext/patches.txt
2026-02-03 00:49:04 +00:00
mergify[bot]
81e65757ee fix: duplicate account number (Indonesia COA) (backport #52080) (#52317)
Co-authored-by: Apriliansyah Idris <apriliansyahidris@gmail.com>
fix: duplicate account number (Indonesia COA) (#52080)
2026-02-02 19:09:22 +00:00
rohitwaghchaure
78e581154b Merge pull request #52312 from frappe/mergify/bp/version-16-hotfix/pr-52303
fix: batch selector not working if Use Legacy (Client side) Reactivity disabled (backport #52303)
2026-02-02 23:32:40 +05:30
Rohit Waghchaure
2a3642b55a fix: batch selector not working if Use Legacy (Client side) Reactivity disabled
(cherry picked from commit d1cba1073f)
2026-02-02 16:32:18 +00:00
Mihir Kandoi
beaa76ca16 Merge pull request #52311 from frappe/mergify/bp/version-16-hotfix/pr-52246 2026-02-02 21:01:34 +05:30
Mihir Kandoi
9997185071 Merge pull request #52246 from mihir-kandoi/st58765
(cherry picked from commit 135a433018)
2026-02-02 15:15:38 +00:00
Mihir Kandoi
681c0b5917 Merge pull request #52308 from frappe/mergify/bp/version-16-hotfix/pr-52304
fix: populate contact fields when creating quotation from customer (backport #52304)
2026-02-02 20:36:19 +05:30
Mihir Kandoi
4a0e04ee20 Merge pull request #52306 from frappe/mergify/bp/version-16-hotfix/pr-52281
fix(stock): add stock recon opening stock condition (backport #52281)
2026-02-02 20:24:00 +05:30
Mihir Kandoi
55129e697d fix: populate contact fields when creating quotation from customer
(cherry picked from commit 75b2c2c83d)
2026-02-02 14:46:36 +00:00
kavin-114
f9a8fc1f2d fix(stock): add stock recon opening stock condition
(cherry picked from commit f3eb6c7078)
2026-02-02 14:37:36 +00:00
Mihir Kandoi
091ff81ae5 Merge pull request #52302 from frappe/mergify/bp/version-16-hotfix/pr-52286
fix: reset incoming rate in selling controller if there are changes i… (backport #52286)
2026-02-02 20:05:37 +05:30
Mihir Kandoi
024e7b01ac fix: reset incoming rate in selling controller if there are changes in item
(cherry picked from commit 2d6b43fd54)
2026-02-02 14:18:20 +00:00
ruthra kumar
a0156b61b8 Merge pull request #52284 from frappe/mergify/bp/version-16-hotfix/pr-52200
fix(accounts): correct date in Journal Auditing Voucher print format (backport #52200)
2026-02-02 12:55:41 +05:30
Tamal Majumdar
7e5eab261c fix: journal auditing voucher print date to use posting_date
(cherry picked from commit 43e2495df8)
2026-02-02 07:21:36 +00:00
ruthra kumar
63782e6355 Merge pull request #52282 from frappe/mergify/bp/version-16-hotfix/pr-51692
fix: correct spelling of Payment Reconciliation in Accounting (backport #51692)
2026-02-02 12:43:17 +05:30
nivithamerlin
c80b554cd7 fix: correct spelling of Payment Reconciliation in Accounting
(cherry picked from commit 35e53d28df)
2026-02-02 07:09:54 +00:00
Mihir Kandoi
7db88b210e Merge pull request #52276 from frappe/mergify/bp/version-16-hotfix/pr-52274 2026-02-02 10:24:07 +05:30
Mihir Kandoi
42d873f1d9 test: over ordering of quotation items
(cherry picked from commit 53e58f6678)
2026-02-02 04:38:13 +00:00
MochaMind
19c1dcc3dd chore: update POT file (#52264) 2026-02-01 15:07:28 +01:00
Mihir Kandoi
23e027b6be Merge pull request #52230 from frappe/mergify/bp/version-16-hotfix/pr-52222
fix: validate over ordering of quotation (backport #52222)
2026-01-31 20:26:44 +05:30
Mihir Kandoi
d91cfa76e6 Merge pull request #52257 from frappe/mergify/bp/version-16-hotfix/pr-52253 2026-01-31 20:19:18 +05:30
Mihir Kandoi
a29df7be67 chore: resolve conflicts 2026-01-31 20:13:26 +05:30
Mihir Kandoi
dbe5846908 fix: make item name editable in RFQ
(cherry picked from commit d9998a977c)
2026-01-31 14:34:24 +00:00
Mihir Kandoi
83fcb5d2d8 Merge pull request #52255 from frappe/mergify/bp/version-16-hotfix/pr-52252
fix: better fix for #51495 (backport #52252)
2026-01-31 19:52:45 +05:30
Mihir Kandoi
b8ab55fee8 fix: better fix for aac39b2671
(cherry picked from commit b24ae5e9a2)
2026-01-31 14:21:27 +00:00
rohitwaghchaure
4d03f4ebaa Merge pull request #52240 from frappe/mergify/bp/version-16-hotfix/pr-52232
fix: validation when more than one FG items in repack stock entry (backport #52232)
2026-01-31 17:54:08 +05:30
Rohit Waghchaure
a2d302b3fa fix: validation when more than one FG items in repack stock entry
(cherry picked from commit 6423ce2fa7)
2026-01-31 07:16:45 +00:00
Mihir Kandoi
b5321d42a3 Merge pull request #52234 from frappe/mergify/bp/version-16-hotfix/pr-52231
fix: item code not showing in report view (backport #52231)
2026-01-30 22:17:26 +05:30
UmakanthKaspa
af167f91fe fix: item code not showing in report view
(cherry picked from commit b20f57321f)
2026-01-30 16:46:26 +00:00
Mihir Kandoi
e74389f01c fix: test cases
(cherry picked from commit 36f1e3572c)
2026-01-30 14:00:52 +00:00
Mihir Kandoi
e7ace8e620 fix: validate over ordering of quotation
(cherry picked from commit 4cc306d2d8)

# Conflicts:
#	erpnext/patches.txt
2026-01-30 14:00:52 +00:00
Mihir Kandoi
e23e9b5d66 Merge pull request #52227 from frappe/mergify/bp/version-16-hotfix/pr-52226 2026-01-30 18:03:40 +05:30
Mihir Kandoi
136b2cfba5 fix: failing test cases
(cherry picked from commit d3f44a425c)
2026-01-30 12:18:10 +00:00
Mihir Kandoi
3b3738577d Merge pull request #52225 from frappe/mergify/bp/version-16-hotfix/pr-51433 2026-01-30 17:30:01 +05:30
Mihir Kandoi
1e646bd0ed Merge pull request #52224 from frappe/mergify/bp/version-16-hotfix/pr-52223
fix: allow sales invoice to be renamed (backport #52223)
2026-01-30 17:19:10 +05:30
Mihir Kandoi
02e6c49130 test: add test case
(cherry picked from commit e2c3d0fa94)
2026-01-30 11:41:46 +00:00
Mihir Kandoi
e9fa725030 chore: make feature opt in
(cherry picked from commit b8d4522ea1)
2026-01-30 11:41:46 +00:00
Mihir Kandoi
b03494bb67 feat: document naming rule will now use posting date of the document
(cherry picked from commit 22fd1a1cfd)
2026-01-30 11:41:45 +00:00
Mihir Kandoi
f7b915dfe6 fix: allow sales invoice to be renamed
(cherry picked from commit 95fdbe55f9)
2026-01-30 11:33:20 +00:00
Mihir Kandoi
0a5aac9ce7 Merge pull request #52218 from frappe/mergify/bp/version-16-hotfix/pr-52209
fix: add precision to rejected batch no qty calculation (backport #52209)
2026-01-30 12:21:50 +05:30
Mihir Kandoi
e3c62070d1 Merge pull request #52215 from frappe/mergify/bp/version-16-hotfix/pr-52213
fix: hide close button on WO if WO is completed (backport #52213)
2026-01-30 12:06:39 +05:30
Mihir Kandoi
b365444027 fix: add precision to rejected batch no qty calculation
(cherry picked from commit 838d245215)
2026-01-30 06:35:59 +00:00
Mihir Kandoi
0d1c30f3f0 fix: hide close button on WO if WO is completed
(cherry picked from commit 6e17ccf499)
2026-01-30 06:29:32 +00:00
Mihir Kandoi
d0b553dca3 Merge pull request #52212 from frappe/mergify/bp/version-16-hotfix/pr-52210
fix(barcode): failing request when item has both batch and serial (backport #52210)
2026-01-30 11:52:49 +05:30
Mihir Kandoi
e4cdd971c8 fix(barcode): failing request when item has both batch and serial
(cherry picked from commit 89f6f0f46f)
2026-01-30 06:17:41 +00:00
mergify[bot]
78c4f01733 fix: missing depr_series causing error on jv creation (backport #52085) (#52206)
fix: missing depr_series causing error on jv creation (#52085)

(cherry picked from commit b565dd3da8)

Co-authored-by: Dany Robert <rtdany10@gmail.com>
2026-01-29 23:30:29 +05:30
Mihir Kandoi
eac4978278 Merge pull request #52203 from frappe/mergify/bp/version-16-hotfix/pr-52201
fix: hide item_wise_tax_details table from print (backport #52201)
2026-01-29 21:58:37 +05:30
Mihir Kandoi
c619be989b fix: hide item_wise_tax_details table from print
(cherry picked from commit c38f884095)
2026-01-29 16:12:55 +00:00
rohitwaghchaure
64921fc1b5 Merge pull request #52197 from frappe/mergify/bp/version-16-hotfix/pr-52190
fix: lead time calculation for FG item (backport #52190)
2026-01-29 19:06:53 +05:30
rohitwaghchaure
6d8d502bbf Merge pull request #52192 from frappe/mergify/bp/version-16-hotfix/pr-52158
Add Landed Cost Voucher Amount in Internal Purchase Receipt (backport #52158)
2026-01-29 18:07:46 +05:30
Rohit Waghchaure
5595602f24 fix: lead time calculation for FG item
(cherry picked from commit 646688c291)
2026-01-29 12:29:39 +00:00
kavin-114
7042f2b8fb test: add unit test to check internal purchase with lcv
(cherry picked from commit dd4fd89ef8)
2026-01-29 12:02:50 +00:00
kavin-114
f462639aa0 fix(stock): set incoming_rate with lcv rate for internal purchase
(cherry picked from commit f0dccc3cd7)
2026-01-29 12:02:49 +00:00
Mihir Kandoi
14ba0f1cae Merge pull request #52183 from frappe/mergify/bp/version-16-hotfix/pr-52181
fix: js error if user does not have write permission for date field (backport #52181)
2026-01-29 15:42:29 +05:30
Mihir Kandoi
3944dfde31 fix: js error if user does not have write permission for date field
(cherry picked from commit 7f6f39f5e7)
2026-01-29 10:01:33 +00:00
ruthra kumar
16cc2b0a25 Merge pull request #52177 from frappe/mergify/bp/version-16-hotfix/pr-52173
New accounting icons (backport #52173)
2026-01-29 14:51:36 +05:30
Jacob Salvi
3394e1a126 refactor: new accounting icons (#52173)
* chore: new icons share-management

* chore: new accounting icons

* chore: trigger CI

---------

Co-authored-by: Soham Kulkarni <77533095+sokumon@users.noreply.github.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
(cherry picked from commit cdcf3fa593)
2026-01-29 09:13:39 +00:00
mergify[bot]
66086010fc fix(demo): removed toolbar eventlistener (backport #52171) (#52172)
Co-authored-by: Diptanil Saha <diptanil@frappe.io>
fix(demo): removed toolbar eventlistener (#52171)
2026-01-29 11:29:59 +05:30
Mihir Kandoi
195a2f3e74 Merge pull request #52168 from frappe/mergify/bp/version-16-hotfix/pr-52166
fix: production plan not considering planning datetime when creating WO (backport #52166)
2026-01-29 11:06:50 +05:30
Mihir Kandoi
7e7b16b23e fix: production plan not considering planning datetime when creating WO
(cherry picked from commit 4e19c7e8bd)
2026-01-29 05:20:59 +00:00
Aarol D'Souza
f4beb41df2 Merge pull request #52164 from frappe/mergify/bp/version-16-hotfix/pr-52092
fix(RFQ): render email templates for preview and sending (backport #52092)
2026-01-29 09:23:39 +05:30
AarDG10
4c4aa9bbdf ci: minor text correction
(cherry picked from commit 37cdae2f34)
2026-01-29 03:38:02 +00:00
AarDG10
687a80d74c fix(RFQ): render email templates for preview and sending
(cherry picked from commit 525b3960e1)
2026-01-29 03:38:01 +00:00
rohitwaghchaure
f01e0576b9 Merge pull request #52141 from frappe/mergify/bp/version-16-hotfix/pr-52007
Fix: Set Zero Rate for Standalone Credit Note with Expired Batch (backport #52007)
2026-01-28 19:46:10 +05:30
Frappe PR Bot
83a0d957ef chore(release): Bumped to Version 16.3.0
# [16.3.0](https://github.com/frappe/erpnext/compare/v16.2.0...v16.3.0) (2026-01-28)

### Features

* clear demo data from desktop screen (backport [#52128](https://github.com/frappe/erpnext/issues/52128))  ([#52150](https://github.com/frappe/erpnext/issues/52150)) ([554aeb9](554aeb94fd))
2026-01-28 12:51:32 +00:00
mergify[bot]
554aeb94fd feat: clear demo data from desktop screen (backport #52128) (#52150)
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Soham Kulkarni <77533095+sokumon@users.noreply.github.com>
2026-01-28 18:19:41 +05:30
mergify[bot]
05e30dc011 feat: clear demo data from desktop screen (backport #52128) (#52147)
Co-authored-by: Soham Kulkarni <77533095+sokumon@users.noreply.github.com>
2026-01-28 17:36:04 +05:30
kavin-114
40a3dabd30 test(credit-note): add unit test for zero valuation rate on expired batch
(cherry picked from commit 3460a7efb5)
2026-01-28 10:43:58 +00:00
kavin-114
0f9bf08685 fix(credit-note): set incoming rate as zero for expired batch
(cherry picked from commit e78c750b4e)
2026-01-28 10:43:58 +00:00
kavin-114
b84fd46841 feat(credit-note): add checkbox to set valuation rate as zero for expired batch
(cherry picked from commit 04cdf88715)
2026-01-28 10:43:58 +00:00
Frappe PR Bot
6209d633c2 chore(release): Bumped to Version 16.2.0
# [16.2.0](https://github.com/frappe/erpnext/compare/v16.1.0...v16.2.0) (2026-01-28)

### Bug Fixes

* **accounts:** correct base grand total and rounded total mismatch (backport [#51739](https://github.com/frappe/erpnext/issues/51739)) ([#52101](https://github.com/frappe/erpnext/issues/52101)) ([6115f8f](6115f8fb9a))
* **asset capitalization:** update total_asset_cost on asset capitalisation submission (backport [#52077](https://github.com/frappe/erpnext/issues/52077)) ([#52115](https://github.com/frappe/erpnext/issues/52115)) ([4f16956](4f1695616a))
* autofill warehouse for packed items ([881562f](881562fc37))
* Bin reserved qty for production for extra material transfer ([bf53133](bf53133f94))
* calculate weighted average rate for customer provided items in subcontracting inward order ([7120fbd](7120fbd14b))
* check the payment ledger entry has the dimension ([#51823](https://github.com/frappe/erpnext/issues/51823)) ([7342b25](7342b2551b))
* check the payment ledger entry has the dimension (backport [#51823](https://github.com/frappe/erpnext/issues/51823)) ([#52108](https://github.com/frappe/erpnext/issues/52108)) ([1927adb](1927adbd2e))
* create DN btn should not be shown if it cannot be created ([30e6b5d](30e6b5daac))
* **customer:** add customer group filters ([b1716bf](b1716bfeef))
* disable asset repair when status is fully depreciated ([13e4849](13e4849c43))
* Ensure paid_amount is always numeric before calling allocate_amount_to_references (backport [#50935](https://github.com/frappe/erpnext/issues/50935)) ([#52036](https://github.com/frappe/erpnext/issues/52036)) ([e9f3f0f](e9f3f0f445))
* force user to enter batch or serial for serial/batch items ([91199ea](91199ea9c9))
* handle parent level project change ([0b7684e](0b7684eccd))
* handle undefined bank_transaction_mapping in quick entry ([22a8d48](22a8d483e1))
* job cards should not be deleted on close of WO ([7c2bbe0](7c2bbe0d82))
* **journal-entry:** prevent submit failure due to double background queuing (backport [#52083](https://github.com/frappe/erpnext/issues/52083)) ([#52087](https://github.com/frappe/erpnext/issues/52087)) ([46e6096](46e6096fe3))
* negative stock for purchae return ([fb3fb8c](fb3fb8ca5e))
* not able to complete the job card ([f486071](f486071cf6))
* **payment entry:** update currency symbol (backport [#51956](https://github.com/frappe/erpnext/issues/51956)) ([#52094](https://github.com/frappe/erpnext/issues/52094)) ([b1b1f25](b1b1f25bb1))
* **project:** add missing counter to project update naming series ([37a237d](37a237dbb7))
* rejected qty in PR doesn't consider conversion factor ([c7c7a55](c7c7a55a58))
* **sales order:** set project at item level from parent ([27fe754](27fe754a7d))
* **shipment:** user contact validation to use full name ([0a56647](0a56647a61))
* show everything else besides other party specific item ([7575861](75758610dd))
* show message if image is removed from item description (backport [#52088](https://github.com/frappe/erpnext/issues/52088)) ([#52097](https://github.com/frappe/erpnext/issues/52097)) ([53b7375](53b73757ed))
* **stock:** use purchase UOM in Supplier Quotation items ([f97b850](f97b850077))
* strip whitespace in customer_name ([41e6687](41e6687b35))
* swedish_address_template ([cff09b7](cff09b71cc))
* tests ([6fa60d2](6fa60d2f1a))
* throw if item order field is not set in subcontracting controller ([264855e](264855e5e1))
* unable to split asset from capitalization (backport [#52020](https://github.com/frappe/erpnext/issues/52020)) ([#52114](https://github.com/frappe/erpnext/issues/52114)) ([c1cc1db](c1cc1dbd27)), closes [#52016](https://github.com/frappe/erpnext/issues/52016) [#52016](https://github.com/frappe/erpnext/issues/52016)
* UOM of item not fetching in BOM ([1b9a93f](1b9a93f90e))
* update country_wise_tax.json for Algerian Taxes (backport [#51878](https://github.com/frappe/erpnext/issues/51878)) ([#52038](https://github.com/frappe/erpnext/issues/52038)) ([8946f12](8946f12677))
* validation to check at-least one raw material for manufacture entry ([d067e37](d067e37ab6))
* warehouse permissions in MR incorrectly ignored ([504c84e](504c84e28a))

### Features

* **accounts:** retain filters when switching between financial statements (backport [#51668](https://github.com/frappe/erpnext/issues/51668)) ([#52117](https://github.com/frappe/erpnext/issues/52117)) ([9ed3801](9ed3801d06))
2026-01-28 04:15:59 +00:00
ruthra kumar
095fe65bef Merge pull request #52103 from frappe/version-16-hotfix
chore: release v16
2026-01-28 09:44:30 +05:30
Mihir Kandoi
b285548a46 Merge pull request #52124 from frappe/mergify/bp/version-16-hotfix/pr-51961
fix(sales order): set project at item level from parent (backport #51961)
2026-01-27 21:55:49 +05:30
SowmyaArunachalam
0b7684eccd fix: handle parent level project change
(cherry picked from commit 543b6e51c0)
2026-01-27 16:24:22 +00:00
SowmyaArunachalam
574460c009 chore: use frappe.model.set_value
(cherry picked from commit 3b27f49d79)
2026-01-27 16:24:22 +00:00
SowmyaArunachalam
27fe754a7d fix(sales order): set project at item level from parent
(cherry picked from commit 9e51701e2a)
2026-01-27 16:24:22 +00:00
Mihir Kandoi
531fe59a24 Merge pull request #52122 from frappe/mergify/bp/version-16-hotfix/pr-52084
fix(shipment): user contact validation to use full name (backport #52084)
2026-01-27 21:29:22 +05:30
harrishragavan
0a56647a61 fix(shipment): user contact validation to use full name
(cherry picked from commit 3c6eb9a531)
2026-01-27 15:57:22 +00:00
Soham Kulkarni
c2f666b7a3 Merge pull request #52120 from frappe/mergify/bp/version-16-hotfix/pr-52119 2026-01-27 21:11:42 +05:30
sokumon
c1bbe1104e chore: change color of icons in accounting folders
(cherry picked from commit 6f9cd8c261)
2026-01-27 15:15:16 +00:00
ruthra kumar
2c86327c7e Merge pull request #52112 from frappe/mergify/bp/version-16-hotfix/pr-52106
fix: show everything else besides other party specific item (backport #52106)
2026-01-27 20:08:54 +05:30
ruthra kumar
31385a1f91 Merge pull request #52118 from frappe/mergify/bp/version-16-hotfix/pr-51894
refactor: accounting workspace (backport #51894)
2026-01-27 20:08:29 +05:30
mergify[bot]
4f1695616a fix(asset capitalization): update total_asset_cost on asset capitalisation submission (backport #52077) (#52115)
fix(asset capitalization): update total_asset_cost on asset capitalisation submission (#52077)

fix(asset capitalization): update total_asset_cost on asset capitalization submission

(cherry picked from commit ec41f1b0f5)

Co-authored-by: NaviN <118178330+Navin-S-R@users.noreply.github.com>
2026-01-27 19:31:52 +05:30
mergify[bot]
9ed3801d06 feat(accounts): retain filters when switching between financial statements (backport #51668) (#52117) 2026-01-27 19:03:44 +05:30
ruthra kumar
61ad67ec29 refactor: reuse icon for invoicing
(cherry picked from commit f0332c4dc7)
2026-01-27 13:15:37 +00:00
ruthra kumar
735b9da6b1 refactor: rename Accounts to Accounting
(cherry picked from commit fb9656b975)
2026-01-27 13:15:36 +00:00
ruthra kumar
fe7a797156 refactor: link payments dashboard to sidebar
(cherry picked from commit f7abf9c1da)
2026-01-27 13:15:36 +00:00
ruthra kumar
f951dd180a refactor: payments dashboard
(cherry picked from commit 99406ccc15)
2026-01-27 13:15:36 +00:00
ruthra kumar
8e871796d4 refactor: shed duplicates from invoicing sidebar
(cherry picked from commit 1295d7aa30)
2026-01-27 13:15:36 +00:00
ruthra kumar
c88ee50c34 refactor: reorder accounts setup sidebar
(cherry picked from commit 5a680d5037)
2026-01-27 13:15:35 +00:00
ruthra kumar
e49f6f4f09 refactor: introduce setup icon and reorder
(cherry picked from commit 7528d42187)
2026-01-27 13:15:35 +00:00
ruthra kumar
72942e6b8c refactor: payments sidebar and icon
(cherry picked from commit cbdc945287)
2026-01-27 13:15:35 +00:00
ruthra kumar
fdcf037f1b chore: rename accounting to invoicing
(cherry picked from commit faf0dcb102)
2026-01-27 13:15:35 +00:00
ruthra kumar
9e0c606b95 chore: remove accounting icon
(cherry picked from commit 5e02b4009e)
2026-01-27 13:15:34 +00:00
ruthra kumar
6b9f2ddf83 refactor: invoicing icon
(cherry picked from commit 8125f9035c)
2026-01-27 13:15:34 +00:00
mergify[bot]
c1cc1dbd27 fix: unable to split asset from capitalization (backport #52020) (#52114)
fix: unable to split asset from capitalization (#52020)

* fix: Allow split asset from capitalized composite asset (fixes #52016)

* test: Add test case for splitting asset created via capitalization (fixes #52016)

* docs: Add docstring to before_submit method

* fix: Remove unused variable and fix UTF-8 encoding in asset files

* fix: Remove UTF-8 BOM from asset.py to fix linting

* fix: Fix test_split_asset_created_via_capitalization test parameters

* fix: Remove unused import create_item

* chore: remove unnecessary comments

Removed validation comments for composite asset capitalization in before_submit method.

---------


(cherry picked from commit 7e9647f3f0)

Co-authored-by: madelyngamble2 <madelyngamble2@gmail.com>
Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2026-01-27 18:04:19 +05:30
Mihir Kandoi
de584e2e8d test: fix tests
(cherry picked from commit 5eeebbde7f)
2026-01-27 10:57:40 +00:00
Mihir Kandoi
75758610dd fix: show everything else besides other party specific item
(cherry picked from commit 71371b0ba5)
2026-01-27 10:57:40 +00:00
ruthra kumar
1927adbd2e fix: check the payment ledger entry has the dimension (backport #51823) (#52108)
fix: check the payment ledger entry has the dimension (#51823)

* fix: check the payment ledger entry has the dimension

* fix: add project in payment ledger entry

(cherry picked from commit efa3973b77)

Co-authored-by: Vishnu Priya Baskaran <145791817+ervishnucs@users.noreply.github.com>
2026-01-27 16:25:33 +05:30
Vishnu Priya Baskaran
7342b2551b fix: check the payment ledger entry has the dimension (#51823)
* fix: check the payment ledger entry has the dimension

* fix: add project in payment ledger entry

(cherry picked from commit efa3973b77)
2026-01-27 10:27:23 +00:00
mergify[bot]
6115f8fb9a fix(accounts): correct base grand total and rounded total mismatch (backport #51739) (#52101)
Co-authored-by: Dharanidharan S <dharanidharans1328@gmail.com>
fix(accounts): correct base grand total and rounded total mismatch (#51739)
2026-01-27 14:23:10 +05:30
mergify[bot]
53b73757ed fix: show message if image is removed from item description (backport #52088) (#52097)
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
2026-01-27 14:09:02 +05:30
rohitwaghchaure
dee3357da2 Merge pull request #52075 from frappe/mergify/bp/version-16-hotfix/pr-52062
fix: not able to complete the job card (backport #52062)
2026-01-27 13:03:43 +05:30
mergify[bot]
b1b1f25bb1 fix(payment entry): update currency symbol (backport #51956) (#52094)
Co-authored-by: NaviN <118178330+Navin-S-R@users.noreply.github.com>
fix(payment entry): update currency symbol (#51956)
2026-01-27 06:34:19 +00:00
mergify[bot]
46e6096fe3 fix(journal-entry): prevent submit failure due to double background queuing (backport #52083) (#52087)
Co-authored-by: V Shankar <shankarv292002@gmail.com>
fix(journal-entry): prevent submit failure due to double background queuing (#52083)
2026-01-27 05:53:05 +00:00
Rohit Waghchaure
f486071cf6 fix: not able to complete the job card
(cherry picked from commit 696ea68f86)
2026-01-26 17:45:21 +00:00
Mihir Kandoi
b541fbbd60 Merge pull request #52066 from frappe/mergify/bp/version-16-hotfix/pr-52064
fix: strip whitespace in customer_name (backport #52064)
2026-01-26 15:32:27 +05:30
Shankarv19bcr
41e6687b35 fix: strip whitespace in customer_name
(cherry picked from commit e5ba0e6401)
2026-01-26 09:47:06 +00:00
MochaMind
55ce40de37 chore: update POT file (#52058) 2026-01-25 20:37:09 +01:00
ruthra kumar
6f21ab5d9a Merge pull request #52040 from frappe/mergify/bp/version-16-hotfix/pr-51670
fix: handle undefined bank_transaction_mapping in quick entry (backport #51670)
2026-01-25 13:11:28 +05:30
ruthra kumar
7c81672b36 Merge pull request #52041 from frappe/mergify/bp/version-16-hotfix/pr-51691
refactor: not warn when filter field is missing in FS reports (backport #51691)
2026-01-25 13:10:02 +05:30
ruthra kumar
d0faff09cb Merge pull request #52055 from frappe/mergify/bp/version-16-hotfix/pr-52050
fix: swedish_address_template (backport #52050)
2026-01-25 13:08:42 +05:30
mahsem
cff09b71cc fix: swedish_address_template
(cherry picked from commit 334e8ada30)
2026-01-25 05:22:41 +00:00
rohitwaghchaure
b180e3b78c Merge pull request #52053 from frappe/mergify/bp/version-16-hotfix/pr-52043
fix: UOM of item not fetching in BOM (backport #52043)
2026-01-25 10:50:38 +05:30
rohitwaghchaure
6ba2795043 Merge pull request #51905 from frappe/mergify/bp/version-16-hotfix/pr-51900
fix: validation to check at-least one raw material for manufacture entry (backport #51900)
2026-01-25 10:45:11 +05:30
Rohit Waghchaure
1b9a93f90e fix: UOM of item not fetching in BOM
(cherry picked from commit ba8eadda52)
2026-01-25 05:15:05 +00:00
rohitwaghchaure
1f1428f00a Merge branch 'version-16-hotfix' into mergify/bp/version-16-hotfix/pr-51900 2026-01-24 13:49:24 +05:30
Abdeali Chharchhoda
606ac2a91a refactor: not warn when filter field is missing in FS reports
(cherry picked from commit d905f78984)
2026-01-24 07:08:08 +00:00
Abdeali Chharchhoda
9a175757ac refactor: use console.error for error logging in Plaid integration
(cherry picked from commit 9322095786)
2026-01-24 07:07:48 +00:00
Abdeali Chharchhoda
22a8d483e1 fix: handle undefined bank_transaction_mapping in quick entry
(cherry picked from commit 8a1b8259bd)
2026-01-24 07:07:47 +00:00
Abdeali Chharchhoda
7abaaed957 refactor: remove redundant onload function for bank mapping table
(cherry picked from commit 7c7ba0154a)
2026-01-24 07:07:47 +00:00
mergify[bot]
8946f12677 fix: update country_wise_tax.json for Algerian Taxes (backport #51878) (#52038)
fix: update country_wise_tax.json for Algerian Taxes (#51878)

* Algeria chart of accounts

Algeria chart of accounts

* Update Algeria Chart Of Account

* Algeria chart of account

* Algeria Chart of Account

Algeria Chart of Account

* Modify Algeria tax entries in country_wise_tax.json

Updated tax rates and account names for Algeria.

* Rename account for Algeria tax from VAT to TVA

Rename account for Algeria tax from VAT to TVA

(cherry picked from commit e810cd8440)

Co-authored-by: HALFWARE <contact@half-ware.com>
2026-01-24 06:48:16 +00:00
mergify[bot]
e9f3f0f445 fix: Ensure paid_amount is always numeric before calling allocate_amount_to_references (backport #50935) (#52036)
fix: Ensure paid_amount is always numeric before calling allocate_amount_to_references (#50935)

fix: ensure paid_amount is not null in allocate_party_amount_against_ref_docs
(cherry picked from commit 50b3396064)

Co-authored-by: El-Shafei H. <el.shafei.developer@gmail.com>
2026-01-24 12:03:34 +05:30
ruthra kumar
ba38bc3eaf Merge pull request #52026 from frappe/mergify/bp/version-16-hotfix/pr-51756
fix: disable asset repair when status is fully depreciated (backport #51756)
2026-01-24 09:46:53 +05:30
rohitwaghchaure
b4572978f9 Merge pull request #52031 from frappe/mergify/bp/version-16-hotfix/pr-52024
fix: Bin reserved qty for production for extra material transfer (backport #52024)
2026-01-24 08:47:44 +05:30
Rohit Waghchaure
bf53133f94 fix: Bin reserved qty for production for extra material transfer
(cherry picked from commit f5378b6573)
2026-01-23 15:45:46 +00:00
Mihir Kandoi
23c902c317 Merge pull request #52022 from frappe/mergify/bp/version-16-hotfix/pr-51999
fix(stock): use purchase UOM in Supplier Quotation items (backport #51999)
2026-01-23 19:21:12 +05:30
SowmyaArunachalam
13e4849c43 fix: disable asset repair when status is fully depreciated
(cherry picked from commit 66fe1aa85d)
2026-01-23 11:38:39 +00:00
Bharathidhasan06
f97b850077 fix(stock): use purchase UOM in Supplier Quotation items
(cherry picked from commit 2606ca6fa9)
2026-01-23 08:34:36 +00:00
rohitwaghchaure
b3e12f9acb Merge pull request #52015 from frappe/mergify/bp/version-16-hotfix/pr-52006
fix: negative stock for purchase return (backport #52006)
2026-01-23 13:22:36 +05:30
Rohit Waghchaure
fb3fb8ca5e fix: negative stock for purchae return
(cherry picked from commit d68a04ad16)
2026-01-23 06:04:02 +00:00
rohitwaghchaure
e2232340dc Merge pull request #52005 from frappe/mergify/bp/version-16-hotfix/pr-51989
fix: autofill warehouse for packed items (backport #51989)
2026-01-22 23:56:30 +05:30
Sudharsanan11
881562fc37 fix: autofill warehouse for packed items
(cherry picked from commit 3f8a0a4833)
2026-01-22 17:28:22 +00:00
Mihir Kandoi
dcd6279d47 Merge pull request #51983 from frappe/mergify/bp/version-16-hotfix/pr-51908
fix: throw if item order field is not set in subcontracting controller (backport #51908)
2026-01-22 10:53:05 +05:30
Mihir Kandoi
041a7c5a57 Merge pull request #51982 from frappe/mergify/bp/version-16-hotfix/pr-51929
fix: calculate weighted average rate for customer provided items in subcontracting inward order (backport #51929)
2026-01-22 10:51:54 +05:30
Mihir Kandoi
27ffef41a7 Merge pull request #51980 from frappe/mergify/bp/version-16-hotfix/pr-51966
fix(customer): add customer group filters (backport #51966)
2026-01-22 10:42:45 +05:30
Mihir Kandoi
9038f19fb6 Merge pull request #51978 from frappe/mergify/bp/version-16-hotfix/pr-51967
fix(project): add missing counter to project update naming series (backport #51967)
2026-01-22 10:38:33 +05:30
ljain112
264855e5e1 fix: throw if item order field is not set in subcontracting controller
(cherry picked from commit d256365f4a)
2026-01-22 05:05:22 +00:00
ljain112
7120fbd14b fix: calculate weighted average rate for customer provided items in subcontracting inward order
(cherry picked from commit 37ee560eae)
2026-01-22 05:02:16 +00:00
SowmyaArunachalam
b1716bfeef fix(customer): add customer group filters
(cherry picked from commit 1e3db9f916)
2026-01-22 04:57:04 +00:00
ravibharathi656
37a237dbb7 fix(project): add missing counter to project update naming series
(cherry picked from commit 49e64f4e1c)
2026-01-22 04:53:10 +00:00
Mihir Kandoi
be9112b6fc Merge pull request #51972 from frappe/mergify/bp/version-16-hotfix/pr-51968 2026-01-22 09:04:25 +05:30
Mihir Kandoi
2f240f3553 Merge pull request #51970 from frappe/mergify/bp/version-16-hotfix/pr-51964
fix: create DN btn should not be shown if it cannot be created (backport #51964)
2026-01-21 22:54:50 +05:30
Mihir Kandoi
c7c7a55a58 fix: rejected qty in PR doesn't consider conversion factor
(cherry picked from commit 343ee9695b)
2026-01-21 17:21:00 +00:00
Mihir Kandoi
30e6b5daac fix: create DN btn should not be shown if it cannot be created
(cherry picked from commit 70ec977cb2)
2026-01-21 17:09:48 +00:00
Mihir Kandoi
0b5cc039b6 Merge pull request #51962 from frappe/mergify/bp/version-16-hotfix/pr-51958
fix!: force user to enter batch or serial for serial/batch items (backport #51958)
2026-01-21 16:38:31 +05:30
Mihir Kandoi
6fa60d2f1a fix: tests
(cherry picked from commit 035b3cb61e)
2026-01-21 10:53:46 +00:00
Mihir Kandoi
91199ea9c9 fix: force user to enter batch or serial for serial/batch items
(cherry picked from commit 7170a1bd78)
2026-01-21 10:53:46 +00:00
Mihir Kandoi
e23ba0e852 Merge pull request #51960 from frappe/mergify/bp/version-16-hotfix/pr-51947
fix: job cards should not be deleted on close of WO (backport #51947)
2026-01-21 16:03:09 +05:30
Mihir Kandoi
7c2bbe0d82 fix: job cards should not be deleted on close of WO
(cherry picked from commit c919b1de38)
2026-01-21 10:17:16 +00:00
Mihir Kandoi
0a2234a814 Merge pull request #51951 from frappe/mergify/bp/version-16-hotfix/pr-51948
fix: warehouse permissions in MR incorrectly ignored (backport #51948)
2026-01-21 14:05:14 +05:30
Mihir Kandoi
504c84e28a fix: warehouse permissions in MR incorrectly ignored
(cherry picked from commit 5bacb67d36)
2026-01-21 07:36:22 +00:00
ruthra kumar
bb2bada1fd Merge pull request #51945 from ruthra-kumar/reenable_auto_close
chore: reenable auto close
2026-01-21 10:16:58 +05:30
ruthra kumar
ca85ee33f5 chore: reenable auto close 2026-01-21 10:13:32 +05:30
ruthra kumar
21c1189e24 Merge pull request #51944 from ruthra-kumar/remove_junk_comment
chore: remove stray comment and disable auto close
2026-01-21 10:10:35 +05:30
ruthra kumar
7e7885b304 chore: remove stray comment and disable auto close 2026-01-21 10:09:03 +05:30
Frappe PR Bot
30238e3063 chore(release): Bumped to Version 16.1.0
# [16.1.0](https://github.com/frappe/erpnext/compare/v16.0.1...v16.1.0) (2026-01-20)

### Bug Fixes

* **accounts_controller:** make return message translatable ([621243c](621243c1d3))
* **accounts:** add missing accounting dimensions in advance taxes and charges ([673635e](673635e2c3))
* add below-0 column in ar/ap report (backport [#51673](https://github.com/frappe/erpnext/issues/51673)) ([#51780](https://github.com/frappe/erpnext/issues/51780)) ([5c93bf5](5c93bf5798))
* add company filters for warehouse ([ccab91b](ccab91b9ed))
* add other charges in total ([68c8dfb](68c8dfb24c))
* add uom js error ([a660ed0](a660ed061b))
* add validation for amount and hours ([ce421bb](ce421bb1d4))
* add validation for direct return ([bfd6375](bfd6375508))
* add validation for duplication ([84a749e](84a749e3d0))
* add validation for return against ([6dade11](6dade11d8f))
* allow creation of DN in SI for items not having DN reference ([fef6df7](fef6df709d))
* allow disassemble stock entry without work order (backport [#51761](https://github.com/frappe/erpnext/issues/51761)) ([#51836](https://github.com/frappe/erpnext/issues/51836)) ([c830bf6](c830bf6fc7))
* **bank_account:** validation for is_company_account ([5d5d208](5d5d208a49))
* **bom:** pass company warehouse filter ([3c533d0](3c533d04f5))
* **budget variance report:** check budget dimensions ([a3d860e](a3d860eabf))
* bugs ([accce1f](accce1fe59))
* calculate net profit amount from root node accounts ([89b44c4](89b44c41a2))
* change docfield type to render html format (backport [#51795](https://github.com/frappe/erpnext/issues/51795)) ([#51804](https://github.com/frappe/erpnext/issues/51804)) ([fcea760](fcea7603a8))
* common_party_path ([#51826](https://github.com/frappe/erpnext/issues/51826)) ([aeb2b60](aeb2b60450))
* continuous raw material consumption with bom validation (backport [#51914](https://github.com/frappe/erpnext/issues/51914)) ([#51919](https://github.com/frappe/erpnext/issues/51919)) ([c9d7c6c](c9d7c6cd42))
* docs_path ([86d5939](86d5939d91))
* dont show certain fields based on permissions ([d3dfed9](d3dfed909e))
* handle return cancellation ([65a1c70](65a1c7086b))
* include total hours validation in depends on ([cbfc137](cbfc13728b))
* **manufacturing:** consider process loss qty while validating the work order ([7b3f746](7b3f74609a))
* no attribute error on LCV ([fe59ace](fe59ace285))
* no attribute error on subcontracting receipt ([2131c7a](2131c7aadb))
* overproduction % not considered when making WO from SO ([fb669eb](fb669eb6f4))
* **pos:** reapply set warehouse during cart update ([6869115](686911546f))
* **postgres:** compute current month sales without DATE_FORMAT ([49760e4](49760e4542))
* prevent UOM from updating incorrectly while scanning barcode ([9d5a0e5](9d5a0e56a0))
* qty with serial no count ([ae6b3af](ae6b3af013))
* remove already transferred batch ([f1e41f4](f1e41f4a4f))
* setting process loss qty causes fg item qty to be incorrect ([cb2d455](cb2d4550af))
* Show non-SLE vouchers with GL entries in Stock vs Account Value Comparison report ([e64ae9a](e64ae9a8a9))
* **stock:** resolve quantity issue when adding items via barcode scan ([ab482ca](ab482caac9))
* **transaction.js:** use flt instead of cint for plc_conversion_rate ([8ba4701](8ba470160d))
* validation message in stock reco row idx ([176096b](176096bc5b))
* valuation rate for non batchwise valuation ([768c131](768c131073))

### Features

* add list_view status for partial billing ([9b88275](9b88275312))
* add new 2025 Charts of Accounts for France ([9cc9fa5](9cc9fa59be))
* Adding Item name in update item dialog box ([1da8ed2](1da8ed202b))
* modify field properties ([e49add2](e49add20b7))
* remove old French chart of accounts with code as nex 2025 is provided ([3bdaab1](3bdaab149b))
* support for serial item ([c4c2d35](c4c2d35565))
* **timesheet:** handle partial billing in sales invoice ([332673f](332673f260))

### Performance Improvements

* prevent duplicate reposting for the same item ([3ac431b](3ac431bd50))
2026-01-20 16:47:59 +00:00
ruthra kumar
35b3045b72 Merge pull request #51911 from frappe/version-16-hotfix
chore: release v16
2026-01-20 22:16:27 +05:30
Mihir Kandoi
cf130ff865 Merge pull request #51936 from frappe/mergify/bp/version-16-hotfix/pr-51934
fix: validation message in stock reco row idx (backport #51934)
2026-01-20 21:05:40 +05:30
Mihir Kandoi
176096bc5b fix: validation message in stock reco row idx
(cherry picked from commit 3960c01798)
2026-01-20 15:17:53 +00:00
rohitwaghchaure
e854eafc0b Merge pull request #51933 from frappe/mergify/bp/version-16-hotfix/pr-51930
Revert "perf: prevent duplicate reposting for the same item" (backport #51930)
2026-01-20 20:05:41 +05:30
rohitwaghchaure
72cdddbeda Revert "perf: prevent duplicate reposting for the same item"
(cherry picked from commit 6e4b90055f)
2026-01-20 14:19:47 +00:00
mergify[bot]
c9d7c6cd42 fix: continuous raw material consumption with bom validation (backport #51914) (#51919)
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
2026-01-20 12:56:27 +00:00
Diptanil Saha
8393c3c32d Merge pull request #51922 from frappe/mergify/bp/version-16-hotfix/pr-51887
fix(bank_account): `is_company_account` related validations (backport #51887)
2026-01-20 18:09:01 +05:30
Mihir Kandoi
5752d2e0a1 Merge pull request #51926 from frappe/mergify/bp/version-16-hotfix/pr-51909
fix: allow creation of DN in SI for items not having DN reference (backport #51909)
2026-01-20 18:03:35 +05:30
rohitwaghchaure
f25558b4d7 Merge pull request #51924 from frappe/mergify/bp/version-16-hotfix/pr-51920
perf: prevent duplicate reposting for the same item (backport #51920)
2026-01-20 18:01:21 +05:30
Mihir Kandoi
fef6df709d fix: allow creation of DN in SI for items not having DN reference
(cherry picked from commit b691de0147)
2026-01-20 12:14:59 +00:00
Rohit Waghchaure
3ac431bd50 perf: prevent duplicate reposting for the same item
(cherry picked from commit 7535931571)
2026-01-20 12:09:03 +00:00
diptanilsaha
5d5d208a49 fix(bank_account): validation for is_company_account
(cherry picked from commit 7532ab01d6)
2026-01-20 11:53:16 +00:00
ruthra kumar
9535f3d583 Merge pull request #51916 from frappe/mergify/bp/version-16-hotfix/pr-51671
fix(accounts): add missing accounting dimensions in advance taxes and charges (backport #51671)
2026-01-20 17:19:35 +05:30
Nikhil Kothari
673635e2c3 fix(accounts): add missing accounting dimensions in advance taxes and charges
(cherry picked from commit 22e9cb4cf4)

# Conflicts:
#	erpnext/patches.txt
2026-01-20 17:04:51 +05:30
Rohit Waghchaure
d067e37ab6 fix: validation to check at-least one raw material for manufacture entry
(cherry picked from commit f003b3c378)
2026-01-20 08:25:59 +00:00
Mihir Kandoi
37e241ba15 Merge pull request #51897 from frappe/mergify/bp/version-16-hotfix/pr-51895
fix: overproduction % not considered when making WO from SO (backport #51895)
2026-01-20 13:25:01 +05:30
Mihir Kandoi
fb669eb6f4 fix: overproduction % not considered when making WO from SO
(cherry picked from commit edba9efb5e)
2026-01-20 07:34:24 +00:00
ruthra kumar
232225d753 Merge pull request #51891 from frappe/mergify/bp/version-16-hotfix/pr-51561
fix: delete advance ledger entries  while reconciling payment entry (backport #51561)
2026-01-20 08:17:44 +05:30
ruthra kumar
80cbd851d1 Merge pull request #51893 from frappe/mergify/bp/version-16-hotfix/pr-51886
fix(accounts_controller): make return message translatable (backport #51886)
2026-01-20 08:13:12 +05:30
ruthra kumar
5474ac298d Merge pull request #51884 from frappe/mergify/bp/version-16-hotfix/pr-51830
fix(manufacturing): consider process loss qty while validating the work order (backport #51830)
2026-01-20 08:08:29 +05:30
ruthra kumar
7a9b10a05e Merge pull request #51861 from frappe/mergify/bp/version-16-hotfix/pr-51822
fix(budget variance report): check budget dimensions (backport #51822)
2026-01-20 07:56:49 +05:30
barredterra
621243c1d3 fix(accounts_controller): make return message translatable
(cherry picked from commit 0209f0fe29)
2026-01-20 02:26:48 +00:00
Lakshit Jain
efa5173964 Merge pull request #51561 from ljain112/fic-adv-ple-po
fix: delete advance ledger entries  while reconciling payment entry
(cherry picked from commit aea70c5ec1)
2026-01-20 02:21:34 +00:00
Sudharsanan11
7b3f74609a fix(manufacturing): consider process loss qty while validating the work order
(cherry picked from commit e6366e830c)
2026-01-19 16:18:36 +00:00
Mihir Kandoi
775f6d07b1 Merge pull request #51882 from frappe/mergify/bp/version-16-hotfix/pr-51880
fix: no attribute error on LCV (backport #51880)
2026-01-19 20:30:03 +05:30
Mihir Kandoi
e80ed14456 Merge pull request #51881 from frappe/mergify/bp/version-16-hotfix/pr-51879
fix: no attribute error on subcontracting receipt (backport #51879)
2026-01-19 20:15:55 +05:30
Mihir Kandoi
fe59ace285 fix: no attribute error on LCV
(cherry picked from commit ad11914fca)
2026-01-19 14:35:22 +00:00
Mihir Kandoi
2131c7aadb fix: no attribute error on subcontracting receipt
(cherry picked from commit fbac8b032e)
2026-01-19 14:30:08 +00:00
Diptanil Saha
b7284c7717 Merge pull request #51877 from frappe/mergify/bp/version-16-hotfix/pr-51595 2026-01-19 18:12:07 +05:30
Florian HENRY
6b9107c05c chore: re add older template
(cherry picked from commit b3efb3084f)
2026-01-19 12:23:31 +00:00
Florian HENRY
1ed8857d31 chore: fix bank account type
(cherry picked from commit 4fe1b214c1)
2026-01-19 12:23:31 +00:00
Florian HENRY
a195690bc8 chore: fix CASH acount type
(cherry picked from commit 6a876de838)
2026-01-19 12:23:31 +00:00
Florian HENRY
0c546c9e5a chore: fix bank acount type
(cherry picked from commit 765487a087)
2026-01-19 12:23:30 +00:00
Florian HENRY
11d9fd3dee chore: add Expenses Included In Valuation account
(cherry picked from commit c519cd0268)
2026-01-19 12:23:30 +00:00
Florian HENRY
3bdaab149b feat: remove old French chart of accounts with code as nex 2025 is provided
(cherry picked from commit bf430fce09)
2026-01-19 12:23:30 +00:00
Florian HENRY
ad4ac4e53c chore: Review PR #51595
(cherry picked from commit 6bdaeb983d)
2026-01-19 12:23:30 +00:00
Florian HENRY
9cc9fa59be feat: add new 2025 Charts of Accounts for France
(cherry picked from commit c81dee137f)
2026-01-19 12:23:30 +00:00
rohitwaghchaure
ab2aedd9a2 Merge pull request #51866 from frappe/mergify/bp/version-16-hotfix/pr-51769
fix(pos): reapply set warehouse during cart update (backport #51769)
2026-01-19 15:44:38 +05:30
ravibharathi656
686911546f fix(pos): reapply set warehouse during cart update
(cherry picked from commit 5a53c45321)
2026-01-19 10:07:50 +00:00
rohitwaghchaure
4f3078ab1a Merge pull request #51863 from frappe/mergify/bp/version-16-hotfix/pr-51690
feat: Adding Item name in update item dialog box (backport #51690)
2026-01-19 15:34:47 +05:30
rohitwaghchaure
a950adab79 Merge pull request #51864 from frappe/mergify/bp/version-16-hotfix/pr-51856
fix: qty with serial no count (backport #51856)
2026-01-19 15:34:23 +05:30
Rohit Waghchaure
ae6b3af013 fix: qty with serial no count
(cherry picked from commit 56e58ef301)
2026-01-19 10:00:35 +00:00
Nishka Gosalia
1da8ed202b feat: Adding Item name in update item dialog box
(cherry picked from commit e6133ad6d4)
2026-01-19 10:00:34 +00:00
ervishnucs
a3d860eabf fix(budget variance report): check budget dimensions
(cherry picked from commit cb696a8880)
2026-01-19 09:55:17 +00:00
rohitwaghchaure
adc9dc82ca Merge pull request #51848 from frappe/mergify/bp/version-16-hotfix/pr-51644
Refactor batch bundle get snos sle (backport #51644)
2026-01-19 15:15:20 +05:30
Rohit Waghchaure
79e04ea1fe chore: fix semantic commit message
(cherry picked from commit dfcbee9cc0)
2026-01-19 09:22:45 +00:00
krupalvora
0981b894dd refactor: Batch & Bundle get sle for snos - Added docstring
(cherry picked from commit 22dee50348)
2026-01-19 09:22:45 +00:00
krupalvora
380564a677 refactor: Batch & Bundle get Stock ledger for snos - added posting date in select
(cherry picked from commit 1ccc7365a7)
2026-01-19 09:22:45 +00:00
krupalvora
75deb180fb refactor: Batch & Bundle get Stock ledger for snos v2
(cherry picked from commit a074d81754)
2026-01-19 09:22:45 +00:00
krupalvora
839315752b refactor: Batch & Bundle get Stock ledger for snos
(cherry picked from commit c0149925ad)
2026-01-19 09:22:44 +00:00
Mihir Kandoi
2b4a547e23 Merge pull request #51847 from frappe/mergify/bp/version-16-hotfix/pr-51845
fix(bom): pass company warehouse filter (backport #51845)
2026-01-19 14:18:39 +05:30
22-poojashree
3c533d04f5 fix(bom): pass company warehouse filter
(cherry picked from commit 73bcfc4710)
2026-01-19 08:34:16 +00:00
ruthra kumar
1c214eec98 Merge pull request #51844 from frappe/mergify/bp/version-16-hotfix/pr-51826
fix: common_party_path (backport #51826)
2026-01-19 13:21:14 +05:30
mahsem
aeb2b60450 fix: common_party_path (#51826)
* fix: common_pary_path

* chore: remove non-existent anchor

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
(cherry picked from commit 0c0f43f7f7)
2026-01-19 07:50:30 +00:00
ruthra kumar
1b3f5e1c96 Merge pull request #51841 from frappe/mergify/bp/version-16-hotfix/pr-51513
fix: calculate net profit amount from root node accounts (backport #51513)
2026-01-19 13:05:56 +05:30
mergify[bot]
c830bf6fc7 fix: allow disassemble stock entry without work order (backport #51761) (#51836)
fix: allow disassemble stock entry without work order (#51761)

* fix: allow disassemble stock entry without work order

* fix: use existing functionality to load fg item

* chore: better dict update

(cherry picked from commit 83919119f8)

Co-authored-by: Smit Vora <smitvora203@gmail.com>
2026-01-19 12:54:06 +05:30
ruthra kumar
e2b95da24d Merge pull request #51839 from frappe/mergify/bp/version-16-hotfix/pr-51787
fix: recalculate taxes when item tax template changes after discount (backport #51787)
2026-01-19 12:50:34 +05:30
Navin-S-R
89b44c41a2 fix: calculate net profit amount from root node accounts
(cherry picked from commit c84986d00e)
2026-01-19 07:15:50 +00:00
Lakshit Jain
181141b56a Merge pull request #51787 from ljain112/fix-taxes-disc
fix: recalculate taxes when item tax template changes after discount
(cherry picked from commit f00aeec9b4)
2026-01-19 07:01:52 +00:00
ruthra kumar
5742a5d86a Merge pull request #51834 from frappe/mergify/bp/version-16-hotfix/pr-51742
fix: add other charges in total (backport #51742)
2026-01-19 11:34:22 +05:30
SowmyaArunachalam
68c8dfb24c fix: add other charges in total
(cherry picked from commit 9406c07c42)
2026-01-19 05:45:20 +00:00
Mihir Kandoi
7f54de7926 Merge pull request #51829 from frappe/mergify/bp/version-16-hotfix/pr-51824
fix: setting process loss qty causes fg item qty to be incorrect (backport #51824)
2026-01-18 22:51:58 +05:30
Mihir Kandoi
cb2d4550af fix: setting process loss qty causes fg item qty to be incorrect
(cherry picked from commit 56f5df6847)
2026-01-18 17:21:03 +00:00
Mihir Kandoi
c22d7e16d1 Merge pull request #51821 from frappe/mergify/bp/version-16-hotfix/pr-51817
fix: prevent UOM from updating incorrectly while scanning barcode (backport #51817)
2026-01-18 15:10:56 +05:30
Pandiyan5273
9d5a0e56a0 fix: prevent UOM from updating incorrectly while scanning barcode
(cherry picked from commit 30263b26a5)
2026-01-18 09:36:44 +00:00
mergify[bot]
fcea7603a8 fix: change docfield type to render html format (backport #51795) (#51804)
fix: change docfield type to render html format (#51795)

(cherry picked from commit 3fe5b5c80d)

Co-authored-by: Sowmya <106989392+SowmyaArunachalam@users.noreply.github.com>
2026-01-17 15:12:57 +05:30
ruthra kumar
42ebb7446a Merge pull request #51797 from frappe/mergify/bp/version-16-hotfix/pr-51555
fix(postgres): compute current month sales without DATE_FORMAT (backport #51555)
2026-01-16 17:15:48 +05:30
Matt Howard
49760e4542 fix(postgres): compute current month sales without DATE_FORMAT
(cherry picked from commit 64f391adf7)
2026-01-16 11:29:08 +00:00
Mihir Kandoi
6e1f4d84b6 Merge pull request #51794 from frappe/mergify/bp/version-16-hotfix/pr-51790
fix(stock): resolve quantity issue when adding items via barcode scan (backport #51790)
2026-01-16 16:20:37 +05:30
Pandiyan5273
ab482caac9 fix(stock): resolve quantity issue when adding items via barcode scan
(cherry picked from commit f959b2c59a)
2026-01-16 10:49:36 +00:00
Mihir Kandoi
d8506fb2c0 Merge pull request #51792 from frappe/mergify/bp/version-16-hotfix/pr-51791
fix: dont show certain fields based on permissions (backport #51791)
2026-01-16 16:02:37 +05:30
Mihir Kandoi
d3dfed909e fix: dont show certain fields based on permissions
(cherry picked from commit b3db2981de)
2026-01-16 10:31:39 +00:00
Mihir Kandoi
ac31c5ca19 Merge pull request #51789 from frappe/mergify/bp/version-16-hotfix/pr-51784
fix: add company filters for warehouse (backport #51784)
2026-01-16 15:16:05 +05:30
SowmyaArunachalam
ccab91b9ed fix: add company filters for warehouse
(cherry picked from commit f952b92d71)
2026-01-16 09:44:42 +00:00
Mihir Kandoi
541a8b135a Merge pull request #51785 from frappe/mergify/bp/version-16-hotfix/pr-51693 2026-01-16 14:09:49 +05:30
Mihir Kandoi
c0a30a5302 chore: typo
(cherry picked from commit 8fd1d6aec8)
2026-01-16 08:25:03 +00:00
Mihir Kandoi
accce1fe59 fix: bugs
(cherry picked from commit 19ae405742)
2026-01-16 08:25:03 +00:00
Mihir Kandoi
f04221417e test: add test case
(cherry picked from commit b567184dd7)
2026-01-16 08:25:03 +00:00
Mihir Kandoi
c4c2d35565 feat: support for serial item
(cherry picked from commit 3d0f649411)
2026-01-16 08:25:02 +00:00
Mihir Kandoi
f1e41f4a4f fix: remove already transferred batch
(cherry picked from commit b54067e04d)
2026-01-16 08:25:02 +00:00
Mihir Kandoi
d9326d80de refactor: sample retention stock entry
(cherry picked from commit 8d188cd32b)
2026-01-16 08:25:02 +00:00
ruthra kumar
5c93bf5798 fix: add below-0 column in ar/ap report (backport #51673) (#51780)
Merge pull request #51673 from Jatin3128/ar/ap-future-range-fix

fix: add below-0 column in ar/ap report
(cherry picked from commit c5b0787de6)

Co-authored-by: Jatin3128 <140256508+Jatin3128@users.noreply.github.com>
2026-01-16 12:46:26 +05:30
Jatin3128
f62ad83d6f Merge pull request #51673 from Jatin3128/ar/ap-future-range-fix
fix: add below-0 column in ar/ap report
(cherry picked from commit c5b0787de6)
2026-01-16 06:37:34 +00:00
Ankush Menat
876e2d4e6e build: Update Frappe dependency (#51779) 2026-01-16 11:24:43 +05:30
rohitwaghchaure
4977e06c50 Merge pull request #51772 from frappe/mergify/bp/version-16-hotfix/pr-51768
fix: Show non-SLE vouchers with GL entries in Stock vs Account Value … (backport #51768)
2026-01-15 19:26:45 +05:30
Rohit Waghchaure
e64ae9a8a9 fix: Show non-SLE vouchers with GL entries in Stock vs Account Value Comparison report
(cherry picked from commit 1db9ce205f)
2026-01-15 12:20:36 +00:00
rohitwaghchaure
6ddf4eee15 Merge pull request #51752 from frappe/mergify/bp/version-16-hotfix/pr-51729
fix: valuation rate for non batchwise valuation (backport #51729)
2026-01-15 17:00:32 +05:30
Mihir Kandoi
d27a09cb9f Merge pull request #51755 from frappe/mergify/bp/version-16-hotfix/pr-51753
fix: docs_path (backport #51753)
2026-01-14 21:31:31 +05:30
mahsem
86d5939d91 fix: docs_path
(cherry picked from commit 7ef8c81caf)
2026-01-14 16:00:03 +00:00
Rohit Waghchaure
768c131073 fix: valuation rate for non batchwise valuation
(cherry picked from commit b6312bca9c)
2026-01-14 14:06:50 +00:00
Diptanil Saha
8f77223057 Merge pull request #51748 from frappe/mergify/bp/version-16-hotfix/pr-51730
fix(transaction.js): use flt instead of cint for plc_conversion_rate (backport #51730)
2026-01-14 15:55:13 +05:30
diptanilsaha
8ba470160d fix(transaction.js): use flt instead of cint for plc_conversion_rate
(cherry picked from commit 8b445e04e5)
2026-01-14 10:22:21 +00:00
Mihir Kandoi
1a6264d831 Merge pull request #51737 from frappe/mergify/bp/version-16-hotfix/pr-51684 2026-01-14 11:37:00 +05:30
Mihir Kandoi
19a90c0980 Merge pull request #51736 from frappe/mergify/bp/version-16-hotfix/pr-51295 2026-01-14 11:18:57 +05:30
Pandiyan5273
d57fc49896 test(stock-entry): manufacture entry without work order
(cherry picked from commit 784e338be4)
2026-01-14 05:34:40 +00:00
l0gesh29
fe0431a6d0 chore: modify error msg
(cherry picked from commit f7004aa8c3)
2026-01-14 05:33:39 +00:00
l0gesh29
bfd6375508 fix: add validation for direct return
(cherry picked from commit 8379b39aaf)
2026-01-14 05:33:38 +00:00
l0gesh29
6dade11d8f fix: add validation for return against
(cherry picked from commit ff9b936634)
2026-01-14 05:33:38 +00:00
Logesh Periyasamy
ce421bb1d4 fix: add validation for amount and hours
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
(cherry picked from commit 43d1d685c6)
2026-01-14 05:33:38 +00:00
l0gesh29
84a749e3d0 fix: add validation for duplication
(cherry picked from commit cda8a97f4a)
2026-01-14 05:33:37 +00:00
l0gesh29
65a1c7086b fix: handle return cancellation
(cherry picked from commit 50f73a5072)
2026-01-14 05:33:37 +00:00
l0gesh29
a04da71182 test: add test for partial billing and return
(cherry picked from commit ae594e81f9)
2026-01-14 05:33:37 +00:00
l0gesh29
cbfc13728b fix: include total hours validation in depends on
(cherry picked from commit 57d34ab146)
2026-01-14 05:33:37 +00:00
l0gesh29
9b88275312 feat: add list_view status for partial billing
(cherry picked from commit ff0b37055b)
2026-01-14 05:33:36 +00:00
l0gesh29
332673f260 feat(timesheet): handle partial billing in sales invoice
(cherry picked from commit c87b5d3132)
2026-01-14 05:33:36 +00:00
l0gesh29
e49add20b7 feat: modify field properties
(cherry picked from commit 38a4642479)
2026-01-14 05:33:36 +00:00
Mihir Kandoi
c3b0633eda Merge pull request #51734 from frappe/mergify/bp/version-16-hotfix/pr-51733
fix: add uom js error (backport #51733)
2026-01-14 10:28:24 +05:30
Mihir Kandoi
a660ed061b fix: add uom js error
(cherry picked from commit 6d3f6d73d0)
2026-01-14 04:55:22 +00:00
Frappe PR Bot
0b1c0c36b5 chore(release): Bumped to Version 16.0.1
## [16.0.1](https://github.com/frappe/erpnext/compare/v16.0.0...v16.0.1) (2026-01-13)

### Bug Fixes

* **asset value adjustment:** skip cancelling revaluation journal entry if already cancelled (backport [#51666](https://github.com/frappe/erpnext/issues/51666)) ([#51716](https://github.com/frappe/erpnext/issues/51716)) ([4b85d51](4b85d51257))
* Redirect to Desktop after signup ([#51696](https://github.com/frappe/erpnext/issues/51696)) ([0363b01](0363b01ab7))
* Redirect to Desktop after signup ([#51696](https://github.com/frappe/erpnext/issues/51696)) ([#51697](https://github.com/frappe/erpnext/issues/51697)) ([294fb27](294fb27dc8))
* Redirect to Desktop after signup (backport [#51696](https://github.com/frappe/erpnext/issues/51696)) ([#51714](https://github.com/frappe/erpnext/issues/51714)) ([2118321](211832104c))
* stock module not opened when no warehouses ([3420e21](3420e21d45))
* **tds:** correct tax logic for customer ([50ce61a](50ce61ae02))
2026-01-13 16:20:34 +00:00
Mihir Kandoi
d316ef2306 Merge pull request #51728 from frappe/trigger-release-v16 2026-01-13 21:44:48 +05:30
Mihir Kandoi
af3a7903b3 chore: trigger release 2026-01-13 21:43:30 +05:30
Mihir Kandoi
a66e114a71 Merge pull request #51727 from frappe/change-release-branch 2026-01-13 21:34:26 +05:30
Mihir Kandoi
631b9d3bb0 chore: update release branch from version-13 to version-16 2026-01-13 20:32:48 +05:30
Mihir Kandoi
eb03781718 Merge pull request #51713 from frappe/version-16-hotfix 2026-01-13 20:17:06 +05:30
rohitwaghchaure
eb7cebac91 Merge pull request #51720 from frappe/mergify/bp/version-16-hotfix/pr-51719
fix: stock module not opened when no warehouses (backport #51719)
2026-01-13 17:38:25 +05:30
Rohit Waghchaure
3420e21d45 fix: stock module not opened when no warehouses
(cherry picked from commit 9de3b07223)
2026-01-13 11:49:56 +00:00
Mihir Kandoi
211832104c fix: Redirect to Desktop after signup (backport #51696) (#51714)
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
fix: Redirect to Desktop after signup (#51696)
2026-01-13 16:07:20 +05:30
mergify[bot]
4b85d51257 fix(asset value adjustment): skip cancelling revaluation journal entry if already cancelled (backport #51666) (#51716)
Co-authored-by: Navin-S-R <navin@aerele.in>
2026-01-13 16:05:14 +05:30
Nabin Hait
0363b01ab7 fix: Redirect to Desktop after signup (#51696)
(cherry picked from commit 3bc58fb46f)
2026-01-13 09:46:21 +00:00
Mihir Kandoi
fc517f7fa2 Merge pull request #51707 from mihir-kandoi/ci-patch-test-2 2026-01-13 15:11:37 +05:30
ruthra kumar
18451b69e6 Merge pull request #51703 from frappe/mergify/bp/version-16-hotfix/pr-51412
fix(tds): correct tax logic for customer (backport #51412)
2026-01-13 11:41:28 +05:30
ljain112
50ce61ae02 fix(tds): correct tax logic for customer
(cherry picked from commit 86b0f67dbc)
2026-01-13 05:37:32 +00:00
Nabin Hait
294fb27dc8 fix: Redirect to Desktop after signup (#51696) (#51697) 2026-01-12 19:22:24 +05:30
Rohit Waghchaure
c3fdb191b9 Merge branch 'develop' into version-16 2026-01-12 16:20:48 +05:30
Rohit Waghchaure
93db2ebd6f Merge branch 'develop' into version-16 2026-01-12 15:07:27 +05:30
rohitwaghchaure
2925f9a04e chore: weekly release for v16 2026-01-12 14:29:14 +05:30
rohitwaghchaure
c7bf103c0c chore: fix version 2026-01-12 14:04:45 +05:30
rohitwaghchaure
6dead8fd85 chore: fix version 2026-01-12 12:19:58 +05:30
419 changed files with 24134 additions and 6225 deletions

View File

@@ -60,7 +60,7 @@ body:
description: Share exact version number of Frappe and ERPNext you are using.
placeholder: |
Frappe version -
ERPNext Verion -
ERPNext version -
validations:
required: true

View File

@@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
version: ["14", "15"]
version: ["14", "15", "16"]
steps:
- uses: octokit/request-action@v2.x

View File

@@ -113,8 +113,8 @@ jobs:
jq 'del(.install_apps)' ~/frappe-bench/sites/test_site/site_config.json > tmp.json
mv tmp.json ~/frappe-bench/sites/test_site/site_config.json
wget https://erpnext.com/files/v13-erpnext.sql.gz
bench --site test_site --force restore ~/frappe-bench/v13-erpnext.sql.gz
wget https://frappe.io/files/erpnext-v14.sql.gz
bench --site test_site --force restore ~/frappe-bench/erpnext-v14.sql.gz
git -C "apps/frappe" remote set-url upstream https://github.com/frappe/frappe.git
git -C "apps/erpnext" remote set-url upstream https://github.com/frappe/erpnext.git
@@ -142,7 +142,6 @@ jobs:
bench --site test_site migrate
}
update_to_version 14 3.11
update_to_version 15 3.13
echo "Updating to latest version"

View File

@@ -2,7 +2,7 @@ name: Generate Semantic Release
on:
push:
branches:
- version-13
- version-16
permissions:
contents: read

View File

@@ -7,6 +7,7 @@ on:
paths:
- "**.js"
- "**.css"
- "**.svg"
- "**.md"
- "**.html"
- 'crowdin.yml'

View File

@@ -1,5 +1,5 @@
{
"branches": ["version-13"],
"branches": ["version-16"],
"plugins": [
"@semantic-release/commit-analyzer", {
"preset": "angular",
@@ -21,4 +21,4 @@
],
"@semantic-release/github"
]
}
}

View File

@@ -1,3 +1,4 @@
<div align="center">
<a href="https://frappe.io/erpnext">
<img src="./erpnext/public/images/v16/erpnext.svg" alt="ERPNext Logo" height="80px" width="80xp"/>

View File

@@ -6,7 +6,7 @@ import frappe
from frappe.model.document import Document
from frappe.utils.user import is_website_user
__version__ = "16.0.0-dev"
__version__ = "16.8.3"
def get_default_company(user=None):

View File

@@ -0,0 +1,50 @@
{
"cards": [
{
"card": "Total Outgoing Bills"
},
{
"card": "Total Incoming Bills"
},
{
"card": "Total Incoming Payment"
},
{
"card": "Total Outgoing Payment"
}
],
"charts": [
{
"chart": "Incoming Bills (Purchase Invoice)",
"width": "Half"
},
{
"chart": "Outgoing Bills (Sales Invoice)",
"width": "Half"
},
{
"chart": "Accounts Receivable Ageing",
"width": "Half"
},
{
"chart": "Accounts Payable Ageing",
"width": "Half"
},
{
"chart": "Bank Balance",
"width": "Full"
}
],
"creation": "2026-01-26 21:25:12.793893",
"dashboard_name": "Payments",
"docstatus": 0,
"doctype": "Dashboard",
"idx": 0,
"is_default": 0,
"is_standard": 1,
"modified": "2026-01-26 21:25:12.793893",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payments",
"owner": "Administrator"
}

View File

@@ -33,6 +33,17 @@
},
"account_number": "1151.000"
},
"Pajak Dibayar di Muka": {
"PPN Masukan": {
"account_number": "1152.001",
"account_type": "Tax"
},
"PPh 23 Dibayar di Muka": {
"account_number": "1152.002",
"account_type": "Tax"
},
"account_number": "1152.000"
},
"account_number": "1150.000"
},
"Kas": {
@@ -97,17 +108,6 @@
},
"account_number": "1130.000"
},
"Pajak Dibayar di Muka": {
"PPN Masukan": {
"account_number": "1151.001",
"account_type": "Tax"
},
"PPh 23 Dibayar di Muka": {
"account_number": "1152.001",
"account_type": "Tax"
},
"account_number": "1150.000"
},
"account_number": "1100.000"
},

View File

@@ -20,6 +20,10 @@
"enable_common_party_accounting",
"allow_multi_currency_invoices_against_single_party_account",
"confirm_before_resetting_posting_date",
"analytics_section",
"enable_accounting_dimensions",
"column_break_vtnr",
"enable_discounts_and_margin",
"journals_section",
"merge_similar_account_heads",
"deferred_accounting_settings_section",
@@ -51,12 +55,16 @@
"allow_pegged_currencies_exchange_rates",
"column_break_yuug",
"stale_days",
"payments_tab",
"section_break_jpd0",
"auto_reconcile_payments",
"auto_reconciliation_job_trigger",
"reconciliation_queue_size",
"column_break_resa",
"exchange_gain_loss_posting_date",
"payment_options_section",
"enable_loyalty_point_program",
"column_break_ctam",
"invoicing_settings_tab",
"accounts_transactions_settings_section",
"over_billing_allowance",
@@ -281,7 +289,7 @@
},
{
"default": "0",
"description": "Learn about <a href=\"https://docs.erpnext.com/docs/v13/user/manual/en/accounts/articles/common_party_accounting#:~:text=Common%20Party%20Accounting%20in%20ERPNext,Invoice%20against%20a%20primary%20Supplier.\">Common Party</a>",
"description": "Learn about <a href=\"https://docs.frappe.io/erpnext/user/manual/en/common_party_accounting\" rel=\"noopener noreferrer\">Common Party</a>",
"fieldname": "enable_common_party_accounting",
"fieldtype": "Check",
"label": "Enable Common Party Accounting"
@@ -637,16 +645,59 @@
"fieldname": "budget_section",
"fieldtype": "Section Break",
"label": "Budget"
},
{
"fieldname": "analytics_section",
"fieldtype": "Section Break",
"label": "Analytical Accounting"
},
{
"fieldname": "column_break_vtnr",
"fieldtype": "Column Break"
},
{
"default": "0",
"description": "Apply discounts and margins on products",
"fieldname": "enable_discounts_and_margin",
"fieldtype": "Check",
"label": "Enable Discounts and Margin"
},
{
"fieldname": "payments_tab",
"fieldtype": "Tab Break",
"label": "Payments"
},
{
"fieldname": "payment_options_section",
"fieldtype": "Section Break",
"label": "Payment Options"
},
{
"default": "0",
"fieldname": "enable_loyalty_point_program",
"fieldtype": "Check",
"label": "Enable Loyalty Point Program"
},
{
"fieldname": "column_break_ctam",
"fieldtype": "Column Break"
},
{
"default": "0",
"description": "Enable cost center, projects and other custom accounting dimensions",
"fieldname": "enable_accounting_dimensions",
"fieldtype": "Check",
"label": "Enable Accounting Dimensions"
}
],
"grid_page_length": 50,
"hide_toolbar": 1,
"hide_toolbar": 0,
"icon": "icon-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2026-01-11 18:30:45.968531",
"modified": "2026-02-04 17:15:38.609327",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -12,6 +12,28 @@ from frappe.utils import cint
from erpnext.accounts.utils import sync_auto_reconcile_config
SELLING_DOCTYPES = [
"Sales Invoice",
"Sales Order",
"Delivery Note",
"Quotation",
"Sales Invoice Item",
"Sales Order Item",
"Delivery Note Item",
"Quotation Item",
"POS Invoice",
"POS Invoice Item",
]
BUYING_DOCTYPES = [
"Purchase Invoice",
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice Item",
"Purchase Order Item",
"Purchase Receipt Item",
]
class AccountsSettings(Document):
# begin: auto-generated types
@@ -43,9 +65,12 @@ class AccountsSettings(Document):
default_ageing_range: DF.Data | None
delete_linked_ledger_entries: DF.Check
determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"]
enable_accounting_dimensions: DF.Check
enable_common_party_accounting: DF.Check
enable_discounts_and_margin: DF.Check
enable_fuzzy_matching: DF.Check
enable_immutable_ledger: DF.Check
enable_loyalty_point_program: DF.Check
enable_party_matching: DF.Check
exchange_gain_loss_posting_date: DF.Literal["Invoice", "Payment", "Reconciliation Date"]
fetch_valuation_rate_for_internal_transaction: DF.Check
@@ -98,6 +123,18 @@ class AccountsSettings(Document):
if old_doc.show_payment_schedule_in_print != self.show_payment_schedule_in_print:
self.enable_payment_schedule_in_print()
if old_doc.enable_accounting_dimensions != self.enable_accounting_dimensions:
toggle_accounting_dimension_sections(not self.enable_accounting_dimensions)
clear_cache = True
if old_doc.enable_discounts_and_margin != self.enable_discounts_and_margin:
toggle_sales_discount_section(not self.enable_discounts_and_margin)
clear_cache = True
if old_doc.enable_loyalty_point_program != self.enable_loyalty_point_program:
toggle_loyalty_point_program_section(not self.enable_loyalty_point_program)
clear_cache = True
if clear_cache:
frappe.clear_cache()
@@ -154,3 +191,36 @@ class AccountsSettings(Document):
frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.init_procedure_name}")
frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.allocate_procedure_name}")
def toggle_accounting_dimension_sections(hide):
accounting_dimension_doctypes = frappe.get_hooks("accounting_dimension_doctypes")
for doctype in accounting_dimension_doctypes:
create_property_setter_for_hiding_field(doctype, "accounting_dimensions_section", hide)
def toggle_sales_discount_section(hide):
for doctype in SELLING_DOCTYPES + BUYING_DOCTYPES:
meta = frappe.get_meta(doctype)
if meta.has_field("additional_discount_section"):
create_property_setter_for_hiding_field(doctype, "additional_discount_section", hide)
if meta.has_field("discount_and_margin"):
create_property_setter_for_hiding_field(doctype, "discount_and_margin", hide)
def toggle_loyalty_point_program_section(hide):
for doctype in SELLING_DOCTYPES:
meta = frappe.get_meta(doctype)
if meta.has_field("loyalty_points_redemption"):
create_property_setter_for_hiding_field(doctype, "loyalty_points_redemption", hide)
def create_property_setter_for_hiding_field(doctype, field_name, hide):
make_property_setter(
doctype,
field_name,
"hidden",
hide,
"Check",
validate_fields_for_doctype=False,
)

View File

@@ -50,6 +50,7 @@
"fieldname": "amount",
"fieldtype": "Currency",
"label": "Amount",
"options": "currency",
"read_only": 1
},
{

View File

@@ -3,9 +3,6 @@
frappe.provide("erpnext.integrations");
frappe.ui.form.on("Bank", {
onload: function (frm) {
add_fields_to_mapping_table(frm);
},
refresh: function (frm) {
add_fields_to_mapping_table(frm);
frm.toggle_display(["address_html", "contact_html"], !frm.doc.__islocal);
@@ -37,11 +34,11 @@ let add_fields_to_mapping_table = function (frm) {
});
});
frm.fields_dict.bank_transaction_mapping.grid.update_docfield_property(
"bank_transaction_field",
"options",
options
);
const grid = frm.fields_dict.bank_transaction_mapping?.grid;
if (grid) {
grid.update_docfield_property("bank_transaction_field", "options", options);
}
};
erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
@@ -116,7 +113,7 @@ erpnext.integrations.refreshPlaidLink = class refreshPlaidLink {
"There was an issue connecting to Plaid's authentication server. Check browser console for more information"
)
);
console.log(error);
console.error(error);
}
plaid_success(token, response) {

View File

@@ -42,8 +42,4 @@ frappe.ui.form.on("Bank Account", {
});
}
},
is_company_account: function (frm) {
frm.set_df_property("account", "reqd", frm.doc.is_company_account);
},
});

View File

@@ -52,6 +52,7 @@
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company Account",
"mandatory_depends_on": "is_company_account",
"options": "Account"
},
{
@@ -98,6 +99,7 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Company",
"mandatory_depends_on": "is_company_account",
"options": "Company"
},
{
@@ -252,7 +254,7 @@
"link_fieldname": "default_bank_account"
}
],
"modified": "2025-08-29 12:32:01.081687",
"modified": "2026-01-20 00:46:16.633364",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Account",

View File

@@ -51,25 +51,29 @@ class BankAccount(Document):
delete_contact_and_address("Bank Account", self.name)
def validate(self):
self.validate_company()
self.validate_account()
self.validate_is_company_account()
self.update_default_bank_account()
def validate_account(self):
if self.account:
if accounts := frappe.db.get_all(
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
):
frappe.throw(
_("'{0}' account is already used by {1}. Use another account.").format(
frappe.bold(self.account),
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
)
)
def validate_is_company_account(self):
if self.is_company_account:
if not self.company:
frappe.throw(_("Company is mandatory for company account"))
def validate_company(self):
if self.is_company_account and not self.company:
frappe.throw(_("Company is mandatory for company account"))
if not self.account:
frappe.throw(_("Company Account is mandatory"))
self.validate_account()
def validate_account(self):
if accounts := frappe.db.get_all(
"Bank Account", filters={"account": self.account, "name": ["!=", self.name]}, as_list=1
):
frappe.throw(
_("'{0}' account is already used by {1}. Use another account.").format(
frappe.bold(self.account),
frappe.bold(comma_and([get_link_to_form(self.doctype, x[0]) for x in accounts])),
)
)
def update_default_bank_account(self):
if self.is_default and not self.disabled:

View File

@@ -139,6 +139,8 @@ class BankTransaction(Document):
self.set_status()
def on_cancel(self):
self.ignore_linked_doctypes = ["GL Entry"]
for payment_entry in self.payment_entries:
self.delink_payment_entry(payment_entry)
@@ -373,11 +375,12 @@ def get_clearance_details(transaction, payment_entry, bt_allocations, gl_entries
("unallocated_amount", "bank_account"),
as_dict=True,
)
bt_bank_account = frappe.db.get_value("Bank Account", bt.bank_account, "account")
if bt.bank_account != gl_bank_account:
if bt_bank_account != gl_bank_account:
frappe.throw(
_("Bank Account {} in Bank Transaction {} is not matching with Bank Account {}").format(
bt.bank_account, payment_entry.payment_entry, gl_bank_account
bt_bank_account, payment_entry.payment_entry, gl_bank_account
)
)

View File

@@ -15,7 +15,7 @@ from frappe.database.operator_map import OPERATOR_MAP
from frappe.query_builder import Case
from frappe.query_builder.functions import Sum
from frappe.utils import cstr, date_diff, flt, getdate
from pypika.terms import LiteralValue
from pypika.terms import Bracket, LiteralValue
from erpnext import get_company_currency
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
@@ -541,7 +541,7 @@ class FinancialQueryBuilder:
.where(acb_table.period_closing_voucher == closing_voucher)
)
query = self._apply_standard_filters(query, acb_table)
query = self._apply_standard_filters(query, acb_table, "Account Closing Balance")
results = self._execute_with_permissions(query, "Account Closing Balance")
for row in results:
@@ -636,12 +636,15 @@ class FinancialQueryBuilder:
return self._execute_with_permissions(query, "GL Entry")
def _calculate_running_balances(self, balances_data: dict, gl_data: list[dict]) -> dict:
for row in gl_data:
account = row["account"]
gl_dict = {row["account"]: row for row in gl_data}
accounts = set(balances_data.keys()) | set(gl_dict.keys())
for account in accounts:
if account not in balances_data:
balances_data[account] = AccountData(account=account, **self._get_account_meta(account))
account_data: AccountData = balances_data[account]
gl_movement = gl_dict.get(account, {})
if account_data.has_periods():
first_period = account_data.get_period(self.periods[0]["key"])
@@ -651,20 +654,13 @@ class FinancialQueryBuilder:
for period in self.periods:
period_key = period["key"]
movement = row.get(period_key, 0.0)
movement = gl_movement.get(period_key, 0.0)
closing_balance = current_balance + movement
account_data.add_period(PeriodValue(period_key, current_balance, closing_balance, movement))
current_balance = closing_balance
# Accounts with no movements
for account_data in balances_data.values():
for period in self.periods:
period_key = period["key"]
if period_key not in account_data.period_values:
account_data.add_period(PeriodValue(period_key, 0.0, 0.0, 0.0))
def _handle_balance_accumulation(self, balances_data):
for account_data in balances_data.values():
account_data: AccountData
@@ -683,12 +679,12 @@ class FinancialQueryBuilder:
else:
account_data.unaccumulate_values()
def _apply_standard_filters(self, query, table):
def _apply_standard_filters(self, query, table, doctype: str = "GL Entry"):
if self.filters.get("ignore_closing_entries"):
if hasattr(table, "is_period_closing_voucher_entry"):
query = query.where(table.is_period_closing_voucher_entry == 0)
else:
if doctype == "GL Entry":
query = query.where(table.voucher_type != "Period Closing Voucher")
else:
query = query.where(table.is_period_closing_voucher_entry == 0)
if self.filters.get("project"):
projects = self.filters.get("project")
@@ -736,7 +732,7 @@ class FinancialQueryBuilder:
user_conditions = build_match_conditions(doctype)
if user_conditions:
query = query.where(LiteralValue(user_conditions))
query = query.where(Bracket(LiteralValue(user_conditions)))
return query.run(as_dict=True)

View File

@@ -16,7 +16,8 @@ from erpnext.accounts.doctype.financial_report_template.financial_report_engine
from erpnext.accounts.doctype.financial_report_template.test_financial_report_template import (
FinancialReportTemplateTestCase,
)
from erpnext.accounts.utils import get_currency_precision
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
from erpnext.accounts.utils import get_currency_precision, get_fiscal_year
# On IntegrationTestCase, the doctype test records and all
# link-field test record dependencies are recursively loaded
@@ -1672,3 +1673,360 @@ class TestFilterExpressionParser(FinancialReportTemplateTestCase):
mock_row_invalid = self._create_mock_report_row(invalid_formula)
condition = parser.build_condition(mock_row_invalid, account_table)
self.assertIsNone(condition)
class TestFinancialQueryBuilder(FinancialReportTemplateTestCase):
def test_fetch_balances_with_journal_entries(self):
company = "_Test Company"
cash_account = "_Test Cash - _TC"
bank_account = "_Test Bank - _TC"
# Create journal entries in different periods
# October: Transfer 1000 from Bank to Cash
jv_oct = make_journal_entry(
account1=cash_account,
account2=bank_account,
amount=1000,
posting_date="2024-10-15",
company=company,
submit=True,
)
# November: Transfer 500 from Bank to Cash
jv_nov = make_journal_entry(
account1=cash_account,
account2=bank_account,
amount=500,
posting_date="2024-11-20",
company=company,
submit=True,
)
# December: No transactions (test zero movement period)
try:
# Set up filters and periods for Q4 2024
filters = {
"company": company,
"from_fiscal_year": "2024",
"to_fiscal_year": "2024",
"period_start_date": "2024-10-01",
"period_end_date": "2024-12-31",
"filter_based_on": "Date Range",
"periodicity": "Monthly",
}
periods = [
{"key": "2024_oct", "from_date": "2024-10-01", "to_date": "2024-10-31"},
{"key": "2024_nov", "from_date": "2024-11-01", "to_date": "2024-11-30"},
{"key": "2024_dec", "from_date": "2024-12-01", "to_date": "2024-12-31"},
]
query_builder = FinancialQueryBuilder(filters, periods)
# Create account objects as expected by fetch_account_balances
accounts = [
frappe._dict({"name": cash_account, "account_name": "Cash", "account_number": "1001"}),
frappe._dict({"name": bank_account, "account_name": "Bank", "account_number": "1002"}),
]
# Fetch balances using the full workflow
balances_data = query_builder.fetch_account_balances(accounts)
# Verify Cash account balances
cash_data = balances_data.get(cash_account)
self.assertIsNotNone(cash_data, "Cash account should exist in results")
# October: movement = +1000 (debit)
oct_cash = cash_data.get_period("2024_oct")
self.assertIsNotNone(oct_cash, "October period should exist for cash")
self.assertEqual(oct_cash.movement, 1000.0, "October cash movement should be 1000")
# November: movement = +500
nov_cash = cash_data.get_period("2024_nov")
self.assertIsNotNone(nov_cash, "November period should exist for cash")
self.assertEqual(nov_cash.movement, 500.0, "November cash movement should be 500")
self.assertEqual(
nov_cash.opening, oct_cash.closing, "November opening should equal October closing"
)
# December: movement = 0 (no transactions)
dec_cash = cash_data.get_period("2024_dec")
self.assertIsNotNone(dec_cash, "December period should exist for cash")
self.assertEqual(dec_cash.movement, 0.0, "December cash movement should be 0")
self.assertEqual(
dec_cash.closing,
nov_cash.closing,
"December closing should equal November closing when no movement",
)
# Verify Bank account balances (opposite direction)
bank_data = balances_data.get(bank_account)
self.assertIsNotNone(bank_data, "Bank account should exist in results")
oct_bank = bank_data.get_period("2024_oct")
self.assertEqual(oct_bank.movement, -1000.0, "October bank movement should be -1000")
nov_bank = bank_data.get_period("2024_nov")
self.assertEqual(nov_bank.movement, -500.0, "November bank movement should be -500")
finally:
# Clean up: cancel journal entries
jv_nov.cancel()
jv_oct.cancel()
def test_opening_balance_from_previous_period_closing(self):
company = "_Test Company"
cash_account = "_Test Cash - _TC"
sales_account = "Sales - _TC"
posting_date_2023 = "2023-06-15"
# Create journal entry in prior period (2023)
# Cash Dr 5000, Sales Cr 5000
jv_2023 = make_journal_entry(
account1=cash_account,
account2=sales_account,
amount=5000,
posting_date=posting_date_2023,
company=company,
submit=True,
)
pcv = None
jv_2024 = None
original_pcv_setting = frappe.db.get_single_value(
"Accounts Settings", "use_legacy_controller_for_pcv"
)
try:
# Create Period Closing Voucher for 2023
# This will create Account Closing Balance entries
closing_account = frappe.db.get_value(
"Account",
{
"company": company,
"root_type": "Liability",
"is_group": 0,
"account_type": ["not in", ["Payable", "Receivable"]],
},
"name",
)
fy_2023 = get_fiscal_year(posting_date_2023, company=company)
frappe.db.set_single_value("Accounts Settings", "use_legacy_controller_for_pcv", 1)
pcv = frappe.get_doc(
{
"doctype": "Period Closing Voucher",
"transaction_date": "2023-12-31",
"period_start_date": fy_2023[1],
"period_end_date": fy_2023[2],
"company": company,
"fiscal_year": fy_2023[0],
"cost_center": "_Test Cost Center - _TC",
"closing_account_head": closing_account,
"remarks": "Test Period Closing",
}
)
pcv.insert()
pcv.submit()
pcv.reload()
# Now create a small transaction in 2024 to ensure the account appears
jv_2024 = make_journal_entry(
account1=cash_account,
account2=sales_account,
amount=100,
posting_date="2024-01-15",
company=company,
submit=True,
)
# Set up filters for Q1 2024 (after the period closing)
filters = {
"company": company,
"from_fiscal_year": "2024",
"to_fiscal_year": "2024",
"period_start_date": "2024-01-01",
"period_end_date": "2024-03-31",
"filter_based_on": "Date Range",
"periodicity": "Monthly",
"ignore_closing_entries": True, # Don't include PCV entries in movements
}
periods = [
{"key": "2024_jan", "from_date": "2024-01-01", "to_date": "2024-01-31"},
{"key": "2024_feb", "from_date": "2024-02-01", "to_date": "2024-02-29"},
{"key": "2024_mar", "from_date": "2024-03-01", "to_date": "2024-03-31"},
]
query_builder = FinancialQueryBuilder(filters, periods)
accounts = [
frappe._dict({"name": cash_account, "account_name": "Cash", "account_number": "1001"}),
]
balances_data = query_builder.fetch_account_balances(accounts)
# Verify Cash account has opening balance from 2023 transactions
cash_data = balances_data.get(cash_account)
self.assertIsNotNone(cash_data, "Cash account should exist in results")
jan_cash = cash_data.get_period("2024_jan")
self.assertIsNotNone(jan_cash, "January period should exist")
# Opening balance should be from prior period
# Cash had 5000 debit in 2023, so opening in 2024 should be >= 5000
# (may be higher if there were other test transactions)
self.assertEqual(
jan_cash.opening,
5000.0,
"January opening should equal to balance from 2023 (5000)",
)
# Verify running balance logic
# Movement in January is 100 (from jv_2024)
self.assertEqual(jan_cash.movement, 100.0, "January movement should be 100")
self.assertEqual(
jan_cash.closing, jan_cash.opening + jan_cash.movement, "Closing = Opening + Movement"
)
# February and March should have no movement but carry the balance
feb_cash = cash_data.get_period("2024_feb")
self.assertEqual(feb_cash.opening, jan_cash.closing, "Feb opening = Jan closing")
self.assertEqual(feb_cash.movement, 0.0, "February should have no movement")
self.assertEqual(feb_cash.closing, feb_cash.opening, "Feb closing = opening when no movement")
mar_cash = cash_data.get_period("2024_mar")
self.assertEqual(mar_cash.opening, feb_cash.closing, "Mar opening = Feb closing")
self.assertEqual(mar_cash.movement, 0.0, "March should have no movement")
self.assertEqual(mar_cash.closing, mar_cash.opening, "Mar closing = opening when no movement")
# Set up filters for Q2 2024
filters_q2 = {
"company": company,
"from_fiscal_year": "2024",
"to_fiscal_year": "2024",
"period_start_date": "2024-04-01",
"period_end_date": "2024-06-30",
"filter_based_on": "Date Range",
"periodicity": "Monthly",
"ignore_closing_entries": True,
}
periods_q2 = [
{"key": "2024_apr", "from_date": "2024-04-01", "to_date": "2024-04-30"},
{"key": "2024_may", "from_date": "2024-05-01", "to_date": "2024-05-31"},
{"key": "2024_jun", "from_date": "2024-06-01", "to_date": "2024-06-30"},
]
query_builder_q2 = FinancialQueryBuilder(filters_q2, periods_q2)
balances_data_q2 = query_builder_q2.fetch_account_balances(accounts)
# Verify Cash account in Q2
cash_data_q2 = balances_data_q2.get(cash_account)
self.assertIsNotNone(cash_data_q2, "Cash account should exist in Q2 results")
apr_cash = cash_data_q2.get_period("2024_apr")
self.assertIsNotNone(apr_cash, "April period should exist")
# Opening balance in April should equal closing in March
self.assertEqual(
apr_cash.opening,
mar_cash.closing,
"April opening should equal March closing balance",
)
self.assertEqual(apr_cash.closing, apr_cash.opening, "April closing = opening when no movement")
finally:
# Clean up
frappe.db.set_single_value(
"Accounts Settings", "use_legacy_controller_for_pcv", original_pcv_setting or 0
)
if jv_2024:
jv_2024.cancel()
if pcv:
pcv.reload()
if pcv.docstatus == 1:
pcv.cancel()
jv_2023.cancel()
def test_account_with_gl_entries_but_no_prior_closing_balance(self):
company = "_Test Company"
cash_account = "_Test Cash - _TC"
bank_account = "_Test Bank - _TC"
# Create journal entries WITHOUT any prior Period Closing Voucher
# This ensures the account exists in gl_dict but NOT in balances_data
jv = make_journal_entry(
account1=cash_account,
account2=bank_account,
amount=2500,
posting_date="2024-07-15",
company=company,
submit=True,
)
try:
# Set up filters - use a period with no prior PCV
filters = {
"company": company,
"from_fiscal_year": "2024",
"to_fiscal_year": "2024",
"period_start_date": "2024-07-01",
"period_end_date": "2024-09-30",
"filter_based_on": "Date Range",
"periodicity": "Monthly",
}
periods = [
{"key": "2024_jul", "from_date": "2024-07-01", "to_date": "2024-07-31"},
{"key": "2024_aug", "from_date": "2024-08-01", "to_date": "2024-08-31"},
{"key": "2024_sep", "from_date": "2024-09-01", "to_date": "2024-09-30"},
]
query_builder = FinancialQueryBuilder(filters, periods)
# Use accounts that have GL entries but may not have Account Closing Balance
accounts = [
frappe._dict({"name": cash_account, "account_name": "Cash", "account_number": "1001"}),
frappe._dict({"name": bank_account, "account_name": "Bank", "account_number": "1002"}),
]
balances_data = query_builder.fetch_account_balances(accounts)
# Verify accounts are present in results even without prior closing balance
cash_data = balances_data.get(cash_account)
self.assertIsNotNone(cash_data, "Cash account should exist in results")
bank_data = balances_data.get(bank_account)
self.assertIsNotNone(bank_data, "Bank account should exist in results")
# Verify July has the movement from journal entry
jul_cash = cash_data.get_period("2024_jul")
self.assertIsNotNone(jul_cash, "July period should exist for cash")
self.assertEqual(jul_cash.movement, 2500.0, "July cash movement should be 2500")
jul_bank = bank_data.get_period("2024_jul")
self.assertIsNotNone(jul_bank, "July period should exist for bank")
self.assertEqual(jul_bank.movement, -2500.0, "July bank movement should be -2500")
# Verify subsequent periods exist with zero movement
aug_cash = cash_data.get_period("2024_aug")
self.assertIsNotNone(aug_cash, "August period should exist for cash")
self.assertEqual(aug_cash.movement, 0.0, "August cash movement should be 0")
self.assertEqual(aug_cash.opening, jul_cash.closing, "August opening = July closing")
sep_cash = cash_data.get_period("2024_sep")
self.assertIsNotNone(sep_cash, "September period should exist for cash")
self.assertEqual(sep_cash.movement, 0.0, "September cash movement should be 0")
self.assertEqual(sep_cash.opening, aug_cash.closing, "September opening = August closing")
finally:
jv.cancel()

View File

@@ -4,7 +4,7 @@
import frappe
from dateutil.relativedelta import relativedelta
from frappe import _
from frappe import _, cint
from frappe.model.document import Document
from frappe.utils import add_days, add_years, cstr, getdate
@@ -33,23 +33,11 @@ class FiscalYear(Document):
self.validate_dates()
self.validate_overlap()
if not self.is_new():
year_start_end_dates = frappe.db.sql(
"""select year_start_date, year_end_date
from `tabFiscal Year` where name=%s""",
(self.name),
)
def on_update(self):
frappe.cache().delete_key("fiscal_years")
if year_start_end_dates:
if (
getdate(self.year_start_date) != year_start_end_dates[0][0]
or getdate(self.year_end_date) != year_start_end_dates[0][1]
):
frappe.throw(
_(
"Cannot change Fiscal Year Start Date and Fiscal Year End Date once the Fiscal Year is saved."
)
)
def on_trash(self):
frappe.cache().delete_key("fiscal_years")
def validate_dates(self):
self.validate_from_to_dates("year_start_date", "year_end_date")
@@ -66,28 +54,20 @@ class FiscalYear(Document):
frappe.exceptions.InvalidDates,
)
def on_update(self):
check_duplicate_fiscal_year(self)
frappe.cache().delete_value("fiscal_years")
def on_trash(self):
frappe.cache().delete_value("fiscal_years")
def validate_overlap(self):
existing_fiscal_years = frappe.db.sql(
"""select name from `tabFiscal Year`
where (
(%(year_start_date)s between year_start_date and year_end_date)
or (%(year_end_date)s between year_start_date and year_end_date)
or (year_start_date between %(year_start_date)s and %(year_end_date)s)
or (year_end_date between %(year_start_date)s and %(year_end_date)s)
) and name!=%(name)s""",
{
"year_start_date": self.year_start_date,
"year_end_date": self.year_end_date,
"name": self.name or "No Name",
},
as_dict=True,
fy = frappe.qb.DocType("Fiscal Year")
name = self.name or self.year
existing_fiscal_years = (
frappe.qb.from_(fy)
.select(fy.name)
.where(
(fy.year_start_date <= self.year_end_date)
& (fy.year_end_date >= self.year_start_date)
& (fy.name != name)
)
.run(as_dict=True)
)
if existing_fiscal_years:
@@ -110,37 +90,30 @@ class FiscalYear(Document):
frappe.throw(
_(
"Year start date or end date is overlapping with {0}. To avoid please set company"
).format(existing.name),
).format(frappe.get_desk_link("Fiscal Year", existing.name, open_in_new_tab=True)),
frappe.NameError,
)
@frappe.whitelist()
def check_duplicate_fiscal_year(doc):
year_start_end_dates = frappe.db.sql(
"""select name, year_start_date, year_end_date from `tabFiscal Year` where name!=%s""",
(doc.name),
)
for fiscal_year, ysd, yed in year_start_end_dates:
if (getdate(doc.year_start_date) == ysd and getdate(doc.year_end_date) == yed) and (
not frappe.in_test
):
frappe.throw(
_(
"Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}"
).format(fiscal_year)
)
@frappe.whitelist()
def auto_create_fiscal_year():
for d in frappe.db.sql(
"""select name from `tabFiscal Year` where year_end_date = date_add(current_date, interval 3 day)"""
):
fy = frappe.qb.DocType("Fiscal Year")
# Skipped auto-creating Short Year, as it has very rare use case.
# Reference: https://www.irs.gov/businesses/small-businesses-self-employed/tax-years (US)
follow_up_date = add_days(getdate(), days=3)
fiscal_year = (
frappe.qb.from_(fy)
.select(fy.name)
.where((fy.year_end_date == follow_up_date) & (fy.is_short_year == 0))
.run()
)
for d in fiscal_year:
try:
current_fy = frappe.get_doc("Fiscal Year", d[0])
new_fy = frappe.copy_doc(current_fy, ignore_no_copy=False)
new_fy = frappe.new_doc("Fiscal Year")
new_fy.disabled = cint(current_fy.disabled)
new_fy.year_start_date = add_days(current_fy.year_end_date, 1)
new_fy.year_end_date = add_years(current_fy.year_end_date, 1)
@@ -148,6 +121,10 @@ def auto_create_fiscal_year():
start_year = cstr(new_fy.year_start_date.year)
end_year = cstr(new_fy.year_end_date.year)
new_fy.year = start_year if start_year == end_year else (start_year + "-" + end_year)
for row in current_fy.companies:
new_fy.append("companies", {"company": row.company})
new_fy.auto_created = 1
new_fy.insert(ignore_permissions=True)

View File

@@ -15,20 +15,22 @@
"ignore_user_permissions": 1,
"in_list_view": 1,
"label": "Company",
"options": "Company"
"options": "Company",
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:09:44.659251",
"modified": "2026-02-20 23:02:26.193606",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Fiscal Year Company",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -14,7 +14,7 @@ class FiscalYearCompany(Document):
if TYPE_CHECKING:
from frappe.types import DF
company: DF.Link | None
company: DF.Link
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data

View File

@@ -277,7 +277,21 @@ frappe.ui.form.on("Journal Entry", {
var update_jv_details = function (doc, r) {
$.each(r, function (i, d) {
var row = frappe.model.add_child(doc, "Journal Entry Account", "accounts");
frappe.model.set_value(row.doctype, row.name, "account", d.account);
const {
idx,
name,
owner,
parent,
parenttype,
parentfield,
creation,
modified,
modified_by,
doctype,
docstatus,
...fields
} = d;
frappe.model.set_value(row.doctype, row.name, fields);
});
refresh_field("accounts");
};
@@ -289,10 +303,6 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
}
onload_post_render() {
this.frm.get_field("accounts").grid.set_multiple_add("account");
}
load_defaults() {
//this.frm.show_print_first = true;
if (this.frm.doc.__islocal && this.frm.doc.company) {

View File

@@ -9,19 +9,16 @@
"engine": "InnoDB",
"field_order": [
"entry_type_and_date",
"is_system_generated",
"title",
"voucher_type",
"naming_series",
"process_deferred_accounting",
"reversal_of",
"column_break1",
"from_template",
"company",
"voucher_type",
"column_break1",
"naming_series",
"posting_date",
"finance_book",
"multi_currency",
"apply_tds",
"tax_withholding_category",
"is_system_generated",
"amended_from",
"section_break_tcvw",
"for_all_stock_asset_accounts",
"column_break_wpau",
@@ -30,52 +27,60 @@
"get_balance_for_periodic_accounting",
"2_add_edit_gl_entries",
"accounts",
"section_break99",
"cheque_no",
"cheque_date",
"user_remark",
"column_break99",
"section_break_ouaq",
"total_debit",
"column_break_cixu",
"total_credit",
"difference",
"get_balance",
"multi_currency",
"total_amount_currency",
"total_amount",
"total_amount_in_words",
"section_break99",
"cheque_no",
"cheque_date",
"clearance_date",
"column_break_oizh",
"user_remark",
"subscription_section",
"auto_repeat",
"tax_withholding_tab",
"section_tax_withholding_entry",
"tax_withholding_group",
"ignore_tax_withholding_threshold",
"override_tax_withholding_entries",
"tax_withholding_entries",
"more_info_tab",
"reference",
"clearance_date",
"remark",
"inter_company_journal_entry_reference",
"column_break98",
"bill_no",
"bill_date",
"due_date",
"column_break_isfa",
"inter_company_journal_entry_reference",
"process_deferred_accounting",
"reversal_of",
"payment_order",
"stock_entry",
"printing_settings",
"pay_to_recd_from",
"letter_head",
"select_print_heading",
"column_break_35",
"total_amount_currency",
"total_amount",
"total_amount_in_words",
"write_off",
"write_off_based_on",
"get_outstanding_invoices",
"column_break_30",
"write_off_amount",
"printing_settings",
"pay_to_recd_from",
"column_break_35",
"letter_head",
"select_print_heading",
"addtional_info",
"mode_of_payment",
"payment_order",
"party_not_required",
"column_break3",
"is_opening",
"stock_entry",
"subscription_section",
"auto_repeat",
"amended_from"
"finance_book",
"from_template",
"title",
"column_break3",
"remark",
"mode_of_payment",
"party_not_required"
],
"fields": [
{
@@ -155,6 +160,7 @@
{
"fieldname": "2_add_edit_gl_entries",
"fieldtype": "Section Break",
"hide_border": 1,
"oldfieldtype": "Section Break",
"options": "fa fa-table"
},
@@ -202,10 +208,6 @@
"oldfieldtype": "Small Text",
"print_hide": 1
},
{
"fieldname": "column_break99",
"fieldtype": "Column Break"
},
{
"fieldname": "total_debit",
"fieldtype": "Currency",
@@ -429,7 +431,7 @@
"collapsible": 1,
"fieldname": "addtional_info",
"fieldtype": "Section Break",
"label": "More Information",
"label": "Additional Info",
"oldfieldtype": "Section Break",
"options": "fa fa-file-text"
},
@@ -476,7 +478,7 @@
{
"fieldname": "subscription_section",
"fieldtype": "Section Break",
"label": "Subscription Section"
"label": "Subscription"
},
{
"allow_on_submit": 1,
@@ -593,12 +595,10 @@
"no_copy": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "eval: doc.apply_tds && doc.docstatus == 0",
"depends_on": "eval: doc.apply_tds",
"fieldname": "section_tax_withholding_entry",
"fieldtype": "Section Break",
"label": "Tax Withholding Entry"
"fieldtype": "Section Break"
},
{
"fieldname": "tax_withholding_group",
@@ -624,6 +624,33 @@
"label": "Tax Withholding Entries",
"options": "Tax Withholding Entry",
"read_only_depends_on": "eval: !doc.override_tax_withholding_entries"
},
{
"fieldname": "more_info_tab",
"fieldtype": "Tab Break",
"label": "More Info"
},
{
"fieldname": "section_break_ouaq",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_cixu",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_oizh",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_isfa",
"fieldtype": "Column Break"
},
{
"depends_on": "eval: doc.apply_tds",
"fieldname": "tax_withholding_tab",
"fieldtype": "Tab Break",
"label": "Tax Withholding"
}
],
"icon": "fa fa-file-text",
@@ -638,7 +665,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2025-11-13 17:54:14.542903",
"modified": "2026-02-16 16:06:10.468482",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -74,8 +74,8 @@ class JournalEntry(AccountsController):
mode_of_payment: DF.Link | None
multi_currency: DF.Check
naming_series: DF.Literal["ACC-JV-.YYYY.-"]
party_not_required: DF.Check
override_tax_withholding_entries: DF.Check
party_not_required: DF.Check
pay_to_recd_from: DF.Data | None
payment_order: DF.Link | None
periodic_entry_difference_account: DF.Link | None
@@ -179,11 +179,14 @@ class JournalEntry(AccountsController):
validate_docs_for_deferred_accounting([self.name], [])
def submit(self):
if len(self.accounts) > 100:
if len(self.accounts) > 100 and not self.meta.queue_in_background:
queue_submission(self, "_submit")
else:
return self._submit()
def before_cancel(self):
self.has_asset_adjustment_entry()
def cancel(self):
if len(self.accounts) > 100:
queue_submission(self, "_cancel")
@@ -554,12 +557,27 @@ class JournalEntry(AccountsController):
)
frappe.db.set_value("Journal Entry", self.name, "inter_company_journal_entry_reference", "")
def unlink_asset_adjustment_entry(self):
frappe.db.sql(
""" update `tabAsset Value Adjustment`
set journal_entry = null where journal_entry = %s""",
self.name,
def has_asset_adjustment_entry(self):
if self.flags.get("via_asset_value_adjustment"):
return
asset_value_adjustment = frappe.db.get_value(
"Asset Value Adjustment", {"docstatus": 1, "journal_entry": self.name}, "name"
)
if asset_value_adjustment:
frappe.throw(
_(
"Cannot cancel this document as it is linked with the submitted Asset Value Adjustment <b>{0}</b>. Please cancel the Asset Value Adjustment to continue."
).format(frappe.utils.get_link_to_form("Asset Value Adjustment", asset_value_adjustment))
)
def unlink_asset_adjustment_entry(self):
AssetValueAdjustment = frappe.qb.DocType("Asset Value Adjustment")
(
frappe.qb.update(AssetValueAdjustment)
.set(AssetValueAdjustment.journal_entry, None)
.where(AssetValueAdjustment.journal_entry == self.name)
).run()
def validate_party(self):
for d in self.get("accounts"):
@@ -1673,6 +1691,10 @@ def get_exchange_rate(
credit=None,
exchange_rate=None,
):
# Ensure exchange_rate is always numeric to avoid calculation errors
if isinstance(exchange_rate, str):
exchange_rate = flt(exchange_rate) or 1
account_details = frappe.get_cached_value(
"Account", account, ["account_type", "root_type", "account_currency", "company"], as_dict=1
)

View File

@@ -43,7 +43,7 @@
"fields": [
{
"bold": 1,
"columns": 2,
"columns": 4,
"fieldname": "account",
"fieldtype": "Link",
"in_global_search": 1,
@@ -185,20 +185,19 @@
"fieldtype": "Select",
"label": "Reference Type",
"no_copy": 1,
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry",
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry\nBank Transaction",
"search_index": 1
},
{
"fieldname": "reference_name",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
"label": "Reference Name",
"no_copy": 1,
"options": "reference_type",
"search_index": 1
},
{
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance', 'Bank Transaction'])",
"fieldname": "reference_due_date",
"fieldtype": "Date",
"label": "Reference Due Date",
@@ -294,7 +293,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2025-11-27 12:23:33.157655",
"modified": "2026-02-16 16:04:16.022407",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",

View File

@@ -55,6 +55,7 @@ class JournalEntryAccount(Document):
"Fees",
"Full and Final Statement",
"Payment Entry",
"Bank Transaction",
]
user_remark: DF.SmallText | None
# end: auto-generated types

View File

@@ -3,6 +3,7 @@
frappe.ui.form.on("Journal Entry Template", {
onload: function (frm) {
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
if (frm.is_new()) {
frappe.call({
type: "GET",
@@ -37,6 +38,31 @@ frappe.ui.form.on("Journal Entry Template", {
return { filters: filters };
});
frm.set_query("project", "accounts", function (doc, cdt, cdn) {
let row = frappe.get_doc(cdt, cdn);
let filters = {
company: doc.company,
};
if (row.party_type == "Customer") {
filters.customer = row.party;
}
return {
query: "erpnext.controllers.queries.get_project_name",
filters,
};
});
frm.set_query("party_type", "accounts", function (doc, cdt, cdn) {
const row = locals[cdt][cdn];
return {
query: "erpnext.setup.doctype.party_type.party_type.get_party_type",
filters: {
account: row.account,
},
};
});
},
voucher_type: function (frm) {
var add_accounts = function (doc, r) {

View File

@@ -3,6 +3,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
@@ -42,7 +43,29 @@ class JournalEntryTemplate(Document):
]
# end: auto-generated types
pass
def validate(self):
self.validate_party()
def validate_party(self):
"""
Loop over all accounts and see if party and party type is set correctly
"""
for account in self.accounts:
if account.party_type:
account_type = frappe.get_cached_value("Account", account.account, "account_type")
if account_type not in ["Receivable", "Payable"]:
frappe.throw(
_(
"Check row {0} for account {1}: Party Type is only allowed for Receivable or Payable accounts"
).format(account.idx, account.account)
)
if account.party and not account.party_type:
frappe.throw(
_("Check row {0} for account {1}: Party is only allowed if Party Type is set").format(
account.idx, account.account
)
)
@frappe.whitelist()

View File

@@ -5,7 +5,13 @@
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"account"
"account",
"party_type",
"party",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project"
],
"fields": [
{
@@ -15,18 +21,55 @@
"label": "Account",
"options": "Account",
"reqd": 1
},
{
"fieldname": "party_type",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Party Type",
"options": "DocType"
},
{
"fieldname": "party",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
"label": "Party",
"options": "party_type"
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions"
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
}
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:09:58.986448",
"modified": "2026-01-09 13:16:27.615083",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Template Account",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -16,9 +16,13 @@ class JournalEntryTemplateAccount(Document):
from frappe.types import DF
account: DF.Link
cost_center: DF.Link | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
party: DF.DynamicLink | None
party_type: DF.Link | None
project: DF.Link | None
# end: auto-generated types
pass

View File

@@ -400,6 +400,16 @@ frappe.ui.form.on("Payment Entry", {
);
frm.refresh_fields();
const party_currency =
frm.doc.payment_type === "Receive" ? "paid_from_account_currency" : "paid_to_account_currency";
var reference_grid = frm.fields_dict["references"].grid;
["total_amount", "outstanding_amount", "allocated_amount"].forEach((fieldname) => {
reference_grid.update_docfield_property(fieldname, "options", party_currency);
});
reference_grid.refresh();
},
show_general_ledger: function (frm) {
@@ -502,12 +512,16 @@ frappe.ui.form.on("Payment Entry", {
frm.set_value("contact_email", "");
frm.set_value("contact_person", "");
}
if (frm.doc.payment_type && frm.doc.party_type && frm.doc.party && frm.doc.company) {
if (!frm.doc.posting_date) {
frappe.msgprint(__("Please select Posting Date before selecting Party"));
frm.set_value("party", "");
return;
}
erpnext.utils.get_employee_contact_details(frm);
frm.set_party_account_based_on_party = true;
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
@@ -1104,7 +1118,7 @@ frappe.ui.form.on("Payment Entry", {
allocate_party_amount_against_ref_docs: async function (frm, paid_amount, paid_amount_change) {
await frm.call("allocate_amount_to_references", {
paid_amount: paid_amount,
paid_amount: flt(paid_amount),
paid_amount_change: paid_amount_change,
allocate_payment_amount: frappe.flags.allocate_payment_amount ?? false,
});
@@ -1440,16 +1454,15 @@ frappe.ui.form.on("Payment Entry", {
callback: function (r) {
if (!r.exc && r.message) {
// set taxes table
if (r.message) {
for (let tax of r.message) {
if (tax.charge_type === "On Net Total") {
tax.charge_type = "On Paid Amount";
}
frm.add_child("taxes", tax);
let taxes = r.message;
taxes.forEach((tax) => {
if (tax.charge_type === "On Net Total") {
tax.charge_type = "On Paid Amount";
}
frm.events.apply_taxes(frm);
frm.events.set_unallocated_amount(frm);
}
});
frm.set_value("taxes", taxes);
frm.events.apply_taxes(frm);
frm.events.set_unallocated_amount(frm);
}
},
});

View File

@@ -701,7 +701,6 @@
"fetch_from": "company.book_advance_payments_in_separate_party_account",
"fieldname": "book_advance_payments_in_separate_party_account",
"fieldtype": "Check",
"hidden": 1,
"label": "Book Advance Payments in Separate Party Account",
"no_copy": 1,
"read_only": 1
@@ -793,7 +792,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2025-12-18 13:56:40.206038",
"modified": "2026-02-03 16:08:49.800381",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -1065,8 +1065,12 @@ class PaymentEntry(AccountsController):
total_allocated_amount += flt(d.allocated_amount)
base_total_allocated_amount += self.calculate_base_allocated_amount_for_reference(d)
self.total_allocated_amount = abs(total_allocated_amount)
self.base_total_allocated_amount = abs(base_total_allocated_amount)
self.total_allocated_amount = flt(
abs(total_allocated_amount), self.precision("total_allocated_amount")
)
self.base_total_allocated_amount = flt(
abs(base_total_allocated_amount), self.precision("base_total_allocated_amount")
)
def set_unallocated_amount(self):
self.unallocated_amount = 0
@@ -1082,20 +1086,32 @@ class PaymentEntry(AccountsController):
self.base_paid_amount + deductions_to_consider
):
self.unallocated_amount = (
self.base_paid_amount
+ deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
) / self.source_exchange_rate
flt(
(
self.base_paid_amount
+ deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
),
self.precision("unallocated_amount"),
)
/ self.source_exchange_rate
)
elif self.payment_type == "Pay" and self.base_total_allocated_amount < (
self.base_received_amount - deductions_to_consider
):
self.unallocated_amount = (
self.base_received_amount
- deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
) / self.target_exchange_rate
flt(
(
self.base_received_amount
- deductions_to_consider
- self.base_total_allocated_amount
- included_taxes
),
self.precision("unallocated_amount"),
)
/ self.target_exchange_rate
)
def set_exchange_gain_loss(self):
exchange_gain_loss = flt(

View File

@@ -132,6 +132,12 @@
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"fieldname": "due_date",

View File

@@ -38,6 +38,7 @@ class PaymentLedgerEntry(Document):
amount_in_account_currency: DF.Currency
company: DF.Link | None
cost_center: DF.Link | None
project: DF.Link | None
delinked: DF.Check
due_date: DF.Date | None
finance_book: DF.Link | None

View File

@@ -746,7 +746,7 @@ class PaymentReconciliation(Document):
ple = qb.DocType("Payment Ledger Entry")
for x in self.dimensions:
dimension = x.fieldname
if self.get(dimension):
if self.get(dimension) and frappe.db.has_column("Payment Ledger Entry", dimension):
self.accounting_dimension_filter_conditions.append(ple[dimension] == self.get(dimension))
def build_qb_filter_conditions(self, get_invoices=False, get_return_invoices=False):

View File

@@ -0,0 +1,88 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2025-12-02 17:50:08.648006",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"payment_term",
"column_break_lnjp",
"payment_schedule",
"section_break_fjhh",
"description",
"section_break_mjlv",
"due_date",
"column_break_qghl",
"amount"
],
"fields": [
{
"fieldname": "payment_term",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Payment Term",
"options": "Payment Term"
},
{
"collapsible": 1,
"fieldname": "section_break_fjhh",
"fieldtype": "Section Break",
"label": "Description"
},
{
"fieldname": "description",
"fieldtype": "Small Text",
"in_list_view": 1,
"label": "Description"
},
{
"fieldname": "section_break_mjlv",
"fieldtype": "Section Break"
},
{
"fieldname": "due_date",
"fieldtype": "Date",
"in_list_view": 1,
"label": "Due Date"
},
{
"fieldname": "column_break_qghl",
"fieldtype": "Column Break"
},
{
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Amount",
"precision": "2"
},
{
"fieldname": "column_break_lnjp",
"fieldtype": "Column Break"
},
{
"allow_on_submit": 1,
"fieldname": "payment_schedule",
"fieldtype": "Link",
"label": "Payment Schedule",
"options": "Payment Schedule",
"read_only": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2026-01-19 02:21:36.455830",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reference",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"rows_threshold_for_grid_search": 20,
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,27 @@
# Copyright (c) 2025, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class PaymentReference(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
amount: DF.Currency
description: DF.SmallText | None
due_date: DF.Date | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
payment_schedule: DF.Link | None
payment_term: DF.Link | None
# end: auto-generated types
pass

View File

@@ -105,3 +105,29 @@ frappe.ui.form.on("Payment Request", "is_a_subscription", function (frm) {
});
}
});
frappe.ui.form.on("Payment Request", "calculate_total_amount_by_selected_rows", function (frm) {
if (frm.doc.docstatus !== 0) {
frappe.msgprint(__("Cannot fetch selected rows for submitted Payment Request"));
return;
}
const selected = frm.get_selected()?.payment_reference || [];
if (!selected.length) {
frappe.throw(__("No rows selected"));
}
let total = 0;
selected.forEach((name) => {
const row = frm.doc.payment_reference.find((d) => d.name === name);
if (row) {
row.manually_selected = 1;
total += row.amount;
}
});
frm.doc.payment_reference.forEach((row) => {
row.auto_selected = 0;
});
frm.set_value("grand_total", total);
frm.refresh_field("grand_total");
frm.save();
});

View File

@@ -19,6 +19,8 @@
"column_break_4",
"reference_doctype",
"reference_name",
"payment_reference_section",
"payment_reference",
"transaction_details",
"grand_total",
"currency",
@@ -157,6 +159,7 @@
"label": "Amount",
"non_negative": 1,
"options": "currency",
"read_only_depends_on": "eval:doc.payment_reference.length>0",
"reqd": 1
},
{
@@ -457,6 +460,17 @@
"fieldname": "phone_number",
"fieldtype": "Data",
"label": "Phone Number"
},
{
"fieldname": "payment_reference_section",
"fieldtype": "Section Break"
},
{
"fieldname": "payment_reference",
"fieldtype": "Table",
"label": "Payment Reference",
"options": "Payment Reference",
"read_only": 1
}
],
"grid_page_length": 50,
@@ -464,7 +478,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2025-08-29 11:52:48.555415",
"modified": "2026-01-13 12:53:00.963274",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",

View File

@@ -45,6 +45,7 @@ class PaymentRequest(Document):
if TYPE_CHECKING:
from frappe.types import DF
from erpnext.accounts.doctype.payment_reference.payment_reference import PaymentReference
from erpnext.accounts.doctype.subscription_plan_detail.subscription_plan_detail import (
SubscriptionPlanDetail,
)
@@ -78,6 +79,7 @@ class PaymentRequest(Document):
payment_gateway: DF.ReadOnly | None
payment_gateway_account: DF.Link | None
payment_order: DF.Link | None
payment_reference: DF.Table[PaymentReference]
payment_request_type: DF.Literal["Outward", "Inward"]
payment_url: DF.Data | None
phone_number: DF.Data | None
@@ -109,15 +111,36 @@ class PaymentRequest(Document):
if self.get("__islocal"):
self.status = "Draft"
self.validate_reference_document()
self.validate_against_payment_reference()
self.validate_payment_request_amount()
# self.validate_currency()
self.validate_subscription_details()
def validate_against_payment_reference(self):
if not self.payment_reference:
return
expected = sum(flt(r.amount) for r in self.payment_reference)
if flt(expected, self.precision("grand_total")) != flt(self.grand_total):
frappe.throw(_("Grand Total must match sum of Payment References"))
seen = set()
for r in self.payment_reference:
if not r.payment_schedule:
continue # legacy mode → skip
if r.payment_schedule in seen:
frappe.throw(_("Duplicate Payment Schedule selected"))
seen.add(r.payment_schedule)
def validate_reference_document(self):
if not self.reference_doctype or not self.reference_name:
frappe.throw(_("To create a Payment Request reference document is required"))
def validate_payment_request_amount(self):
if self.payment_reference:
return
if self.grand_total == 0:
frappe.throw(
_("{0} cannot be zero").format(self.get_label_from_fieldname("grand_total")),
@@ -535,7 +558,7 @@ class PaymentRequest(Document):
row_number += TO_SKIP_NEW_ROW
@frappe.whitelist(allow_guest=True)
@frappe.whitelist()
def make_payment_request(**args):
"""Make payment request"""
@@ -546,12 +569,69 @@ def make_payment_request(**args):
if args.dn and not isinstance(args.dn, str):
frappe.throw(_("Invalid parameter. 'dn' should be of type str"))
frappe.has_permission("Payment Request", "create", throw=True)
frappe.has_permission(args.dt, "read", args.dn, throw=True)
ref_doc = args.ref_doc or frappe.get_doc(args.dt, args.dn)
if not args.get("company"):
args.company = ref_doc.company
gateway_account = get_gateway_details(args) or frappe._dict()
grand_total = get_amount(ref_doc, gateway_account.get("payment_account"))
# Schedule-based PRs are allowed only if no Payment Entry exists for this document.
# Any existing Payment Entry forces legacy (amount-based) flow.
selected_payment_schedules = json.loads(args.get("schedules")) if args.get("schedules") else []
# Backend guard:
# If any Payment Entry exists, schedule-based PRs are not allowed.
if selected_payment_schedules and get_existing_payment_entry(ref_doc.name):
frappe.throw(
_(
"Payment Schedule based Payment Requests cannot be created because a Payment Entry already exists for this document."
)
)
has_payment_entry = bool(get_existing_payment_entry(ref_doc.name))
payment_reference = []
if selected_payment_schedules:
existing_payment_references = get_existing_payment_references(ref_doc.name)
if existing_payment_references:
existing_ids = {r["payment_schedule"] for r in existing_payment_references}
selected_ids = {r["name"] for r in selected_payment_schedules}
duplicate_ids = existing_ids & selected_ids
if duplicate_ids:
duplicate_schedules = []
for row in selected_payment_schedules:
if row["name"] in duplicate_ids:
existing_ref = next(
(r for r in existing_payment_references if r["payment_schedule"] == row["name"]),
{},
)
existing_pr = existing_ref.get("parent")
duplicate_schedules.append(
f"Payment Term: {row.get('payment_term')}, "
f"Due Date: {row.get('due_date')}, "
f"Amount: {row.get('payment_amount')} "
f"(already requested in PR {existing_pr})"
)
frappe.throw(
_("The following payment schedule(s) already exist:\n{0}").format(
"\n".join(duplicate_schedules)
)
)
payment_reference = set_payment_references(args.get("schedules"))
# Determine grand_total
if selected_payment_schedules and not has_payment_entry:
grand_total = sum(row.get("payment_amount") for row in selected_payment_schedules)
else:
grand_total = get_amount(ref_doc, gateway_account.get("payment_account"))
if not grand_total:
frappe.throw(_("Payment Entry is already created"))
@@ -561,7 +641,6 @@ def make_payment_request(**args):
loyalty_amount = validate_loyalty_points(ref_doc, int(args.loyalty_points)) # sets fields on ref_doc
ref_doc.db_update()
grand_total = grand_total - loyalty_amount
# fetches existing payment request `grand_total` amount
existing_payment_request_amount = get_existing_payment_request_amount(ref_doc)
@@ -581,19 +660,20 @@ def make_payment_request(**args):
else:
# If PR's are processed, cancel all of them.
cancel_old_payment_requests(ref_doc.doctype, ref_doc.name)
else:
elif not selected_payment_schedules:
grand_total = validate_and_calculate_grand_total(grand_total, existing_payment_request_amount)
draft_payment_request = frappe.db.get_value(
"Payment Request",
{"reference_doctype": ref_doc.doctype, "reference_name": ref_doc.name, "docstatus": 0},
)
if draft_payment_request:
frappe.db.set_value(
"Payment Request", draft_payment_request, "grand_total", grand_total, update_modified=False
)
pr = frappe.get_doc("Payment Request", draft_payment_request)
if selected_payment_schedules:
apply_payment_references(pr, payment_reference)
pr.save()
else:
bank_account = (
get_party_bank_account(args.get("party_type"), args.get("party"))
@@ -648,7 +728,10 @@ def make_payment_request(**args):
}
)
# Update dimensions
if selected_payment_schedules:
apply_payment_references(pr, payment_reference)
# Dimensions
pr.update(
{
"cost_center": ref_doc.get("cost_center"),
@@ -677,6 +760,51 @@ def make_payment_request(**args):
return pr.as_dict()
def apply_payment_references(pr, payment_reference):
existing_refs = pr.get("payment_reference") or []
existing_ids = {r.get("payment_schedule") for r in existing_refs if r.get("payment_schedule")}
new_refs = [r for r in (payment_reference or []) if r.get("payment_schedule") not in existing_ids]
pr.set("payment_reference", existing_refs + new_refs)
pr.set("grand_total", sum(flt(r.get("amount")) for r in pr.get("payment_reference")))
def set_payment_references(payment_schedules):
payment_schedules = json.loads(payment_schedules) if payment_schedules else []
payment_reference = []
for row in payment_schedules:
payment_reference.append(
{
"payment_term": row.get("payment_term"),
"payment_schedule": row.get("name"),
"description": row.get("description"),
"due_date": row.get("due_date"),
"amount": row.get("payment_amount"),
}
)
return payment_reference
def get_existing_payment_entry(ref_docname):
pe = frappe.qb.DocType("Payment Entry")
per = frappe.qb.DocType("Payment Entry Reference")
existing_pe = (
frappe.qb.from_(pe)
.join(per)
.on(per.parent == pe.name)
.select(pe.name)
.where(pe.docstatus < 2)
.where(per.reference_name == ref_docname)
.limit(1)
.run()
)
return existing_pe
def get_amount(ref_doc, payment_account=None):
"""get amount based on doctype"""
grand_total = 0
@@ -819,7 +947,7 @@ def get_print_format_list(ref_doctype):
return {"print_format": print_format_list}
@frappe.whitelist(allow_guest=True)
@frappe.whitelist()
def resend_payment_email(docname):
return frappe.get_doc("Payment Request", docname).send_email()
@@ -1021,3 +1149,44 @@ def get_irequests_of_payment_request(doc: str | None = None) -> list:
},
)
return res
@frappe.whitelist()
def get_available_payment_schedules(reference_doctype, reference_name):
ref_doc = frappe.get_doc(reference_doctype, reference_name)
if not hasattr(ref_doc, "payment_schedule") or not ref_doc.payment_schedule:
return []
if get_existing_payment_entry(reference_name):
return []
existing_refs = get_existing_payment_references(reference_name)
existing_ids = {r["payment_schedule"] for r in existing_refs if r.get("payment_schedule")}
return [r for r in ref_doc.payment_schedule if r.name not in existing_ids]
def get_existing_payment_references(reference_name):
PR = frappe.qb.DocType("Payment Request")
PRF = frappe.qb.DocType("Payment Reference")
result = (
frappe.qb.from_(PR)
.join(PRF)
.on(PR.name == PRF.parent)
.select(
PRF.payment_term,
PRF.due_date,
PRF.amount.as_("payment_amount"),
PRF.payment_schedule,
PRF.parent,
)
.where(PR.reference_name == reference_name)
.where(PR.docstatus < 2)
.where(
PR.status.isin(["Draft", "Requested", "Initiated", "Partially Paid", "Payment Ordered", "Paid"])
)
).run(as_dict=True)
return result

View File

@@ -1,12 +1,14 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import json
import re
import unittest
from unittest.mock import patch
import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import add_days, nowdate
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_terms_template
@@ -851,3 +853,130 @@ class TestPaymentRequest(IntegrationTestCase):
pr.load_from_db()
self.assertEqual(pr.grand_total, pi.outstanding_amount)
def test_payment_request_grand_total_from_selected_schedules(self):
po = create_purchase_order(do_not_save=1, currency="INR", qty=1, rate=100)
po.payment_schedule = []
po.append("payment_schedule", {"due_date": nowdate(), "payment_amount": 30})
po.append("payment_schedule", {"due_date": add_days(nowdate(), 1), "payment_amount": 30})
po.append("payment_schedule", {"due_date": add_days(nowdate(), 2), "payment_amount": 40})
po.save()
po.submit()
schedules = json.dumps(
[
{
"payment_term": row.payment_term,
"name": row.name,
"due_date": row.due_date,
"payment_amount": row.payment_amount,
"description": row.description,
}
for row in [po.payment_schedule[0], po.payment_schedule[2]]
]
)
pr = make_payment_request(
dt="Purchase Order",
dn=po.name,
mute_email=1,
submit_doc=False,
return_doc=True,
schedules=schedules,
)
pr.submit()
self.assertEqual(pr.grand_total, 70)
self.assertEqual(len(pr.payment_reference), 2)
def test_draft_pr_reuse_merges_payment_references(self):
from frappe.utils import add_days, nowdate
po = create_purchase_order(do_not_save=1, currency="INR", qty=1, rate=100)
po.payment_schedule = []
po.append("payment_schedule", {"due_date": nowdate(), "payment_amount": 50})
po.append("payment_schedule", {"due_date": add_days(nowdate(), 1), "payment_amount": 50})
po.save()
po.submit()
schedules = json.dumps(
[
{
"payment_term": row.payment_term,
"name": row.name,
"due_date": row.due_date,
"payment_amount": row.payment_amount,
"description": row.description,
}
for row in [po.payment_schedule[0]]
]
)
pr = make_payment_request(
dt="Purchase Order",
dn=po.name,
mute_email=1,
submit_doc=False,
return_doc=True,
schedules=schedules,
)
pr.save()
schedules = json.dumps(
[
{
"payment_term": row.payment_term,
"name": row.name,
"due_date": row.due_date,
"payment_amount": row.payment_amount,
"description": row.description,
}
for row in [po.payment_schedule[1]]
]
)
# call make_payment_request again → reuse draft
pr_reused = make_payment_request(
dt="Purchase Order",
dn=po.name,
mute_email=1,
submit_doc=False,
return_doc=True,
schedules=schedules,
)
self.assertEqual(pr.name, pr_reused.name)
self.assertEqual(pr_reused.grand_total, 100)
self.assertEqual(len(pr_reused.payment_reference), 2)
def test_schedule_pr_not_allowed_if_payment_entry_exists(self):
po = create_purchase_order(do_not_save=1, currency="INR", qty=1, rate=100)
po.payment_schedule = []
row = po.append("payment_schedule", {"due_date": nowdate(), "payment_amount": 100})
po.save()
po.submit()
# create PE first
pr = make_payment_request(dt="Purchase Order", dn=po.name, mute_email=1, submit_doc=1, return_doc=1)
pr.create_payment_entry()
schedules = json.dumps(
[
{
"name": row.name,
"payment_term": row.payment_term,
"due_date": row.due_date,
"payment_amount": row.payment_amount,
"description": row.description,
}
]
)
with self.assertRaises(frappe.ValidationError):
make_payment_request(
dt="Purchase Order",
dn=po.name,
mute_email=1,
submit_doc=False,
return_doc=True,
schedules=schedules,
)

View File

@@ -4,19 +4,6 @@
frappe.ui.form.on("POS Closing Entry", {
onload: async function (frm) {
frm.ignore_doctypes_on_cancel_all = ["POS Invoice Merge Log", "Sales Invoice"];
frm.set_query("pos_profile", function (doc) {
return {
filters: { user: doc.user },
};
});
frm.set_query("user", function (doc) {
return {
query: "erpnext.accounts.doctype.pos_closing_entry.pos_closing_entry.get_cashiers",
filters: { parent: doc.pos_profile },
};
});
frm.set_query("pos_opening_entry", function (doc) {
return { filters: { status: "Open", docstatus: 1 } };
});

View File

@@ -159,15 +159,16 @@
"language",
"column_break_84",
"select_print_heading",
"utm_analytics_section",
"utm_source",
"utm_medium",
"column_break_bhao",
"utm_campaign",
"more_information",
"inter_company_invoice_reference",
"customer_group",
"is_discounted",
"col_break23",
"utm_source",
"utm_campaign",
"utm_medium",
"column_break_gpiw",
"status",
"more_info",
"debit_to",
@@ -1541,10 +1542,6 @@
"fieldtype": "Check",
"label": "Update Billed Amount in Delivery Note"
},
{
"fieldname": "column_break_gpiw",
"fieldtype": "Column Break"
},
{
"fieldname": "utm_medium",
"fieldtype": "Link",
@@ -1610,13 +1607,24 @@
"hidden": 1,
"label": "Item Wise Tax Details",
"no_copy": 1,
"options": "Item Wise Tax Detail"
"options": "Item Wise Tax Detail",
"print_hide": 1
},
{
"collapsible": 1,
"fieldname": "utm_analytics_section",
"fieldtype": "Section Break",
"label": "UTM Analytics"
},
{
"fieldname": "column_break_bhao",
"fieldtype": "Column Break"
}
],
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2025-08-04 22:22:31.471752",
"modified": "2026-02-10 14:23:07.181782",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -898,6 +898,53 @@ class TestPOSInvoice(IntegrationTestCase):
if batch.batch_no == batch_no and batch.warehouse == "_Test Warehouse - _TC":
self.assertEqual(batch.qty, 5)
def test_pos_batch_reservation_with_return_qty(self):
"""
Test POS Invoice reserved qty for batch without bundle with return invoices.
"""
from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
get_auto_batch_nos,
)
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
create_batch_item_with_batch,
)
create_batch_item_with_batch("_Batch Item Reserve Return", "TestBatch-RR 01")
se = make_stock_entry(
target="_Test Warehouse - _TC",
item_code="_Batch Item Reserve Return",
qty=30,
basic_rate=100,
)
se.reload()
batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
# POS Invoice for the batch without bundle
pos_inv = create_pos_invoice(item="_Batch Item Reserve Return", rate=300, qty=15, do_not_save=1)
pos_inv.append(
"payments",
{"mode_of_payment": "Cash", "amount": 4500},
)
pos_inv.items[0].batch_no = batch_no
pos_inv.save()
pos_inv.submit()
# POS Invoice return
pos_return = make_sales_return(pos_inv.name)
pos_return.insert()
pos_return.submit()
batches = get_auto_batch_nos(
frappe._dict({"item_code": "_Batch Item Reserve Return", "warehouse": "_Test Warehouse - _TC"})
)
for batch in batches:
if batch.batch_no == batch_no and batch.warehouse == "_Test Warehouse - _TC":
self.assertEqual(batch.qty, 30)
def test_pos_batch_item_qty_validation(self):
from erpnext.stock.doctype.serial_and_batch_bundle.serial_and_batch_bundle import (
BatchNegativeStockError,

View File

@@ -12,9 +12,6 @@
"disabled",
"column_break_9",
"warehouse",
"utm_source",
"utm_campaign",
"utm_medium",
"company_address",
"section_break_15",
"applicable_for_users",
@@ -61,7 +58,13 @@
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project"
"project",
"utm_analytics_section",
"utm_source",
"column_break_tvls",
"utm_campaign",
"column_break_xygw",
"utm_medium"
],
"fields": [
{
@@ -430,6 +433,20 @@
"fieldname": "allow_partial_payment",
"fieldtype": "Check",
"label": "Allow Partial Payment"
},
{
"fieldname": "column_break_tvls",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_xygw",
"fieldtype": "Column Break"
},
{
"collapsible": 1,
"fieldname": "utm_analytics_section",
"fieldtype": "Section Break",
"label": "Campaign"
}
],
"grid_page_length": 50,
@@ -458,7 +475,7 @@
"link_fieldname": "pos_profile"
}
],
"modified": "2025-06-24 11:19:19.834905",
"modified": "2026-02-10 14:24:48.597412",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -99,8 +99,7 @@ def get_customers_list(pos_profile=None):
return (
frappe.db.sql(
f""" select name, customer_name, customer_group,
territory, customer_pos_id from tabCustomer where disabled = 0
f""" select name, customer_name, customer_group, territory from tabCustomer where disabled = 0
and {cond}""",
tuple(customer_groups),
as_dict=1,

View File

@@ -121,7 +121,7 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Apply On",
"options": "\nItem Code\nItem Group\nBrand\nTransaction",
"options": "Item Code\nItem Group\nBrand\nTransaction",
"reqd": 1
},
{
@@ -657,7 +657,7 @@
"icon": "fa fa-gift",
"idx": 1,
"links": [],
"modified": "2025-08-20 11:40:07.096854",
"modified": "2026-02-17 12:24:07.553505",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",
@@ -714,9 +714,10 @@
"write": 1
}
],
"row_format": "Dynamic",
"show_name_in_global_search": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "title"
}
}

View File

@@ -45,7 +45,7 @@ class PricingRule(Document):
apply_discount_on: DF.Literal["Grand Total", "Net Total"]
apply_discount_on_rate: DF.Check
apply_multiple_pricing_rules: DF.Check
apply_on: DF.Literal["", "Item Code", "Item Group", "Brand", "Transaction"]
apply_on: DF.Literal["Item Code", "Item Group", "Brand", "Transaction"]
apply_recursion_over: DF.Float
apply_rule_on_other: DF.Literal["", "Item Code", "Item Group", "Brand"]
brands: DF.Table[PricingRuleBrand]
@@ -346,8 +346,7 @@ def apply_pricing_rule(args, doc=None):
args = frappe._dict(args)
if not args.transaction_type:
set_transaction_type(args)
set_transaction_type(args)
# list of dictionaries
out = []
@@ -683,23 +682,23 @@ def remove_pricing_rules(item_list):
return out
def set_transaction_type(args):
if args.transaction_type:
def set_transaction_type(pricing_ctx: frappe._dict) -> None:
if pricing_ctx.transaction_type in ["buying", "selling"]:
return
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
args.transaction_type = "selling"
elif args.doctype in (
if pricing_ctx.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
pricing_ctx.transaction_type = "selling"
elif pricing_ctx.doctype in (
"Material Request",
"Supplier Quotation",
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
):
args.transaction_type = "buying"
elif args.customer:
args.transaction_type = "selling"
pricing_ctx.transaction_type = "buying"
elif pricing_ctx.customer:
pricing_ctx.transaction_type = "selling"
else:
args.transaction_type = "buying"
pricing_ctx.transaction_type = "buying"
@frappe.whitelist()

View File

@@ -10,7 +10,7 @@
],
"fields": [
{
"depends_on": "eval:parent.apply_on == 'Item Code'",
"depends_on": "eval:parent.apply_on == 'Brand'",
"fieldname": "brand",
"fieldtype": "Link",
"in_list_view": 1,
@@ -28,14 +28,15 @@
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:17.857046",
"modified": "2026-02-17 12:17:13.073587",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule Brand",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -10,7 +10,7 @@
],
"fields": [
{
"depends_on": "eval:parent.apply_on == 'Item Code'",
"depends_on": "eval:parent.apply_on == 'Item Group'",
"fieldname": "item_group",
"fieldtype": "Link",
"in_list_view": 1,
@@ -28,14 +28,15 @@
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:18.221095",
"modified": "2026-02-17 12:16:57.778471",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule Item Group",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -415,8 +415,9 @@ def reconcile(doc: None | str = None) -> None:
for x in allocations:
pr.append("allocation", x)
skip_ref_details_update_for_pe = check_multi_currency(pr)
# reconcile
pr.reconcile_allocations(skip_ref_details_update_for_pe=True)
pr.reconcile_allocations(skip_ref_details_update_for_pe=skip_ref_details_update_for_pe)
# If Payment Entry, update details only for newly linked references
# This is for performance
@@ -504,6 +505,37 @@ def reconcile(doc: None | str = None) -> None:
frappe.db.set_value("Process Payment Reconciliation", doc, "status", "Completed")
def check_multi_currency(pr_doc):
GL = frappe.qb.DocType("GL Entry")
Account = frappe.qb.DocType("Account")
def get_account_currency(voucher_type, voucher_no):
currency = (
frappe.qb.from_(GL)
.join(Account)
.on(GL.account == Account.name)
.select(Account.account_currency)
.where(
(GL.voucher_type == voucher_type)
& (GL.voucher_no == voucher_no)
& (Account.account_type.isin(["Payable", "Receivable"]))
)
.limit(1)
).run(as_dict=True)
return currency[0].account_currency if currency else None
for allocation in pr_doc.allocation:
reference_currency = get_account_currency(allocation.reference_type, allocation.reference_name)
invoice_currency = get_account_currency(allocation.invoice_type, allocation.invoice_number)
if reference_currency != invoice_currency:
return True
return False
@frappe.whitelist()
def is_any_doc_running(for_filter: str | dict | None = None) -> str | None:
running_doc = None

View File

@@ -18,8 +18,19 @@ class TestProcessStatementOfAccounts(AccountsTestMixin, IntegrationTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
letterhead = frappe.get_doc("Letter Head", "Company Letterhead - Grey")
letterhead.is_default = 0
letterhead.save()
cls.enterClassContext(cls.change_settings("Selling Settings", validate_selling_price=0))
@classmethod
def tearDownClass(cls):
super().tearDownClass()
letterhead = frappe.get_doc("Letter Head", "Company Letterhead - Grey")
letterhead.is_default = 1
letterhead.save()
frappe.db.commit() # nosemgrep
def setUp(self):
self.create_company()
self.create_customer()

View File

@@ -134,7 +134,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
this.frm.add_custom_button(
__("Payment Request"),
function () {
me.make_payment_request();
me.make_payment_request_with_schedule();
},
__("Create")
);

View File

@@ -85,20 +85,24 @@
"taxes_and_charges_added",
"taxes_and_charges_deducted",
"total_taxes_and_charges",
"section_break_49",
"totals_section",
"use_company_roundoff_cost_center",
"grand_total",
"in_words",
"column_break8",
"disable_rounded_total",
"rounding_adjustment",
"rounded_total",
"base_totals_section",
"base_grand_total",
"base_in_words",
"column_break_hcca",
"base_rounding_adjustment",
"base_rounded_total",
"base_in_words",
"column_break8",
"grand_total",
"rounding_adjustment",
"use_company_roundoff_cost_center",
"rounded_total",
"in_words",
"section_break_ttrv",
"total_advance",
"column_break_peap",
"outstanding_amount",
"disable_rounded_total",
"section_tax_withholding_entry",
"tax_withholding_group",
"ignore_tax_withholding_threshold",
@@ -606,6 +610,7 @@
},
{
"default": "0",
"depends_on": "eval:doc.items.every((item) => !item.pr_detail)",
"fieldname": "update_stock",
"fieldtype": "Check",
"label": "Update Stock",
@@ -882,15 +887,10 @@
"options": "currency",
"print_hide": 1
},
{
"fieldname": "section_break_49",
"fieldtype": "Section Break",
"label": "Totals"
},
{
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"label": "Grand Total (Company Currency)",
"label": "Grand Total",
"oldfieldname": "grand_total",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
@@ -901,7 +901,7 @@
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "base_rounding_adjustment",
"fieldtype": "Currency",
"label": "Rounding Adjustment (Company Currency)",
"label": "Rounding Adjustment",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
@@ -911,7 +911,7 @@
"depends_on": "eval:!doc.disable_rounded_total",
"fieldname": "base_rounded_total",
"fieldtype": "Currency",
"label": "Rounded Total (Company Currency)",
"label": "Rounded Total",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
@@ -920,7 +920,7 @@
{
"fieldname": "base_in_words",
"fieldtype": "Data",
"label": "In Words (Company Currency)",
"label": "In Words",
"length": 240,
"oldfieldname": "in_words",
"oldfieldtype": "Data",
@@ -1660,6 +1660,28 @@
"fieldname": "override_tax_withholding_entries",
"fieldtype": "Check",
"label": "Edit Tax Withholding Entries"
},
{
"fieldname": "column_break_hcca",
"fieldtype": "Column Break"
},
{
"fieldname": "section_break_ttrv",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_peap",
"fieldtype": "Column Break"
},
{
"fieldname": "base_totals_section",
"fieldtype": "Section Break",
"label": "Totals (Company Currency)"
},
{
"fieldname": "totals_section",
"fieldtype": "Section Break",
"label": "Totals"
}
],
"grid_page_length": 50,
@@ -1667,7 +1689,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2025-12-15 06:41:38.237728",
"modified": "2026-02-23 14:23:57.269770",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -36,7 +36,7 @@ from erpnext.accounts.utils import get_account_currency, get_fiscal_year, update
from erpnext.assets.doctype.asset.asset import is_cwip_accounting_enabled
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.controllers.accounts_controller import validate_account_head
from erpnext.controllers.accounts_controller import merge_taxes, validate_account_head
from erpnext.controllers.buying_controller import BuyingController
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
update_billed_amount_based_on_po,
@@ -1745,10 +1745,6 @@ class PurchaseInvoice(BuyingController):
project_doc.db_update()
def validate_supplier_invoice(self):
if self.bill_date:
if getdate(self.bill_date) > getdate(self.posting_date):
frappe.throw(_("Supplier Invoice Date cannot be greater than Posting Date"))
if self.bill_no:
if cint(frappe.get_single_value("Accounts Settings", "check_supplier_invoice_uniqueness")):
fiscal_year = get_fiscal_year(self.posting_date, company=self.company, as_dict=True)
@@ -2005,9 +2001,17 @@ def make_purchase_receipt(source_name, target_doc=None, args=None):
args = json.loads(args)
def post_parent_process(source_parent, target_parent):
for row in target_parent.get("items"):
if row.get("qty") == 0:
target_parent.remove(row)
remove_items_with_zero_qty(target_parent)
set_missing_values(source_parent, target_parent)
def remove_items_with_zero_qty(target_parent):
target_parent.items = [row for row in target_parent.get("items") if row.get("qty") != 0]
def set_missing_values(source_parent, target_parent):
target_parent.run_method("set_missing_values")
if args and args.get("merge_taxes"):
merge_taxes(source_parent, target_parent)
target_parent.run_method("calculate_taxes_and_totals")
def update_item(obj, target, source_parent):
from erpnext.controllers.sales_and_purchase_return import get_returned_qty_map_for_row
@@ -2059,7 +2063,11 @@ def make_purchase_receipt(source_name, target_doc=None, args=None):
"postprocess": update_item,
"condition": lambda doc: abs(doc.received_qty) < abs(doc.qty) and select_item(doc),
},
"Purchase Taxes and Charges": {"doctype": "Purchase Taxes and Charges"},
"Purchase Taxes and Charges": {
"doctype": "Purchase Taxes and Charges",
"reset_value": not (args and args.get("merge_taxes")),
"ignore": args.get("merge_taxes") if args else 0,
},
},
target_doc,
post_parent_process,

View File

@@ -52,6 +52,7 @@
"stock_uom_rate",
"is_free_item",
"apply_tds",
"allow_zero_valuation_rate",
"section_break_22",
"net_rate",
"net_amount",
@@ -97,7 +98,6 @@
"service_start_date",
"service_end_date",
"reference",
"allow_zero_valuation_rate",
"item_tax_rate",
"bom",
"include_exploded_items",
@@ -420,6 +420,7 @@
"options": "UOM"
},
{
"depends_on": "eval:parent.update_stock",
"fieldname": "warehouse_section",
"fieldtype": "Section Break",
"label": "Warehouse"
@@ -447,7 +448,6 @@
"print_hide": 1
},
{
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "batch_no",
"fieldtype": "Link",
"label": "Batch No",
@@ -459,14 +459,12 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "serial_no",
"fieldtype": "Text",
"label": "Serial No",
"no_copy": 1
},
{
"depends_on": "eval:!doc.is_fixed_asset && doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "rejected_serial_no",
"fieldtype": "Text",
"label": "Rejected Serial No",
@@ -577,6 +575,7 @@
},
{
"default": "0",
"depends_on": "eval:parent.update_stock",
"fieldname": "allow_zero_valuation_rate",
"fieldtype": "Check",
"label": "Allow Zero Valuation Rate",
@@ -800,7 +799,7 @@
"read_only": 1
},
{
"depends_on": "eval:parent.is_internal_supplier && parent.update_stock",
"depends_on": "eval:parent.is_internal_supplier",
"fieldname": "from_warehouse",
"fieldtype": "Link",
"ignore_user_permissions": 1,
@@ -896,7 +895,7 @@
"label": "Consider for Tax Withholding"
},
{
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
@@ -906,7 +905,7 @@
"search_index": 1
},
{
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
"fieldname": "rejected_serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Rejected Serial and Batch Bundle",
@@ -922,7 +921,7 @@
"options": "Asset"
},
{
"depends_on": "eval:parent.update_stock === 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"depends_on": "eval:doc.use_serial_batch_fields === 0 && doc.docstatus === 0",
"fieldname": "add_serial_batch_bundle",
"fieldtype": "Button",
"label": "Add Serial / Batch No"
@@ -992,7 +991,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2025-12-13 14:10:02.379392",
"modified": "2026-02-15 21:07:49.455930",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -44,6 +44,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
"Unreconcile Payment Entries",
"Serial and Batch Bundle",
"Bank Transaction",
"Packing Slip",
];
if (!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
@@ -115,18 +116,21 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
}
if (cint(doc.update_stock) != 1) {
// show Make Delivery Note button only if Sales Invoice is not created from Delivery Note
var from_delivery_note = false;
from_delivery_note = this.frm.doc.items.some(function (item) {
return item.delivery_note ? true : false;
});
if (!from_delivery_note && !is_delivered_by_supplier) {
this.frm.add_custom_button(
__("Delivery"),
this.frm.cscript["Make Delivery Note"],
__("Create")
if (!is_delivered_by_supplier) {
const should_create_delivery_note = doc.items.some(
(item) =>
item.qty - item.delivered_qty > 0 &&
!item.scio_detail &&
!item.dn_detail &&
!item.delivered_by_supplier
);
if (should_create_delivery_note) {
this.frm.add_custom_button(
__("Delivery Note"),
this.frm.cscript["Make Delivery Note"],
__("Create")
);
}
}
}
@@ -134,7 +138,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends (
this.frm.add_custom_button(
__("Payment Request"),
function () {
me.make_payment_request();
me.make_payment_request_with_schedule();
},
__("Create")
);

View File

@@ -7,12 +7,12 @@
"engine": "InnoDB",
"field_order": [
"customer_section",
"company",
"company_tax_id",
"naming_series",
"customer",
"customer_name",
"tax_id",
"company",
"company_tax_id",
"column_break1",
"posting_date",
"posting_time",
@@ -77,34 +77,38 @@
"base_total_taxes_and_charges",
"column_break_47",
"total_taxes_and_charges",
"totals",
"totals_section",
"use_company_roundoff_cost_center",
"grand_total",
"in_words",
"column_break5",
"disable_rounded_total",
"rounding_adjustment",
"rounded_total",
"base_totals_section",
"base_grand_total",
"base_in_words",
"column_break_xjag",
"base_rounding_adjustment",
"base_rounded_total",
"base_in_words",
"column_break5",
"grand_total",
"rounding_adjustment",
"use_company_roundoff_cost_center",
"rounded_total",
"in_words",
"section_break_vacb",
"total_advance",
"column_break_rdks",
"outstanding_amount",
"disable_rounded_total",
"section_tax_withholding_entry",
"tax_withholding_group",
"ignore_tax_withholding_threshold",
"override_tax_withholding_entries",
"tax_withholding_entries",
"section_break_49",
"additional_discount_section",
"apply_discount_on",
"base_discount_amount",
"coupon_code",
"is_cash_or_non_trade_discount",
"additional_discount_account",
"column_break_51",
"additional_discount_percentage",
"discount_amount",
"is_cash_or_non_trade_discount",
"additional_discount_account",
"sec_tax_breakup",
"other_charges_calculation",
"item_wise_tax_details",
@@ -194,13 +198,13 @@
"column_break8",
"unrealized_profit_loss_account",
"against_income_account",
"sales_team_section_break",
"commission_section",
"sales_partner",
"amount_eligible_for_commission",
"column_break10",
"commission_rate",
"total_commission",
"section_break2",
"sales_team_section",
"sales_team",
"edit_printing_settings",
"letter_head",
@@ -215,20 +219,21 @@
"column_break_140",
"to_date",
"update_auto_repeat_reference",
"utm_analytics_section",
"utm_source",
"utm_medium",
"column_break_ixxw",
"utm_campaign",
"utm_content",
"more_information",
"status",
"inter_company_invoice_reference",
"represents_company",
"remarks",
"customer_group",
"column_break_imbx",
"utm_source",
"utm_campaign",
"utm_medium",
"utm_content",
"col_break23",
"is_internal_customer",
"represents_company",
"inter_company_invoice_reference",
"is_discounted",
"remarks",
"connections_tab"
],
"fields": [
@@ -266,6 +271,7 @@
"oldfieldtype": "Link",
"options": "Customer",
"print_hide": 1,
"reqd": 1,
"search_index": 1
},
{
@@ -703,6 +709,7 @@
},
{
"default": "0",
"depends_on": "eval:doc.items.every((item) => !item.dn_detail)",
"fieldname": "update_stock",
"fieldtype": "Check",
"hide_days": 1,
@@ -778,8 +785,7 @@
},
{
"collapsible": 1,
"collapsible_depends_on": "eval:doc.total_billing_amount > 0",
"depends_on": "eval:!doc.is_return",
"collapsible_depends_on": "eval:doc.total_billing_amount > 0 || doc.total_billing_hours > 0",
"fieldname": "time_sheet_list",
"fieldtype": "Section Break",
"hide_border": 1,
@@ -793,7 +799,6 @@
"hide_days": 1,
"hide_seconds": 1,
"label": "Time Sheets",
"no_copy": 1,
"options": "Sales Invoice Timesheet",
"print_hide": 1
},
@@ -1074,14 +1079,6 @@
"no_copy": 1,
"options": "Cost Center"
},
{
"collapsible": 1,
"fieldname": "section_break_49",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Additional Discount"
},
{
"default": "Grand Total",
"fieldname": "apply_discount_on",
@@ -1126,22 +1123,12 @@
"options": "currency",
"print_hide": 1
},
{
"fieldname": "totals",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Totals",
"oldfieldtype": "Section Break",
"options": "fa fa-money",
"print_hide": 1
},
{
"fieldname": "base_grand_total",
"fieldtype": "Currency",
"hide_days": 1,
"hide_seconds": 1,
"label": "Grand Total (Company Currency)",
"label": "Grand Total (Company Currency",
"oldfieldname": "grand_total",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
@@ -1155,9 +1142,8 @@
"fieldtype": "Currency",
"hide_days": 1,
"hide_seconds": 1,
"label": "Rounding Adjustment (Company Currency)",
"label": "Rounding Adjustment",
"no_copy": 1,
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
@@ -1167,10 +1153,9 @@
"fieldtype": "Currency",
"hide_days": 1,
"hide_seconds": 1,
"label": "Rounded Total (Company Currency)",
"label": "Rounded Total",
"oldfieldname": "rounded_total",
"oldfieldtype": "Currency",
"options": "Company:company:default_currency",
"print_hide": 1,
"read_only": 1
},
@@ -1180,7 +1165,7 @@
"fieldtype": "Small Text",
"hide_days": 1,
"hide_seconds": 1,
"label": "In Words (Company Currency)",
"label": "In Words",
"length": 240,
"oldfieldname": "in_words",
"oldfieldtype": "Data",
@@ -1273,7 +1258,6 @@
"read_only": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "advances",
"fieldname": "advances_section",
"fieldtype": "Section Break",
@@ -1649,13 +1633,6 @@
"no_copy": 1,
"read_only": 1
},
{
"fieldname": "col_break23",
"fieldtype": "Column Break",
"hide_days": 1,
"hide_seconds": 1,
"width": "50%"
},
{
"default": "Draft",
"fieldname": "status",
@@ -1707,10 +1684,10 @@
"read_only": 1
},
{
"allow_on_submit": 1,
"default": "No",
"fieldname": "is_opening",
"fieldtype": "Select",
"hidden": 1,
"hide_days": 1,
"hide_seconds": 1,
"label": "Is Opening Entry",
@@ -1739,18 +1716,6 @@
"oldfieldtype": "Text",
"print_hide": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "sales_partner",
"fieldname": "sales_team_section_break",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Commission",
"oldfieldtype": "Section Break",
"options": "fa fa-group",
"print_hide": 1
},
{
"fieldname": "sales_partner",
"fieldtype": "Link",
@@ -1794,16 +1759,6 @@
"options": "Company:company:default_currency",
"print_hide": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "sales_team",
"fieldname": "section_break2",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Sales Team",
"print_hide": 1
},
{
"allow_on_submit": 1,
"fieldname": "sales_team",
@@ -2092,7 +2047,7 @@
"fieldtype": "Column Break"
},
{
"depends_on": "eval:(!doc.is_return && doc.total_billing_amount > 0)",
"depends_on": "eval:doc.total_billing_amount > 0 || doc.total_billing_hours > 0",
"fieldname": "section_break_104",
"fieldtype": "Section Break"
},
@@ -2252,7 +2207,8 @@
"hidden": 1,
"label": "Item Wise Tax Details",
"no_copy": 1,
"options": "Item Wise Tax Detail"
"options": "Item Wise Tax Detail",
"print_hide": 1
},
{
"default": "0",
@@ -2293,6 +2249,74 @@
"fieldname": "override_tax_withholding_entries",
"fieldtype": "Check",
"label": "Edit Tax Withholding Entries"
},
{
"fieldname": "totals_section",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Totals",
"oldfieldtype": "Section Break",
"options": "fa fa-money",
"print_hide": 1
},
{
"fieldname": "base_totals_section",
"fieldtype": "Section Break",
"label": "Totals (Company Currency)",
"options": "Company:company:default_currency"
},
{
"fieldname": "column_break_xjag",
"fieldtype": "Column Break"
},
{
"collapsible": 1,
"fieldname": "additional_discount_section",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Additional Discount"
},
{
"collapsible": 1,
"collapsible_depends_on": "sales_team",
"fieldname": "sales_team_section",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Sales Team",
"print_hide": 1
},
{
"collapsible": 1,
"collapsible_depends_on": "sales_partner",
"fieldname": "commission_section",
"fieldtype": "Section Break",
"hide_days": 1,
"hide_seconds": 1,
"label": "Commission",
"oldfieldtype": "Section Break",
"options": "fa fa-group",
"print_hide": 1
},
{
"fieldname": "section_break_vacb",
"fieldtype": "Section Break"
},
{
"fieldname": "column_break_rdks",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_ixxw",
"fieldtype": "Column Break"
},
{
"collapsible": 1,
"fieldname": "utm_analytics_section",
"fieldtype": "Section Break",
"label": "UTM Analytics"
}
],
"grid_page_length": 50,
@@ -2306,7 +2330,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2025-10-09 14:48:59.472826",
"modified": "2026-02-28 17:58:56.453076",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -33,6 +33,7 @@ from erpnext.accounts.utils import (
get_account_currency,
update_voucher_outstanding,
)
from erpnext.assets.doctype.asset.asset import split_asset
from erpnext.assets.doctype.asset.depreciation import (
depreciate_asset,
get_gl_entries_on_asset_disposal,
@@ -118,7 +119,7 @@ class SalesInvoice(SellingController):
cost_center: DF.Link | None
coupon_code: DF.Link | None
currency: DF.Link
customer: DF.Link | None
customer: DF.Link
customer_address: DF.Link | None
customer_group: DF.Link | None
customer_name: DF.SmallText | None
@@ -352,10 +353,22 @@ class SalesInvoice(SellingController):
self.is_opening = "No"
self.set_against_income_account()
self.validate_time_sheets_are_submitted()
if self.is_return and not self.return_against and self.timesheets:
frappe.throw(_("Direct return is not allowed for Timesheet."))
if not self.is_return:
self.validate_time_sheets_are_submitted()
self.validate_multiple_billing("Delivery Note", "dn_detail", "amount")
if self.is_return:
self.timesheets = []
if self.is_return and self.return_against:
for row in self.timesheets:
if row.billing_hours:
row.billing_hours = -abs(row.billing_hours)
if row.billing_amount:
row.billing_amount = -abs(row.billing_amount)
self.update_packing_list()
self.set_billing_hours_and_amount()
self.update_timesheet_billing_for_project()
@@ -468,6 +481,8 @@ class SalesInvoice(SellingController):
self.update_stock_reservation_entries()
self.update_stock_ledger()
self.split_asset_based_on_sale_qty()
self.process_asset_depreciation()
# this sequence because outstanding may get -ve
@@ -484,7 +499,7 @@ class SalesInvoice(SellingController):
if cint(self.is_pos) != 1 and not self.is_return:
self.update_against_document_in_jv()
self.update_time_sheet(self.name)
self.update_time_sheet(None if (self.is_return and self.return_against) else self.name)
if frappe.get_single_value("Selling Settings", "sales_update_frequency") == "Each Transaction":
update_company_current_month_sales(self.company)
@@ -564,7 +579,7 @@ class SalesInvoice(SellingController):
self.check_if_consolidated_invoice()
super().before_cancel()
self.update_time_sheet(None)
self.update_time_sheet(self.return_against if (self.is_return and self.return_against) else None)
def on_cancel(self):
check_if_return_invoice_linked_with_payment_entry(self)
@@ -804,8 +819,20 @@ class SalesInvoice(SellingController):
for data in timesheet.time_logs:
if (
(self.project and args.timesheet_detail == data.name)
or (not self.project and not data.sales_invoice)
or (not sales_invoice and data.sales_invoice == self.name)
or (not self.project and not data.sales_invoice and args.timesheet_detail == data.name)
or (
not sales_invoice
and data.sales_invoice == self.name
and args.timesheet_detail == data.name
)
or (
self.is_return
and self.return_against
and data.sales_invoice
and data.sales_invoice == self.return_against
and not sales_invoice
and args.timesheet_detail == data.name
)
):
data.sales_invoice = sales_invoice
@@ -845,11 +872,26 @@ class SalesInvoice(SellingController):
payment.account = get_bank_cash_account(payment.mode_of_payment, self.company).get("account")
def validate_time_sheets_are_submitted(self):
# Note: This validation is skipped for return invoices
# to allow returns to reference already-billed timesheet details
for data in self.timesheets:
# Handle invoice duplication
if data.time_sheet and data.timesheet_detail:
if sales_invoice := frappe.db.get_value(
"Timesheet Detail", data.timesheet_detail, "sales_invoice"
):
frappe.throw(
_("Row {0}: Sales Invoice {1} is already created for {2}").format(
data.idx, frappe.bold(sales_invoice), frappe.bold(data.time_sheet)
)
)
if data.time_sheet:
status = frappe.db.get_value("Timesheet", data.time_sheet, "status")
if status not in ["Submitted", "Payslip"]:
frappe.throw(_("Timesheet {0} is already completed or cancelled").format(data.time_sheet))
if status not in ["Submitted", "Payslip", "Partially Billed"]:
frappe.throw(
_("Timesheet {0} cannot be invoiced in its current state").format(data.time_sheet)
)
def set_pos_fields(self, for_validate=False):
"""Set retail related fields from POS Profiles"""
@@ -1283,7 +1325,12 @@ class SalesInvoice(SellingController):
timesheet.billing_amount = ts_doc.total_billable_amount
def update_timesheet_billing_for_project(self):
if not self.timesheets and self.project and self.is_auto_fetch_timesheet_enabled():
if (
not self.is_return
and not self.timesheets
and self.project
and self.is_auto_fetch_timesheet_enabled()
):
self.add_timesheet_data()
else:
self.calculate_billing_amount_for_timesheet()
@@ -1358,6 +1405,51 @@ class SalesInvoice(SellingController):
):
throw(_("Delivery Note {0} is not submitted").format(d.delivery_note))
def split_asset_based_on_sale_qty(self):
asset_qty_map = self.get_asset_qty()
for asset, qty in asset_qty_map.items():
if qty["actual_qty"] < qty["sale_qty"]:
frappe.throw(
_(
"Sell quantity cannot exceed the asset quantity. Asset {0} has only {1} item(s)."
).format(asset, qty["actual_qty"])
)
remaining_qty = qty["actual_qty"] - qty["sale_qty"]
if remaining_qty > 0:
split_asset(asset, remaining_qty)
def get_asset_qty(self):
asset_qty_map = {}
assets = {row.asset for row in self.items if row.is_fixed_asset and row.asset}
if not assets or self.is_return:
return asset_qty_map
asset_actual_qty = dict(
frappe.db.get_all(
"Asset",
{"name": ["in", list(assets)]},
["name", "asset_quantity"],
as_list=True,
)
)
for row in self.items:
if row.is_fixed_asset and row.asset:
actual_qty = asset_actual_qty.get(row.asset)
if row.asset in asset_qty_map.keys():
asset_qty_map[row.asset]["sale_qty"] += flt(row.qty)
else:
asset_qty_map.setdefault(
row.asset,
{
"sale_qty": flt(row.qty),
"actual_qty": flt(actual_qty),
},
)
return asset_qty_map
def process_asset_depreciation(self):
if (self.is_return and self.docstatus == 2) or (not self.is_return and self.docstatus == 1):
self.depreciate_asset_on_sale()
@@ -2378,7 +2470,10 @@ def make_delivery_note(source_name, target_doc=None):
"cost_center": "cost_center",
},
"postprocess": update_item,
"condition": lambda doc: doc.delivered_by_supplier != 1 and not doc.scio_detail,
"condition": lambda doc: doc.delivered_by_supplier != 1
and not doc.scio_detail
and not doc.dn_detail
and doc.qty - doc.delivered_qty > 0,
},
"Sales Taxes and Charges": {"doctype": "Sales Taxes and Charges", "reset_value": True},
"Sales Team": {

View File

@@ -2951,6 +2951,60 @@ class TestSalesInvoice(ERPNextTestSuite):
self.assertEqual(sales_invoice.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
self.assertEqual(sales_invoice.items[0].item_tax_rate, item_tax_map)
def test_item_tax_template_change_with_grand_total_discount(self):
"""
Test that when item tax template changes due to discount on Grand Total,
the tax calculations are consistent.
"""
item = create_item("Test Item With Multiple Tax Templates")
item.set("taxes", [])
item.append(
"taxes",
{
"item_tax_template": "_Test Account Excise Duty @ 10 - _TC",
"minimum_net_rate": 0,
"maximum_net_rate": 500,
},
)
item.append(
"taxes",
{
"item_tax_template": "_Test Account Excise Duty @ 12 - _TC",
"minimum_net_rate": 501,
"maximum_net_rate": 1000,
},
)
item.save()
si = create_sales_invoice(item=item.name, rate=700, do_not_save=True)
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "_Test Account Excise Duty - _TC",
"cost_center": "_Test Cost Center - _TC",
"description": "Excise Duty",
"rate": 0,
},
)
si.insert()
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 12 - _TC")
si.apply_discount_on = "Grand Total"
si.discount_amount = 300
si.save()
# Verify template changed to 10%
self.assertEqual(si.items[0].item_tax_template, "_Test Account Excise Duty @ 10 - _TC")
self.assertEqual(si.taxes[0].tax_amount, 70) # 10% of 700
self.assertEqual(si.grand_total, 470) # 700 + 70 - 300
si.submit()
@IntegrationTestCase.change_settings("Selling Settings", {"enable_discount_accounting": 1})
def test_sales_invoice_with_discount_accounting_enabled(self):
discount_account = create_account(
@@ -4691,6 +4745,66 @@ class TestSalesInvoice(ERPNextTestSuite):
doc.db_set("do_not_use_batchwise_valuation", original_value)
@change_settings("Selling Settings", {"set_zero_rate_for_expired_batch": True})
def test_zero_valuation_for_standalone_credit_note_with_expired_batch(self):
item_code = "_Test Item for Expiry Batch Zero Valuation"
make_item_for_si(
item_code,
{
"is_stock_item": 1,
"has_batch_no": 1,
"has_expiry_date": 1,
"shelf_life_in_days": 2,
"create_new_batch": 1,
"batch_number_series": "TBATCH-EBZV.####",
},
)
se = make_stock_entry(
item_code=item_code,
qty=10,
target="_Test Warehouse - _TC",
rate=100,
)
# fetch batch no from bundle
batch_no = get_batch_from_bundle(se.items[0].serial_and_batch_bundle)
si = create_sales_invoice(
posting_date=add_days(nowdate(), 3),
item=item_code,
qty=-10,
rate=100,
is_return=1,
update_stock=1,
use_serial_batch_fields=1,
do_not_save=1,
do_not_submit=1,
)
si.items[0].batch_no = batch_no
si.save()
si.submit()
si.reload()
# check zero incoming rate in voucher
self.assertEqual(si.items[0].incoming_rate, 0.0)
# chekc zero incoming rate in stock ledger
stock_ledger_entry = frappe.db.get_value(
"Stock Ledger Entry",
{
"voucher_type": "Sales Invoice",
"voucher_no": si.name,
"item_code": item_code,
"warehouse": "_Test Warehouse - _TC",
},
["incoming_rate", "valuation_rate"],
as_dict=True,
)
self.assertEqual(stock_ledger_entry.incoming_rate, 0.0)
def make_item_for_si(item_code, properties=None):
from erpnext.stock.doctype.item.test_item import make_item

View File

@@ -52,6 +52,7 @@
"is_free_item",
"apply_tds",
"grant_commission",
"allow_zero_valuation_rate",
"section_break_21",
"net_rate",
"net_amount",
@@ -88,7 +89,6 @@
"serial_and_batch_bundle",
"use_serial_batch_fields",
"col_break5",
"allow_zero_valuation_rate",
"incoming_rate",
"item_tax_rate",
"actual_batch_qty",
@@ -580,6 +580,7 @@
{
"collapsible": 1,
"collapsible_depends_on": "eval:doc.serial_no || doc.batch_no",
"depends_on": "eval:parent.update_stock",
"fieldname": "warehouse_and_reference",
"fieldtype": "Section Break",
"label": "Stock Details"
@@ -595,7 +596,7 @@
"print_hide": 1
},
{
"depends_on": "eval: parent.is_internal_customer && parent.update_stock",
"depends_on": "eval: parent.is_internal_customer",
"fieldname": "target_warehouse",
"fieldtype": "Link",
"hidden": 1,
@@ -613,7 +614,6 @@
"options": "Quality Inspection"
},
{
"depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "batch_no",
"fieldtype": "Link",
"label": "Batch No",
@@ -626,6 +626,7 @@
},
{
"default": "0",
"depends_on": "eval:parent.update_stock",
"fieldname": "allow_zero_valuation_rate",
"fieldtype": "Check",
"label": "Allow Zero Valuation Rate",
@@ -633,7 +634,6 @@
"print_hide": 1
},
{
"depends_on": "eval: doc.use_serial_batch_fields === 1 && parent.update_stock === 1",
"fieldname": "serial_no",
"fieldtype": "Text",
"label": "Serial No",
@@ -843,6 +843,7 @@
"fieldtype": "Currency",
"label": "Incoming Rate (Costing)",
"no_copy": 1,
"non_negative": 1,
"options": "Company:company:default_currency",
"print_hide": 1
},
@@ -906,7 +907,7 @@
"read_only": 1
},
{
"depends_on": "eval:parent.update_stock == 1 && (doc.use_serial_batch_fields === 0 || doc.docstatus === 1)",
"depends_on": "eval:doc.use_serial_batch_fields === 0 || doc.docstatus === 1",
"fieldname": "serial_and_batch_bundle",
"fieldtype": "Link",
"label": "Serial and Batch Bundle",
@@ -916,7 +917,7 @@
"search_index": 1
},
{
"depends_on": "eval:parent.update_stock === 1",
"depends_on": "eval:doc.use_serial_batch_fields === 0 && doc.docstatus === 0",
"fieldname": "pick_serial_and_batch",
"fieldtype": "Button",
"label": "Pick Serial / Batch No"
@@ -1009,7 +1010,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2025-09-04 11:08:25.583561",
"modified": "2026-02-23 14:37:14.853941",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -26,7 +26,7 @@
},
{
"default": "0",
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
"depends_on": "eval: [\"POS Invoice\", \"Sales Invoice\"].includes(parent.doctype)",
"fieldname": "amount",
"fieldtype": "Currency",
"in_list_view": 1,
@@ -85,14 +85,15 @@
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:36.427565",
"modified": "2026-02-16 20:46:34.592604",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Payment",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -52,7 +52,6 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Timesheet Detail",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
@@ -117,15 +116,16 @@
],
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:36.562795",
"modified": "2025-12-23 13:54:17.677187",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Timesheet",
"owner": "Administrator",
"permissions": [],
"quick_entry": 1,
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -415,7 +415,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 500,
"description": "Test",
"add_deduct_tax": "Add",
},
)
pi.save()
@@ -506,7 +505,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 200,
"description": "Test Gross Tax",
"add_deduct_tax": "Add",
},
)
si.save()
@@ -541,10 +539,10 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 400,
"description": "Test Gross Tax",
"add_deduct_tax": "Add",
},
)
si.save()
si.reload()
si.submit()
invoices.append(si)
# For amount before threshold (first 8000 + VAT): TCS entry with amount zero
@@ -594,7 +592,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 500,
"description": "VAT added to test TDS calculation on gross amount",
"add_deduct_tax": "Add",
},
)
si.save()
@@ -1024,7 +1021,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 1000,
"description": "VAT added to test TDS calculation on gross amount",
"add_deduct_tax": "Add",
},
)
pi.save()
@@ -1162,7 +1158,6 @@ class TestTaxWithholdingCategory(IntegrationTestCase):
"cost_center": "Main - _TC",
"tax_amount": 8000,
"description": "Test",
"add_deduct_tax": "Add",
},
)

View File

@@ -708,6 +708,10 @@ class TaxWithholdingController:
existing_taxes = {row.account_head: row for row in self.doc.taxes if row.is_tax_withholding_account}
precision = self.doc.precision("tax_amount", "taxes")
conversion_rate = self.get_conversion_rate()
add_deduct_tax = "Deduct"
if self.party_type == "Customer":
add_deduct_tax = "Add"
for account_head, base_amount in account_amount_map.items():
tax_amount = flt(base_amount / conversion_rate, precision)
@@ -724,6 +728,7 @@ class TaxWithholdingController:
tax_row = self._create_tax_row(account_head, tax_amount)
for_update = False
tax_row.add_deduct_tax = add_deduct_tax
# Set item-wise tax breakup for this tax row
self._set_item_wise_tax_for_tds(
tax_row, account_head, category_withholding_map, for_update=for_update
@@ -743,7 +748,6 @@ class TaxWithholdingController:
"account_head": account_head,
"description": account_head,
"cost_center": cost_center,
"add_deduct_tax": "Deduct",
"tax_amount": tax_amount,
"dont_recompute_tax": 1,
},
@@ -807,12 +811,14 @@ class TaxWithholdingController:
else:
item_tax_amount = 0
multiplier = -1 if tax_row.add_deduct_tax == "Deduct" else 1
self.doc._item_wise_tax_details.append(
frappe._dict(
item=item,
tax=tax_row,
rate=category.tax_rate,
amount=item_tax_amount * -1, # Negative because it's a deduction
amount=item_tax_amount * multiplier,
taxable_amount=item_base_taxable,
)
)

View File

@@ -43,16 +43,18 @@
"read_only": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 13:10:55.008837",
"modified": "2025-11-14 16:17:25.584675",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Transaction Deletion Record Details",
"owner": "Administrator",
"permissions": [],
"row_format": "Dynamic",
"sort_field": "creation",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -0,0 +1,41 @@
{
"allow_roles": [
{
"role": "Accounts Manager"
},
{
"role": "Accounts User"
}
],
"creation": "2026-02-22 18:26:42.015787",
"docstatus": 0,
"doctype": "Module Onboarding",
"idx": 4,
"is_complete": 0,
"modified": "2026-02-23 22:51:34.267812",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting Onboarding",
"owner": "Administrator",
"steps": [
{
"step": "Chart of Accounts"
},
{
"step": "Setup Sales taxes"
},
{
"step": "Create Sales Invoice"
},
{
"step": "Create Payment Entry"
},
{
"step": "View Balance Sheet"
},
{
"step": "Review Accounts Settings"
}
],
"title": "Accounting Onboarding"
}

View File

@@ -1,3 +1,43 @@
<h3>{{ _("Fiscal Year") }}</h3>
<h4>{{ _("New Fiscal Year - {0}").format(doc.name) }}</h4>
<p>{{ _("New fiscal year created :- ") }} {{ doc.name }}</p>
<p>{{ _("A new fiscal year has been automatically created.") }}</p>
<p>{{ _("Fiscal Year Details") }}</p>
<table style="margin-bottom: 1rem; width: 70%">
<tr>
<td style="font-weight:bold; width: 40%">{{ _("Year Name") }}</td>
<td>{{ doc.name }}</td>
</tr>
<tr>
<td style="font-weight:bold; width: 40%">{{ _("Start Date") }}</td>
<td>{{ frappe.format_value(doc.year_start_date) }}</td>
</tr>
<tr>
<td style="font-weight:bold; width: 40%">{{ _("End Date") }}</td>
<td>{{ frappe.format_value(doc.year_end_date) }}</td>
</tr>
{% if doc.companies|length > 0 %}
<tr>
<td style="vertical-align: top; font-weight: bold; width: 40%" rowspan="{{ doc.companies|length }}">
{% if doc.companies|length < 2 %}
{{ _("Company") }}
{% else %}
{{ _("Companies") }}
{% endif %}
</td>
<td>{{ doc.companies[0].company }}</td>
</tr>
{% for idx in range(1, doc.companies|length) %}
<tr>
<td>{{ doc.companies[idx].company }}</td>
</tr>
{% endfor %}
{% endif %}
</table>
{% if doc.disabled %}
<p>{{ _("The fiscal year has been automatically created in a Disabled state to maintain consistency with the previous fiscal year's status.") }}</p>
{% endif %}
<p>{{ _("Please review the {0} configuration and complete any required financial setup activities.").format(frappe.utils.get_link_to_form("Fiscal Year", doc.name, frappe.bold("Fiscal Year"))) }}</p>

View File

@@ -1,7 +1,8 @@
{
"attach_print": 0,
"channel": "Email",
"condition": "doc.auto_created",
"condition": "doc.auto_created == 1",
"condition_type": "Python",
"creation": "2018-04-25 14:19:05.440361",
"days_in_advance": 0,
"docstatus": 0,
@@ -11,8 +12,10 @@
"event": "New",
"idx": 0,
"is_standard": 1,
"message": "<h4>{{ _(\"New Fiscal Year - {0}\").format(doc.name) }}</h4>\n\n<p>{{ _(\"A new fiscal year has been automatically created.\") }}</p>\n\n<p>{{ _(\"Fiscal Year Details\") }}</p>\n\n<table style=\"margin-bottom: 1rem; width: 70%\">\n <tr>\n <td style=\"font-weight:bold; width: 40%\">{{ _(\"Year Name\") }}</td>\n <td>{{ doc.name }}</td>\n </tr>\n <tr>\n <td style=\"font-weight:bold; width: 40%\">{{ _(\"Start Date\") }}</td>\n <td>{{ frappe.format_value(doc.year_start_date) }}</td>\n </tr>\n <tr>\n <td style=\"font-weight:bold; width: 40%\">{{ _(\"End Date\") }}</td>\n <td>{{ frappe.format_value(doc.year_end_date) }}</td>\n </tr>\n {% if doc.companies|length > 0 %}\n <tr>\n <td style=\"vertical-align: top; font-weight: bold; width: 40%\" rowspan=\"{{ doc.companies|length }}\">\n {% if doc.companies|length < 2 %}\n {{ _(\"Company\") }}\n {% else %}\n {{ _(\"Companies\") }}\n {% endif %}\n </td>\n <td>{{ doc.companies[0].company }}</td>\n </tr>\n {% for idx in range(1, doc.companies|length) %}\n <tr>\n <td>{{ doc.companies[idx].company }}</td>\n </tr>\n {% endfor %}\n {% endif %}\n</table>\n\n{% if doc.disabled %}\n<p>{{ _(\"The fiscal year has been automatically created in a Disabled state to maintain consistency with the previous fiscal year's status.\") }}</p>\n{% endif %}\n\n<p>{{ _(\"Please review the {0} configuration and complete any required financial setup activities.\").format(frappe.utils.get_link_to_form(\"Fiscal Year\", doc.name, frappe.bold(\"Fiscal Year\"))) }}</p>",
"message_type": "HTML",
"modified": "2023-11-17 08:54:51.532104",
"minutes_offset": 0,
"modified": "2026-02-23 17:37:03.755394",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Notification for new fiscal year",
@@ -27,5 +30,5 @@
],
"send_system_notification": 0,
"send_to_all_assignees": 0,
"subject": "Notification for new fiscal year {{ doc.name }}"
"subject": "New Fiscal Year {{ doc.name }} - Review Required"
}

View File

@@ -0,0 +1,20 @@
{
"action": "Go to Page",
"action_label": "Configure Chart of Accounts",
"creation": "2026-02-22 18:28:15.401383",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 1,
"is_complete": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2026-02-23 22:44:45.540780",
"modified_by": "Administrator",
"name": "Chart of Accounts",
"owner": "Administrator",
"path": "Tree/Account",
"show_form_tour": 0,
"show_full_form": 0,
"title": "Review Chart of Accounts",
"validate_action": 1
}

View File

@@ -0,0 +1,21 @@
{
"action": "Create Entry",
"action_label": "Create Payment Entry",
"creation": "2026-02-23 19:22:12.005360",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2026-02-23 20:19:56.482245",
"modified_by": "Administrator",
"name": "Create Payment Entry",
"owner": "Administrator",
"reference_document": "Payment Entry",
"route_options": "{\n \"payment_type\": \"Receive\",\n \"party_type\": \"Customer\"\n}",
"show_form_tour": 0,
"show_full_form": 0,
"title": "Create Payment Entry",
"validate_action": 1
}

View File

@@ -0,0 +1,20 @@
{
"action": "Create Entry",
"action_label": "Create Sales Invoice",
"creation": "2026-02-20 13:42:38.439574",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 2,
"is_complete": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2026-02-23 22:16:40.931428",
"modified_by": "Administrator",
"name": "Create Sales Invoice",
"owner": "Administrator",
"reference_document": "Sales Invoice",
"show_form_tour": 0,
"show_full_form": 0,
"title": "Create Sales Invoice",
"validate_action": 1
}

View File

@@ -0,0 +1,21 @@
{
"action": "Update Settings",
"action_label": "Review Accounts Settings",
"creation": "2026-02-23 19:27:06.055104",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
"is_single": 1,
"is_skipped": 0,
"modified": "2026-02-23 22:16:40.855407",
"modified_by": "Administrator",
"name": "Review Accounts Settings",
"owner": "Administrator",
"path": "desk/accounts-settings",
"reference_document": "Accounts Settings",
"show_form_tour": 0,
"show_full_form": 0,
"title": "Review Accounts Settings",
"validate_action": 0
}

View File

@@ -0,0 +1,22 @@
{
"action": "Go to Page",
"action_label": "Setup Sales Taxes",
"creation": "2026-02-22 18:30:18.750391",
"docstatus": 0,
"doctype": "Onboarding Step",
"form_tour": "",
"idx": 1,
"is_complete": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2026-02-23 22:44:42.373227",
"modified_by": "Administrator",
"name": "Setup Sales taxes",
"owner": "Administrator",
"path": "/desk/sales-taxes-and-charges-template",
"reference_document": "Sales Taxes and Charges Template",
"show_form_tour": 0,
"show_full_form": 0,
"title": "Setup Sales taxes",
"validate_action": 1
}

View File

@@ -0,0 +1,23 @@
{
"action": "View Report",
"action_label": "View Balance Sheet",
"creation": "2026-02-23 19:22:57.651194",
"docstatus": 0,
"doctype": "Onboarding Step",
"idx": 0,
"is_complete": 0,
"is_single": 0,
"is_skipped": 0,
"modified": "2026-02-23 22:44:39.178107",
"modified_by": "Administrator",
"name": "View Balance Sheet",
"owner": "Administrator",
"reference_report": "Balance Sheet",
"report_description": "View Balance Sheet",
"report_reference_doctype": "GL Entry",
"report_type": "Script Report",
"show_form_tour": 0,
"show_full_form": 0,
"title": "View Balance Sheet",
"validate_action": 1
}

View File

@@ -7,18 +7,16 @@ from frappe import _, msgprint, qb, scrub
from frappe.contacts.doctype.address.address import get_company_address, get_default_address
from frappe.core.doctype.user_permission.user_permission import get_permitted_documents
from frappe.model.utils import get_fetch_values
from frappe.query_builder.functions import Abs, Count, Date, Sum
from frappe.query_builder.functions import Abs, Date, Sum
from frappe.utils import (
add_days,
add_months,
add_years,
cint,
cstr,
date_diff,
flt,
formatdate,
get_last_day,
get_timestamp,
getdate,
nowdate,
)
@@ -298,19 +296,9 @@ def complete_contact_details(party_details):
contact_details = frappe._dict()
if party_details.party_type == "Employee":
contact_details = frappe.db.get_value(
"Employee",
party_details.party,
[
"employee_name as contact_display",
"prefered_email as contact_email",
"cell_number as contact_mobile",
"designation as contact_designation",
"department as contact_department",
],
as_dict=True,
)
from erpnext.setup.doctype.employee.employee import _get_contact_details as get_employee_contact
contact_details = get_employee_contact(party_details.party)
contact_details.update({"contact_person": None, "contact_phone": None})
elif party_details.contact_person:
contact_details = frappe.db.get_value(

View File

@@ -17,7 +17,7 @@
</div>
<div class="col-xs-6">
<table>
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.format_date(doc.creation) }}</td></tr>
<tr><td><strong>Date: </strong></td><td>{{ frappe.utils.format_date(doc.posting_date) }}</td></tr>
</table>
</div>
</div>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import frappe
from frappe.tests import IntegrationTestCase
from frappe.utils import today
from frappe.utils import add_days, today
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.accounts.report.accounts_payable.accounts_payable import execute
@@ -57,3 +57,66 @@ class TestAccountsPayable(AccountsTestMixin, IntegrationTestCase):
if not do_not_submit:
pi = pi.submit()
return pi
def test_payment_terms_template_filters(self):
from erpnext.controllers.accounts_controller import get_payment_terms
payment_term1 = frappe.get_doc(
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 15 Days"}
).insert()
payment_term2 = frappe.get_doc(
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 30 Days"}
).insert()
template = frappe.get_doc(
{
"doctype": "Payment Terms Template",
"template_name": "_Test 50-50",
"terms": [
{
"doctype": "Payment Terms Template Detail",
"due_date_based_on": "Day(s) after invoice date",
"payment_term": payment_term1.name,
"description": "_Test 50-50",
"invoice_portion": 50,
"credit_days": 15,
},
{
"doctype": "Payment Terms Template Detail",
"due_date_based_on": "Day(s) after invoice date",
"payment_term": payment_term2.name,
"description": "_Test 50-50",
"invoice_portion": 50,
"credit_days": 30,
},
],
}
)
template.insert()
filters = {
"company": self.company,
"report_date": today(),
"range": "30, 60, 90, 120",
"based_on_payment_terms": 1,
"payment_terms_template": template.name,
"ageing_based_on": "Posting Date",
}
pi = self.create_purchase_invoice(do_not_submit=True)
pi.payment_terms_template = template.name
schedule = get_payment_terms(template.name)
pi.set("payment_schedule", [])
for row in schedule:
row["due_date"] = add_days(pi.posting_date, row.get("credit_days", 0))
pi.append("payment_schedule", row)
pi.save()
pi.submit()
report = execute(filters)
row = report[1][0]
self.assertEqual(len(report[1]), 2)
self.assertEqual([pi.name, payment_term1.payment_term_name], [row.voucher_no, row.payment_term])

View File

@@ -877,11 +877,15 @@ class ReceivablePayableReport:
else:
entry_date = row.posting_date
row.range0 = 0.0
self.get_ageing_data(entry_date, row)
# ageing buckets should not have amounts if due date is not reached
if getdate(entry_date) > getdate(self.age_as_on):
row.range0 = row.outstanding
[setattr(row, f"range{i}", 0.0) for i in self.range_numbers]
row.total_due = 0
return
row.total_due = sum(row[f"range{i}"] for i in self.range_numbers)
@@ -1031,9 +1035,8 @@ class ReceivablePayableReport:
self,
):
self.customer = qb.DocType("Customer")
if self.filters.get("customer_group"):
groups = get_customer_group_with_children(self.filters.customer_group)
groups = get_party_group_with_children("Customer", self.filters.customer_group)
customers = (
qb.from_(self.customer)
.select(self.customer.name)
@@ -1045,14 +1048,18 @@ class ReceivablePayableReport:
self.get_hierarchical_filters("Territory", "territory")
if self.filters.get("payment_terms_template"):
self.qb_selection_filter.append(
self.ple.party.isin(
qb.from_(self.customer)
.select(self.customer.name)
.where(self.customer.payment_terms == self.filters.get("payment_terms_template"))
)
customer_ptt = self.ple.party.isin(
qb.from_(self.customer)
.select(self.customer.name)
.where(self.customer.payment_terms == self.filters.get("payment_terms_template"))
)
si_ptt = self.add_payment_term_template_filters("Sales Invoice")
sales_ptt = self.ple.against_voucher_no.isin(si_ptt)
self.qb_selection_filter.append(Criterion.any([customer_ptt, sales_ptt]))
if self.filters.get("sales_partner"):
self.qb_selection_filter.append(
self.ple.party.isin(
@@ -1077,14 +1084,53 @@ class ReceivablePayableReport:
)
if self.filters.get("payment_terms_template"):
self.qb_selection_filter.append(
self.ple.party.isin(
qb.from_(supplier)
.select(supplier.name)
.where(supplier.payment_terms == self.filters.get("supplier_group"))
)
supplier_ptt = self.ple.party.isin(
qb.from_(supplier)
.select(supplier.name)
.where(supplier.payment_terms == self.filters.get("payment_terms_template"))
)
pi_ptt = self.add_payment_term_template_filters("Purchase Invoice")
purchase_ptt = self.ple.against_voucher_no.isin(pi_ptt)
self.qb_selection_filter.append(Criterion.any([supplier_ptt, purchase_ptt]))
def add_payment_term_template_filters(self, dtype):
voucher_type = qb.DocType(dtype)
ptt = (
qb.from_(voucher_type)
.select(voucher_type.name)
.where(voucher_type.payment_terms_template == self.filters.get("payment_terms_template"))
.where(voucher_type.company == self.filters.company)
)
if dtype == "Purchase Invoice":
party = "Supplier"
party_group_type = "supplier_group"
acc_type = "credit_to"
else:
party = "Customer"
party_group_type = "customer_group"
acc_type = "debit_to"
if self.filters.get(party_group_type):
party_groups = get_party_group_with_children(party, self.filters.get(party_group_type))
ptt = ptt.where((voucher_type[party_group_type]).isin(party_groups))
if self.filters.party:
ptt = ptt.where((voucher_type[party.lower()]).isin(self.filters.party))
if self.filters.cost_center:
cost_centers = get_cost_centers_with_children(self.filters.cost_center)
ptt = ptt.where(voucher_type.cost_center.isin(cost_centers))
if self.filters.party_account:
ptt = ptt.where(voucher_type[acc_type] == self.filters.party_account)
return ptt
def get_hierarchical_filters(self, doctype, key):
lft, rgt = frappe.db.get_value(doctype, self.filters.get(key), ["lft", "rgt"])
@@ -1281,6 +1327,8 @@ class ReceivablePayableReport:
ranges = [*self.ranges, _("Above")]
prev_range_value = 0
self.add_column(label=_("<0"), fieldname="range0", fieldtype="Currency")
self.ageing_column_labels.append(_("<0"))
for idx, curr_range_value in enumerate(ranges):
label = f"{prev_range_value}-{curr_range_value}"
self.add_column(label=label, fieldname="range" + str(idx + 1))
@@ -1296,7 +1344,9 @@ class ReceivablePayableReport:
for row in self.data:
row = frappe._dict(row)
if not cint(row.bold):
values = [flt(row.get(f"range{i}", None), precision) for i in self.range_numbers]
values = [flt(row.get("range0", 0), precision)] + [
flt(row.get(f"range{i}", 0), precision) for i in self.range_numbers
]
rows.append({"values": values})
self.chart = {
@@ -1322,20 +1372,26 @@ class ReceivablePayableReport:
self.err_journals = [x[0] for x in results] if results else []
def get_customer_group_with_children(customer_groups):
if not isinstance(customer_groups, list):
customer_groups = [d.strip() for d in customer_groups.strip().split(",") if d]
def get_party_group_with_children(party, party_groups):
if party not in ("Customer", "Supplier"):
return []
all_customer_groups = []
for d in customer_groups:
if frappe.db.exists("Customer Group", d):
lft, rgt = frappe.db.get_value("Customer Group", d, ["lft", "rgt"])
children = frappe.get_all("Customer Group", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
all_customer_groups += [c.name for c in children]
group_dtype = f"{party} Group"
if not isinstance(party_groups, list):
party_groups = [d.strip() for d in party_groups.strip().split(",") if d]
all_party_groups = []
for d in party_groups:
if frappe.db.exists(group_dtype, d):
lft, rgt = frappe.db.get_value(group_dtype, d, ["lft", "rgt"])
children = frappe.get_all(
group_dtype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, pluck="name"
)
all_party_groups += children
else:
frappe.throw(_("Customer Group: {0} does not exist").format(d))
frappe.throw(_("{0}: {1} does not exist").format(group_dtype, d))
return list(set(all_customer_groups))
return list(set(all_party_groups))
class InitSQLProceduresForAR:

View File

@@ -1139,3 +1139,66 @@ class TestAccountsReceivable(AccountsTestMixin, IntegrationTestCase):
self.assertEqual(len(report[1]), 1)
row = report[1][0]
self.assertEqual(expected_data_after_payment, [row.voucher_no, row.cost_center, row.outstanding])
def test_payment_terms_template_filters(self):
from erpnext.controllers.accounts_controller import get_payment_terms
payment_term1 = frappe.get_doc(
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 15 Days"}
).insert()
payment_term2 = frappe.get_doc(
{"doctype": "Payment Term", "payment_term_name": "_Test 50% on 30 Days"}
).insert()
template = frappe.get_doc(
{
"doctype": "Payment Terms Template",
"template_name": "_Test 50-50",
"terms": [
{
"doctype": "Payment Terms Template Detail",
"due_date_based_on": "Day(s) after invoice date",
"payment_term": payment_term1.name,
"description": "_Test 50-50",
"invoice_portion": 50,
"credit_days": 15,
},
{
"doctype": "Payment Terms Template Detail",
"due_date_based_on": "Day(s) after invoice date",
"payment_term": payment_term2.name,
"description": "_Test 50-50",
"invoice_portion": 50,
"credit_days": 30,
},
],
}
)
template.insert()
filters = {
"company": self.company,
"report_date": today(),
"range": "30, 60, 90, 120",
"based_on_payment_terms": 1,
"payment_terms_template": template.name,
"ageing_based_on": "Posting Date",
}
si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
si.payment_terms_template = template.name
schedule = get_payment_terms(template.name)
si.set("payment_schedule", [])
for row in schedule:
row["due_date"] = add_days(si.posting_date, row.get("credit_days", 0))
si.append("payment_schedule", row)
si.save()
si.submit()
report = execute(filters)
row = report[1][0]
self.assertEqual(len(report[1]), 2)
self.assertEqual([si.name, payment_term1.payment_term_name], [row.voucher_no, row.payment_term])

View File

@@ -102,7 +102,7 @@ def execute(filters=None):
filters.periodicity, period_list, filters.accumulated_values, company=filters.company
)
chart = get_chart_data(filters, columns, asset, liability, equity, currency)
chart = get_chart_data(filters, period_list, asset, liability, equity, currency)
report_summary, primitive_summary = get_report_summary(
period_list, asset, liability, equity, provisional_profit_loss, currency, filters
@@ -231,18 +231,19 @@ def get_report_summary(
], (net_asset - net_liability + net_equity)
def get_chart_data(filters, columns, asset, liability, equity, currency):
labels = [d.get("label") for d in columns[2:]]
def get_chart_data(filters, chart_columns, asset, liability, equity, currency):
labels = [col.get("label") for col in chart_columns]
asset_data, liability_data, equity_data = [], [], []
for p in columns[2:]:
for col in chart_columns:
key = col.get("key") or col.get("fieldname")
if asset:
asset_data.append(asset[-2].get(p.get("fieldname")))
asset_data.append(asset[-2].get(key))
if liability:
liability_data.append(liability[-2].get(p.get("fieldname")))
liability_data.append(liability[-2].get(key))
if equity:
equity_data.append(equity[-2].get(p.get("fieldname")))
equity_data.append(equity[-2].get(key))
datasets = []
if asset_data:

View File

@@ -5,6 +5,7 @@ import frappe
from frappe import _
from frappe.utils import add_months, flt, formatdate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import get_dimensions
from erpnext.accounts.utils import get_fiscal_year
from erpnext.controllers.trends import get_period_date_ranges
@@ -13,11 +14,15 @@ def execute(filters=None):
if not filters:
filters = {}
validate_filters(filters)
columns = get_columns(filters)
if filters.get("budget_against_filter"):
dimensions = filters.get("budget_against_filter")
else:
dimensions = get_budget_dimensions(filters)
if not dimensions:
return columns, [], None, None
budget_records = get_budget_records(filters, dimensions)
budget_map = build_budget_map(budget_records, filters)
@@ -29,6 +34,10 @@ def execute(filters=None):
return columns, data, None, chart_data
def validate_filters(filters):
validate_budget_dimensions(filters)
def get_budget_records(filters, dimensions):
budget_against_field = frappe.scrub(filters["budget_against"])
@@ -49,7 +58,7 @@ def get_budget_records(filters, dimensions):
b.company = %s
AND b.docstatus = 1
AND b.budget_against = %s
AND b.{budget_against_field} IN ({', '.join(['%s'] * len(dimensions))})
AND b.{budget_against_field} IN ({", ".join(["%s"] * len(dimensions))})
AND (
b.from_fiscal_year <= %s
AND b.to_fiscal_year >= %s
@@ -402,6 +411,17 @@ def get_budget_dimensions(filters):
) # nosec
def validate_budget_dimensions(filters):
dimensions = [d.get("document_type") for d in get_dimensions(with_cost_center_and_project=True)[0]]
if filters.get("budget_against") and filters.get("budget_against") not in dimensions:
frappe.throw(
title=_("Invalid Accounting Dimension"),
msg=_("{0} is not a valid Accounting Dimension.").format(
frappe.bold(filters.get("budget_against"))
),
)
def build_comparison_chart_data(filters, columns, data):
if not data:
return None

View File

@@ -145,7 +145,7 @@ def execute(filters=None):
True,
)
chart = get_chart_data(columns, data, company_currency)
chart = get_chart_data(period_list, data, company_currency)
report_summary = get_report_summary(summary_data, company_currency)
@@ -417,12 +417,12 @@ def get_report_summary(summary_data, currency):
return report_summary
def get_chart_data(columns, data, currency):
labels = [d.get("label") for d in columns[2:]]
def get_chart_data(period_list, data, currency):
labels = [period.get("label") for period in period_list]
datasets = [
{
"name": section.get("section").replace("'", ""),
"values": [section.get(d.get("fieldname")) for d in columns[2:]],
"values": [section.get(period.get("key")) for period in period_list],
}
for section in data
if section.get("parent_section") is None and section.get("currency")

View File

@@ -48,22 +48,25 @@ def execute(filters=None):
return columns, data, message, chart
fiscal_year = get_fiscal_year_data(filters.get("from_fiscal_year"), filters.get("to_fiscal_year"))
companies_column, companies = get_companies(filters)
columns = get_columns(companies_column, filters)
company_list, companies = get_companies(filters)
company_columns = get_company_columns(company_list, filters)
columns = get_columns(company_columns)
if filters.get("report") == "Balance Sheet":
data, message, chart, report_summary = get_balance_sheet_data(
fiscal_year, companies, columns, filters
fiscal_year, companies, company_columns, filters
)
elif filters.get("report") == "Profit and Loss Statement":
data, message, chart, report_summary = get_profit_loss_data(fiscal_year, companies, columns, filters)
data, message, chart, report_summary = get_profit_loss_data(
fiscal_year, companies, company_columns, filters
)
else:
data, report_summary = get_cash_flow_data(fiscal_year, companies, filters)
return columns, data, message, chart, report_summary
def get_balance_sheet_data(fiscal_year, companies, columns, filters):
def get_balance_sheet_data(fiscal_year, companies, company_columns, filters):
asset = get_data(companies, "Asset", "Debit", fiscal_year, filters=filters)
liability = get_data(companies, "Liability", "Credit", fiscal_year, filters=filters)
@@ -116,7 +119,7 @@ def get_balance_sheet_data(fiscal_year, companies, columns, filters):
True,
)
chart = get_chart_data(filters, columns, asset, liability, equity, company_currency)
chart = get_chart_data(filters, company_columns, asset, liability, equity, company_currency)
return data, message, chart, report_summary
@@ -164,7 +167,7 @@ def get_root_account_name(root_type, company):
return root_account[0][0]
def get_profit_loss_data(fiscal_year, companies, columns, filters):
def get_profit_loss_data(fiscal_year, companies, company_columns, filters):
income, expense, net_profit_loss = get_income_expense_data(companies, fiscal_year, filters)
company_currency = get_company_currency(filters)
@@ -174,7 +177,7 @@ def get_profit_loss_data(fiscal_year, companies, columns, filters):
if net_profit_loss:
data.append(net_profit_loss)
chart = get_pl_chart_data(filters, columns, income, expense, net_profit_loss, company_currency)
chart = get_pl_chart_data(filters, company_columns, income, expense, net_profit_loss, company_currency)
report_summary, primitive_summary = get_pl_summary(
companies, "", income, expense, net_profit_loss, company_currency, filters, True
@@ -280,7 +283,30 @@ def get_account_type_based_data(account_type, companies, fiscal_year, filters):
return data
def get_columns(companies, filters):
def get_company_columns(companies, filters):
company_columns = []
for company in companies:
apply_currency_formatter = 1 if not filters.presentation_currency else 0
currency = filters.presentation_currency
if not currency:
currency = erpnext.get_company_currency(company)
company_columns.append(
{
"fieldname": company,
"label": f"{company} ({currency})",
"fieldtype": "Currency",
"options": "currency",
"width": 150,
"apply_currency_formatter": apply_currency_formatter,
"company_name": company,
}
)
return company_columns
def get_columns(company_columns):
columns = [
{
"fieldname": "account",
@@ -298,23 +324,7 @@ def get_columns(companies, filters):
},
]
for company in companies:
apply_currency_formatter = 1 if not filters.presentation_currency else 0
currency = filters.presentation_currency
if not currency:
currency = erpnext.get_company_currency(company)
columns.append(
{
"fieldname": company,
"label": f"{company} ({currency})",
"fieldtype": "Currency",
"options": "currency",
"width": 150,
"apply_currency_formatter": apply_currency_formatter,
"company_name": company,
}
)
columns.extend(company_columns)
return columns

View File

@@ -86,6 +86,12 @@ frappe.query_reports["Consolidated Trial Balance"] = {
fieldtype: "Check",
default: 1,
},
{
fieldname: "show_net_values",
label: __("Show net values in opening and closing columns"),
fieldtype: "Check",
default: 1,
},
{
fieldname: "show_group_accounts",
label: __("Show Group Accounts"),

View File

@@ -14,6 +14,7 @@ from erpnext.accounts.report.financial_statements import (
)
from erpnext.accounts.report.trial_balance.trial_balance import (
accumulate_values_into_parents,
calculate_total_row,
calculate_values,
get_opening_balances,
hide_group_accounts,
@@ -44,7 +45,6 @@ def execute(filters: dict | None = None):
def validate_filters(filters):
validate_companies(filters)
filters.show_net_values = True
tb_validate_filters(filters)
@@ -99,16 +99,20 @@ def get_data(filters) -> list[list]:
tb_data = get_company_wise_tb_data(company_filter, reporting_currency, ignore_reporting_currency)
consolidate_trial_balance_data(data, tb_data)
for d in data:
prepare_opening_closing(d)
total_row = calculate_total_row(data, reporting_currency)
data.extend([{}, total_row])
if filters.get("show_net_values"):
prepare_opening_closing_for_ctb(data)
if not filters.get("show_group_accounts"):
data = hide_group_accounts(data)
total_row = calculate_total_row(
data, reporting_currency, show_group_accounts=filters.get("show_group_accounts")
)
calculate_foreign_currency_translation_reserve(total_row, data, filters=filters)
data.extend([total_row])
if filters.get("presentation_currency"):
update_to_presentation_currency(
data,
@@ -207,10 +211,6 @@ def prepare_companywise_tb_data(accounts, filters, parent_children_map, reportin
data = []
for d in accounts:
# Prepare opening closing for group account
if parent_children_map.get(d.account) and filters.get("show_net_values"):
prepare_opening_closing(d)
has_value = False
row = {
"account": d.name,
@@ -242,35 +242,9 @@ def prepare_companywise_tb_data(accounts, filters, parent_children_map, reportin
return data
def calculate_total_row(data, reporting_currency):
total_row = {
"account": "'" + _("Total") + "'",
"account_name": "'" + _("Total") + "'",
"warn_if_negative": True,
"opening_debit": 0.0,
"opening_credit": 0.0,
"debit": 0.0,
"credit": 0.0,
"closing_debit": 0.0,
"closing_credit": 0.0,
"parent_account": None,
"indent": 0,
"has_value": True,
"currency": reporting_currency,
}
for d in data:
if not d.get("parent_account"):
for field in value_fields:
total_row[field] += d[field]
if data:
calculate_foreign_currency_translation_reserve(total_row, data)
return total_row
def calculate_foreign_currency_translation_reserve(total_row, data):
def calculate_foreign_currency_translation_reserve(total_row, data, filters):
if not data or not total_row:
return
opening_dr_cr_diff = total_row["opening_debit"] - total_row["opening_credit"]
dr_cr_diff = total_row["debit"] - total_row["credit"]
@@ -289,7 +263,7 @@ def calculate_foreign_currency_translation_reserve(total_row, data):
"root_type": data[idx].get("root_type"),
"account_type": "Equity",
"parent_account": data[idx].get("account"),
"indent": data[idx].get("indent") + 1,
"indent": data[idx].get("indent") + 1 if filters.get("show_group_accounts") else 0,
"has_value": True,
"currency": total_row.get("currency"),
}
@@ -297,7 +271,8 @@ def calculate_foreign_currency_translation_reserve(total_row, data):
fctr_row["closing_debit"] = fctr_row["opening_debit"] + fctr_row["debit"]
fctr_row["closing_credit"] = fctr_row["opening_credit"] + fctr_row["credit"]
prepare_opening_closing(fctr_row)
if filters.get("show_net_values"):
prepare_opening_closing(fctr_row)
data.insert(idx + 1, fctr_row)
@@ -396,6 +371,11 @@ def update_to_presentation_currency(data, from_currency, to_currency, date, igno
d.update(currency=to_currency)
def prepare_opening_closing_for_ctb(data):
for d in data:
prepare_opening_closing(d)
def get_columns():
return [
{

View File

@@ -8,7 +8,7 @@ from frappe.query_builder import Criterion, Tuple
from frappe.query_builder.functions import IfNull
from frappe.utils import getdate, nowdate
from frappe.utils.nestedset import get_descendants_of
from pypika.terms import LiteralValue
from pypika.terms import Bracket, LiteralValue
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -84,10 +84,8 @@ class PartyLedgerSummaryReport:
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions(party_type)
if match_conditions:
query = query.where(LiteralValue(match_conditions))
if match_conditions := build_match_conditions(party_type):
query = query.where(Bracket(LiteralValue(match_conditions)))
party_details = query.run(as_dict=True)

View File

@@ -11,7 +11,7 @@ import frappe
from frappe import _
from frappe.query_builder.functions import Max, Min, Sum
from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate
from pypika.terms import ExistsCriterion
from pypika.terms import Bracket, ExistsCriterion, LiteralValue
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -564,18 +564,15 @@ def get_accounting_entries(
account_filter_query = get_account_filter_query(root_lft, root_rgt, root_type, gl_entry)
query = query.where(ExistsCriterion(account_filter_query))
if group_by_account:
query = query.groupby("account")
from frappe.desk.reportview import build_match_conditions
query, params = query.walk()
match_conditions = build_match_conditions(doctype)
if match_conditions := build_match_conditions(doctype):
query = query.where(Bracket(LiteralValue(match_conditions)))
if match_conditions:
query += "and" + match_conditions
if group_by_account:
query += " GROUP BY `account`"
return frappe.db.sql(query, params, as_dict=True)
return query.run(as_dict=True)
def get_account_filter_query(root_lft, root_rgt, root_type, gl_entry):

View File

@@ -324,10 +324,8 @@ def get_conditions(filters):
from frappe.desk.reportview import build_match_conditions
match_conditions = build_match_conditions("GL Entry")
if match_conditions:
conditions.append(match_conditions)
if match_conditions := build_match_conditions("GL Entry"):
conditions.append(f"({match_conditions})")
accounting_dimensions = get_accounting_dimensions(as_list=False)

View File

@@ -219,13 +219,18 @@ def get_net_profit(
has_value = False
gross_income_roots = [row for row in (gross_income or []) if not flt(row.get("indent"))]
non_gross_income_roots = [row for row in (non_gross_income or []) if not flt(row.get("indent"))]
gross_expense_roots = [row for row in (gross_expense or []) if not flt(row.get("indent"))]
non_gross_expense_roots = [row for row in (non_gross_expense or []) if not flt(row.get("indent"))]
for period in period_list:
key = period if consolidated else period.key
gross_income_for_period = flt(gross_income[0].get(key, 0)) if gross_income else 0
non_gross_income_for_period = flt(non_gross_income[0].get(key, 0)) if non_gross_income else 0
gross_expense_for_period = flt(gross_expense[0].get(key, 0)) if gross_expense else 0
non_gross_expense_for_period = flt(non_gross_expense[0].get(key, 0)) if non_gross_expense else 0
gross_income_for_period = sum(flt(row.get(key, 0)) for row in gross_income_roots)
non_gross_income_for_period = sum(flt(row.get(key, 0)) for row in non_gross_income_roots)
gross_expense_for_period = sum(flt(row.get(key, 0)) for row in gross_expense_roots)
non_gross_expense_for_period = sum(flt(row.get(key, 0)) for row in non_gross_expense_roots)
total_income = gross_income_for_period + non_gross_income_for_period
total_expense = gross_expense_for_period + non_gross_expense_for_period

Some files were not shown because too many files have changed in this diff Show More