Compare commits

...

543 Commits

Author SHA1 Message Date
Frappe PR Bot
66f1e2a076 chore(release): Bumped to Version 14.92.0
# [14.92.0](https://github.com/frappe/erpnext/compare/v14.91.3...v14.92.0) (2025-10-07)

### Bug Fixes

* **Common Code:** fetch canonical URI from Code List (backport [#49882](https://github.com/frappe/erpnext/issues/49882)) ([#49883](https://github.com/frappe/erpnext/issues/49883)) ([9b5183e](9b5183e0e5))
* do not fetch disabled item tax template ([dcae024](dcae024fd2))
* linter; dont change doc after DB update (backport [#49907](https://github.com/frappe/erpnext/issues/49907)) ([#49909](https://github.com/frappe/erpnext/issues/49909)) ([30a6fe5](30a6fe55ca))
* resolved conflict ([2c383a6](2c383a69f9))
* Set paid amount automatically only if return entry validated and has negative grand total ([#49829](https://github.com/frappe/erpnext/issues/49829)) ([b7d76d8](b7d76d8fad))

### Features

* dynamic due date in payment terms when fetched from order (backport [#48864](https://github.com/frappe/erpnext/issues/48864)) ([#49937](https://github.com/frappe/erpnext/issues/49937)) ([d82106c](d82106cb76))
2025-10-07 13:18:52 +00:00
ruthra kumar
1d5935a10f chore: release v14 (#49943)
* refactor(Supplier): custom buttons call make methods (backport #49840) (#49841)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>

* fix(Common Code): fetch canonical URI from Code List (backport #49882) (#49883)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Common Code): fetch canonical URI from Code List (#49882)

* fix: Set paid amount automatically only if return entry validated and has negative grand total (#49829)

(cherry picked from commit dcbcc596f2)

# Conflicts:
#	erpnext/public/js/controllers/taxes_and_totals.js

* fix: resolved conflict

* fix: linter; dont change doc after DB update (backport #49907) (#49909)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
fix: linter; dont change doc after DB update (#49907)

* fix: do not fetch disabled item tax template

(cherry picked from commit b10cf4a928)

# Conflicts:
#	erpnext/public/js/controllers/transaction.js
#	erpnext/stock/get_item_details.py

* chore: fix conflicts

* chore: fix conflicts

* chore: fix linters issue

* feat: dynamic due date in payment terms when fetched from order (backport #48864) (#49937)

* feat: dynamic due date in payment terms when fetched from order (#48864)

* fix: dynamic due date when payment terms are fetched from order

* fix(test): use change_settings decorator for settings enable and disable

* fix(test): compare schedule for due_date dynamically

* fix: save conditions for due date at invoice level

* fix: make fields read only and on change of date unset the date condition fields

* fix: remove fetch_form

* fix: correct field assingment

* fix: revert unwanted changes

* refactor: streamline payment term field assignments and enhance discount date handling

* refactor: remove payment_term from fields_to_copy and optimize currency handling in transaction callback

* refactor: ensure default values for payment schedule and discount validity fields

(cherry picked from commit 3c70cbbaf8)

# Conflicts:
#	erpnext/accounts/doctype/payment_schedule/payment_schedule.json
#	erpnext/accounts/doctype/payment_schedule/payment_schedule.py
#	erpnext/public/js/controllers/transaction.js
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py

* chore: resolve conflicts

---------

Co-authored-by: Lakshit Jain <ljain112@gmail.com>

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
Co-authored-by: ljain112 <ljain112@gmail.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-10-07 18:47:23 +05:30
mergify[bot]
d82106cb76 feat: dynamic due date in payment terms when fetched from order (backport #48864) (#49937)
* feat: dynamic due date in payment terms when fetched from order (#48864)

* fix: dynamic due date when payment terms are fetched from order

* fix(test): use change_settings decorator for settings enable and disable

* fix(test): compare schedule for due_date dynamically

* fix: save conditions for due date at invoice level

* fix: make fields read only and on change of date unset the date condition fields

* fix: remove fetch_form

* fix: correct field assingment

* fix: revert unwanted changes

* refactor: streamline payment term field assignments and enhance discount date handling

* refactor: remove payment_term from fields_to_copy and optimize currency handling in transaction callback

* refactor: ensure default values for payment schedule and discount validity fields

(cherry picked from commit 3c70cbbaf8)

# Conflicts:
#	erpnext/accounts/doctype/payment_schedule/payment_schedule.json
#	erpnext/accounts/doctype/payment_schedule/payment_schedule.py
#	erpnext/public/js/controllers/transaction.js
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py

* chore: resolve conflicts

---------

Co-authored-by: Lakshit Jain <ljain112@gmail.com>
2025-10-07 14:10:46 +05:30
rohitwaghchaure
03aeac6c9b Merge pull request #49931 from frappe/mergify/bp/version-14-hotfix/pr-49702
fix: do not fetch disabled item tax template (backport #49702)
2025-10-07 11:54:19 +05:30
rohitwaghchaure
014f5bff5c chore: fix linters issue 2025-10-07 11:24:49 +05:30
rohitwaghchaure
819667ab24 chore: fix conflicts 2025-10-07 11:00:45 +05:30
rohitwaghchaure
aa20e224fb chore: fix conflicts 2025-10-07 11:00:02 +05:30
ljain112
dcae024fd2 fix: do not fetch disabled item tax template
(cherry picked from commit b10cf4a928)

# Conflicts:
#	erpnext/public/js/controllers/transaction.js
#	erpnext/stock/get_item_details.py
2025-10-07 05:26:09 +00:00
mergify[bot]
30a6fe55ca fix: linter; dont change doc after DB update (backport #49907) (#49909)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
fix: linter; dont change doc after DB update (#49907)
2025-10-06 13:34:24 +02:00
ruthra kumar
57f9894f41 Merge pull request #49892 from frappe/mergify/bp/version-14-hotfix/pr-49829
fix: Set paid amount automatically only if return entry validated and has negative grand total (backport #49829)
2025-10-06 12:58:55 +05:30
Nabin Hait
2c383a69f9 fix: resolved conflict 2025-10-06 12:19:22 +05:30
Nabin Hait
b7d76d8fad fix: Set paid amount automatically only if return entry validated and has negative grand total (#49829)
(cherry picked from commit dcbcc596f2)

# Conflicts:
#	erpnext/public/js/controllers/taxes_and_totals.js
2025-10-06 05:58:16 +00:00
mergify[bot]
9b5183e0e5 fix(Common Code): fetch canonical URI from Code List (backport #49882) (#49883)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Common Code): fetch canonical URI from Code List (#49882)
2025-10-04 19:22:04 +02:00
mergify[bot]
0b43d518af refactor(Supplier): custom buttons call make methods (backport #49840) (#49841)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-10-02 00:16:20 +02:00
Frappe PR Bot
a6b490e4b3 chore(release): Bumped to Version 14.91.3
## [14.91.3](https://github.com/frappe/erpnext/compare/v14.91.2...v14.91.3) (2025-09-30)

### Performance Improvements

* reposting for backdated transactions ([3d51c1b](3d51c1b363))
2025-09-30 13:07:25 +00:00
ruthra kumar
a5d33d5665 Merge pull request #49802 from frappe/version-14-hotfix
chore: release v14
2025-09-30 18:36:03 +05:30
Frappe PR Bot
48c3c80383 chore(release): Bumped to Version 14.91.2
## [14.91.2](https://github.com/frappe/erpnext/compare/v14.91.1...v14.91.2) (2025-09-25)

### Performance Improvements

* reposting for backdated transactions ([f3da431](f3da431f1f))
2025-09-25 14:45:52 +00:00
rohitwaghchaure
a9a68f2523 Merge pull request #49726 from frappe/mergify/bp/version-14/pr-49723
perf: reposting for backdated transactions (backport #49720) (backport #49723)
2025-09-25 20:14:23 +05:30
Rohit Waghchaure
f3da431f1f perf: reposting for backdated transactions
(cherry picked from commit 1b0fc0541b)
(cherry picked from commit 3d51c1b363)
2025-09-25 13:22:15 +00:00
rohitwaghchaure
14e92d589f Merge pull request #49723 from frappe/mergify/bp/version-14-hotfix/pr-49720
perf: reposting for backdated transactions (backport #49720)
2025-09-25 18:50:18 +05:30
Rohit Waghchaure
3d51c1b363 perf: reposting for backdated transactions
(cherry picked from commit 1b0fc0541b)
2025-09-25 12:16:23 +00:00
Frappe PR Bot
825ef415ef chore(release): Bumped to Version 14.91.1
## [14.91.1](https://github.com/frappe/erpnext/compare/v14.91.0...v14.91.1) (2025-09-23)

### Bug Fixes

* add condition for name ([0c7911d](0c7911d0fe))
2025-09-23 13:35:10 +00:00
ruthra kumar
f6148c4352 chore: release v14 (#49696)
* fix: add condition for name

(cherry picked from commit cf5a2d6351)

* test: add test to validate user permission in qb

(cherry picked from commit a5b881ea74)

# Conflicts:
#	erpnext/setup/doctype/employee/test_employee.py

---------

Co-authored-by: venkat102 <venkatesharunachalam659@gmail.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2025-09-23 19:03:40 +05:30
ruthra kumar
3c408ff66b Merge pull request #49616 from frappe/mergify/bp/version-14-hotfix/pr-49467
fix: add condition for name (backport #49467)
2025-09-22 10:49:01 +05:30
venkat102
f6bc9fc505 test: add test to validate user permission in qb
(cherry picked from commit a5b881ea74)

# Conflicts:
#	erpnext/setup/doctype/employee/test_employee.py
2025-09-18 16:47:10 +05:30
venkat102
0c7911d0fe fix: add condition for name
(cherry picked from commit cf5a2d6351)
2025-09-18 11:12:13 +00:00
Frappe PR Bot
b8ecc4274f chore(release): Bumped to Version 14.91.0
# [14.91.0](https://github.com/frappe/erpnext/compare/v14.90.1...v14.91.0) (2025-09-16)

### Bug Fixes

* duplicate items being created when fetching items from warehouse in stock reco ([646de0b](646de0bec1))
* remove ignore_permissions ([180f406](180f406917))

### Features

* add permission check for custom button ([42b38b7](42b38b7998))
2025-09-16 14:41:37 +00:00
ruthra kumar
a9b7bc1385 Merge pull request #49565 from frappe/version-14-hotfix
chore: release v14
2025-09-16 20:08:58 +05:30
Mihir Kandoi
d062e50f35 Merge pull request #49515 from frappe/mergify/bp/version-14-hotfix/pr-48456 2025-09-10 10:06:48 +05:30
Mihir Kandoi
646de0bec1 fix: duplicate items being created when fetching items from warehouse in stock reco
(cherry picked from commit 73f6c29559)
2025-09-10 03:01:06 +00:00
Raffael Meyer
02de47c673 Merge pull request #49434 from frappe/mergify/bp/version-14-hotfix/pr-49374
fix: improve permission handling for party link creation (backport #49374)
2025-09-03 17:12:27 +02:00
Marc-Constantin Enke
42b38b7998 feat: add permission check for custom button
(cherry picked from commit 00fd1d2f26)
2025-09-02 17:20:31 +00:00
Marc-Constantin Enke
180f406917 fix: remove ignore_permissions
(cherry picked from commit 7f55f421ab)
2025-09-02 17:20:31 +00:00
Frappe PR Bot
90803b852e chore(release): Bumped to Version 14.90.1
## [14.90.1](https://github.com/frappe/erpnext/compare/v14.90.0...v14.90.1) (2025-09-02)

### Bug Fixes

* add is_cancelled in condition ([b9f9be3](b9f9be3d88))
* ignore cancelled gl and add company filter ([6b29c06](6b29c06511))
* set missing due date in Purchase Invoice and POS Invoice ([#49232](https://github.com/frappe/erpnext/issues/49232)) ([2b6b0b3](2b6b0b32a7))
2025-09-02 13:48:57 +00:00
ruthra kumar
4cbde47ac4 Merge pull request #49424 from frappe/version-14-hotfix
chore: release v14
2025-09-02 19:17:38 +05:30
ruthra kumar
0b3215cd42 Merge pull request #49416 from frappe/mergify/bp/version-14-hotfix/pr-49379
fix: add is_cancelled in condition (backport #49379)
2025-09-02 11:16:44 +05:30
l0gesh29
b9f9be3d88 fix: add is_cancelled in condition
(cherry picked from commit 77a9cf6398)
2025-09-02 05:27:23 +00:00
ruthra kumar
faeedb01a8 Merge pull request #49411 from frappe/mergify/bp/version-14-hotfix/pr-49366
fix(trial-balance-simple): ignore cancelled gl and add company filter (backport #49366)
2025-09-02 10:42:36 +05:30
Raffael Meyer
a2402ddf52 Merge pull request #49233 from frappe/mergify/bp/version-14-hotfix/pr-49232
fix: set missing due date in Purchase Invoice and POS Invoice (backport #49232)
2025-09-02 00:49:37 +02:00
l0gesh29
6b29c06511 fix: ignore cancelled gl and add company filter
(cherry picked from commit afb067ce50)
2025-09-01 11:16:22 +00:00
Frappe PR Bot
2cedd455d9 chore(release): Bumped to Version 14.90.0
# [14.90.0](https://github.com/frappe/erpnext/compare/v14.89.2...v14.90.0) (2025-08-26)

### Bug Fixes

* **dunning:** include accounting dimension upon gl creation ([4fccef0](4fccef0636))
* **payment_entry:** clear party_type when switching to Internal Transfer to avoid 'Supplier None not found' ([e27dd64](e27dd64044))
* **Supplier:** add make_method for Pricing Rule (backport [#49282](https://github.com/frappe/erpnext/issues/49282)) ([#49283](https://github.com/frappe/erpnext/issues/49283)) ([7986e69](7986e69839))

### Features

* add make methods for Bank Account (backport [#49000](https://github.com/frappe/erpnext/issues/49000)) ([#49274](https://github.com/frappe/erpnext/issues/49274)) ([836545b](836545bdb4))
2025-08-26 11:35:26 +00:00
ruthra kumar
ba31f685f8 Merge pull request #49327 from frappe/version-14-hotfix
chore: release v14
2025-08-26 17:01:27 +05:30
ruthra kumar
507d27d509 Merge pull request #49309 from niyati34/fix/payment-entry-clear-party-type-v14hotfix
Fix/payment entry clear party type v14hotfix
2025-08-26 13:27:38 +05:30
niyati34
e27dd64044 fix(payment_entry): clear party_type when switching to Internal Transfer to avoid 'Supplier None not found' 2025-08-25 19:49:05 +05:30
ruthra kumar
7f617a54d1 Merge pull request #49278 from aerele/dunning-accouting-dimension
fix(dunning): include accounting dimension upon gl creation
2025-08-25 16:56:35 +05:30
mergify[bot]
7986e69839 fix(Supplier): add make_method for Pricing Rule (backport #49282) (#49283)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Supplier): add make_method for Pricing Rule (#49282)
2025-08-22 19:26:10 +02:00
mergify[bot]
836545bdb4 feat: add make methods for Bank Account (backport #49000) (#49274)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-08-22 19:17:44 +02:00
ravibharathi656
4fccef0636 fix(dunning): include accounting dimension upon gl creation 2025-08-22 12:34:39 +05:30
Raffael Meyer
2b6b0b32a7 fix: set missing due date in Purchase Invoice and POS Invoice (#49232)
(cherry picked from commit 77478303fe)
2025-08-19 12:30:46 +00:00
Frappe PR Bot
dac192a210 chore(release): Bumped to Version 14.89.2
## [14.89.2](https://github.com/frappe/erpnext/compare/v14.89.1...v14.89.2) (2025-08-19)

### Bug Fixes

* formatted string for disabled filter in get_income_account ([1c24bed](1c24bedaf6))
* handle empty loyalty point details ([0d6be69](0d6be69ce5))
* include missing cint import ([ea454ef](ea454ef770))
* sanitize column name for inventory_dimensions in get_stock_balance ([c3ebc39](c3ebc39f3b))
* use query builder instead of raw SQL in get_blanket_orders ([9d06e09](9d06e093a6))
* use query builder instead of raw SQL in get_loyalty_details ([64e6d65](64e6d65c00))
* use query builder instead of raw SQL in get_material_requests_based_on_supplier ([5a0e690](5a0e690307))
* use query builder instead of raw SQL in get_rfq_containing_supplier ([4b643fe](4b643feb92))
* use query builder instead of raw SQL in get_timesheet_detail_rate ([22d7bbb](22d7bbb081))
* use query builder instead of raw SQL in unset_existing_data ([06f04ca](06f04cad3e))
2025-08-19 11:53:42 +00:00
ruthra kumar
8421e09a95 Merge pull request #49226 from frappe/version-14-hotfix
chore: release v14
2025-08-19 17:22:16 +05:30
Diptanil Saha
43a723546d Merge pull request #49220 from frappe/mergify/bp/version-14-hotfix/pr-49192
fix: improve queries with query builder and input sanitization (backport #49192)
2025-08-19 11:51:32 +05:30
diptanilsaha
ea454ef770 fix: include missing cint import 2025-08-19 11:27:55 +05:30
diptanilsaha
0d6be69ce5 fix: handle empty loyalty point details
(cherry picked from commit 1231ca17c9)
2025-08-19 05:25:23 +00:00
diptanilsaha
22d7bbb081 fix: use query builder instead of raw SQL in get_timesheet_detail_rate
(cherry picked from commit e563ed0c75)
2025-08-19 05:25:23 +00:00
diptanilsaha
4b643feb92 fix: use query builder instead of raw SQL in get_rfq_containing_supplier
(cherry picked from commit 7f2a52ff71)
2025-08-19 05:25:22 +00:00
diptanilsaha
06f04cad3e fix: use query builder instead of raw SQL in unset_existing_data
(cherry picked from commit 7fa4ed6139)
2025-08-19 05:25:22 +00:00
diptanilsaha
c3ebc39f3b fix: sanitize column name for inventory_dimensions in get_stock_balance
(cherry picked from commit eb22794f14)
2025-08-19 05:25:22 +00:00
diptanilsaha
9d06e093a6 fix: use query builder instead of raw SQL in get_blanket_orders
(cherry picked from commit 1db135262d)
2025-08-19 05:25:22 +00:00
diptanilsaha
1c24bedaf6 fix: formatted string for disabled filter in get_income_account
(cherry picked from commit 6320f7290f)
2025-08-19 05:25:21 +00:00
diptanilsaha
5a0e690307 fix: use query builder instead of raw SQL in get_material_requests_based_on_supplier
(cherry picked from commit de919568b4)
2025-08-19 05:25:21 +00:00
diptanilsaha
64e6d65c00 fix: use query builder instead of raw SQL in get_loyalty_details
(cherry picked from commit 8696ba2f5d)
2025-08-19 05:25:21 +00:00
Frappe PR Bot
e7915b31ce chore(release): Bumped to Version 14.89.1
## [14.89.1](https://github.com/frappe/erpnext/compare/v14.89.0...v14.89.1) (2025-08-12)

### Bug Fixes

* add condition to fetch active accounts ([8fc8aa2](8fc8aa2dfd))
* nonetype error on applying presentation_currency filter on financial statements and trial balance report ([89d00ee](89d00ee4a2))
* **purchase invoice:** filter only enabled account ([e0d9a47](e0d9a47ff7))
* **tax withholding details:** avoid voucher duplication ([92ee871](92ee871b79))
* timeout while submitting purchase receipt ([06c3839](06c3839abc))
2025-08-12 12:02:50 +00:00
ruthra kumar
b4200c5453 Merge pull request #49117 from frappe/version-14-hotfix
chore: release v14
2025-08-12 17:31:29 +05:30
ruthra kumar
2f4bfa77b2 Merge pull request #48998 from frappe/mergify/bp/version-14-hotfix/pr-48761
fix: prevent gain or loss entry cancellation upon reposting (backport #48761)
2025-08-12 16:44:09 +05:30
Vignesh S
5eeaaf4757 chore: fix text case failure casued by mergify 2025-08-12 16:25:59 +05:30
ruthra kumar
8faabb8110 Merge pull request #49115 from frappe/mergify/bp/version-14-hotfix/pr-48909
fix(tax withholding details): avoid voucher duplication (backport #48909)
2025-08-12 16:07:00 +05:30
ravibharathi656
92ee871b79 fix(tax withholding details): avoid voucher duplication
(cherry picked from commit 8837016243)
2025-08-12 09:31:36 +00:00
MochaMind
67dad765dc chore: release v14 (#49057)
* fix: timeout while submitting purchase receipt

(cherry picked from commit c433943c46)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.json

* chore: fix conflicts

* fix: nonetype error on applying presentation_currency filter on financial statements and trial balance report

(cherry picked from commit d7e22de44c)

* fix(purchase invoice): filter only enabled account

(cherry picked from commit c3111db6e2)

* fix: add condition to fetch active accounts

(cherry picked from commit 7c8dd86a35)

* chore: add back filter

(cherry picked from commit 23308f6d10)

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
Co-authored-by: diptanilsaha <diptanil@frappe.io>
Co-authored-by: mithili <mithili15602@gamil.com>
Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
2025-08-11 11:50:29 +05:30
Mihir Kandoi
25ff9e0a4d Merge pull request #49048 from frappe/mergify/bp/version-14-hotfix/pr-48813
fix(purchase invoice): filter only enabled account (backport #48813)
2025-08-08 12:00:55 +05:30
mithili
a230a0d94c chore: add back filter
(cherry picked from commit 23308f6d10)
2025-08-08 05:25:01 +00:00
mithili
8fc8aa2dfd fix: add condition to fetch active accounts
(cherry picked from commit 7c8dd86a35)
2025-08-08 05:25:01 +00:00
mithili
e0d9a47ff7 fix(purchase invoice): filter only enabled account
(cherry picked from commit c3111db6e2)
2025-08-08 05:25:01 +00:00
rohitwaghchaure
9d0034f0a4 Merge pull request #49018 from frappe/mergify/bp/version-14-hotfix/pr-49010
fix: timeout while submitting purchase receipt (backport #49010)
2025-08-07 12:28:30 +05:30
Diptanil Saha
f3d780c5bc Merge pull request #49024 from frappe/mergify/bp/version-14-hotfix/pr-49023
fix: NoneType error on applying presentation_currency filter on financial statements and trial balance report (backport #49023)
2025-08-07 02:31:03 +05:30
diptanilsaha
89d00ee4a2 fix: nonetype error on applying presentation_currency filter on financial statements and trial balance report
(cherry picked from commit d7e22de44c)
2025-08-06 20:41:33 +00:00
rohitwaghchaure
22e63099ee chore: fix conflicts 2025-08-06 22:24:45 +05:30
Rohit Waghchaure
06c3839abc fix: timeout while submitting purchase receipt
(cherry picked from commit c433943c46)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
2025-08-06 14:35:43 +00:00
Frappe PR Bot
a7d13d580c chore(release): Bumped to Version 14.89.0
# [14.89.0](https://github.com/frappe/erpnext/compare/v14.88.4...v14.89.0) (2025-08-06)

### Bug Fixes

* add doctype fieldname in condition ([c263e6d](c263e6d67e))
* add flt to prevent NoneType errors ([2c98081](2c98081be6))
* closing balance being added twice to fifo queue ([7abc4c4](7abc4c4022))
* do not split round off when there is a cost center allocation ([388b5fb](388b5fb8f6))
* payment ledger voucher seperator row currencies ([0de4477](0de4477ddf))
* provide company for outstanding record. ([235f271](235f271729))
* provide missing `company` in report records that require reference to `Company:company:default_currency` ([d38fd07](d38fd0779c))
* Use correct Attachments folder in code list import ([f415bc3](f415bc3d14))

### Features

* add show_amount_in_company_currency in gl report ([eb69122](eb691226d5))
2025-08-06 02:35:47 +00:00
ruthra kumar
dd9dc29fe5 Merge pull request #48980 from frappe/version-14-hotfix
chore: release v14
2025-08-06 08:04:22 +05:30
Logesh Periyasamy
b3035ec7d4 Merge pull request #48761 from aerele/exchange-gain-or-loss-on-repost
fix: prevent gain or loss entry cancellation upon reposting
(cherry picked from commit a8d17b7590)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2025-08-06 07:44:42 +05:30
ruthra kumar
0ecc056a3f Merge pull request #48996 from frappe/mergify/bp/version-14-hotfix/pr-48901
fix: do not split round off when there is a cost center allocation (backport #48901)
2025-08-05 20:55:34 +05:30
ravibharathi656
7a9150aac0 test: add test for cost center allocation commercial rounding
(cherry picked from commit dd24cce509)

# Conflicts:
#	erpnext/accounts/doctype/cost_center_allocation/test_cost_center_allocation.py
2025-08-05 20:35:21 +05:30
venkat102
388b5fb8f6 fix: do not split round off when there is a cost center allocation
(cherry picked from commit f0df41d521)
2025-08-05 20:35:18 +05:30
ruthra kumar
96a1a4a8b8 Merge pull request #48984 from frappe/mergify/bp/version-14-hotfix/pr-48798
feat: add show_amount_in_company_currency in gl report (backport #48798)
2025-08-05 17:44:27 +05:30
l0gesh29
eb691226d5 feat: add show_amount_in_company_currency in gl report
(cherry picked from commit 468e5e9b2e)

# Conflicts:
#	erpnext/accounts/report/general_ledger/general_ledger.js
2025-08-05 17:11:33 +05:30
Mihir Kandoi
00e61a531a Merge pull request #48986 from mihir-kandoi/st45290
fix: closing balance being added twice to fifo queue in stock ageing report
2025-08-05 15:48:38 +05:30
Mihir Kandoi
7abc4c4022 fix: closing balance being added twice to fifo queue 2025-08-05 15:25:25 +05:30
Mihir Kandoi
1ae3fd3e27 Merge pull request #48966 from frappe/mergify/bp/version-14-hotfix/pr-48693
fix: Use correct Attachments folder in code list import (backport #48693)
2025-08-05 14:29:16 +05:30
ruthra kumar
ade44fbdb4 Merge pull request #48970 from frappe/mergify/bp/version-14-hotfix/pr-48861
chore: correct description for `consider_party_ledger_amount` in Tax Withholding Category (backport #48861)
2025-08-05 14:26:25 +05:30
ljain112
82e8fb8a5e chore: correct description for consider_party_ledger_amount in Tax Withholding Category
(cherry picked from commit f619bca2d6)

# Conflicts:
#	erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.json
2025-08-05 14:24:38 +05:30
Corentin Forler
f415bc3d14 fix: Use correct Attachments folder in code list import
(cherry picked from commit bc2cb1737a)
2025-08-05 08:34:37 +00:00
ruthra kumar
5bc3273460 Merge pull request #48963 from frappe/mergify/bp/version-14-hotfix/pr-48860
fix: add doctype fieldname in condition (backport #48860)
2025-08-05 13:09:37 +05:30
l0gesh29
c263e6d67e fix: add doctype fieldname in condition
(cherry picked from commit e2d63e4c32)

# Conflicts:
#	erpnext/accounts/utils.py
2025-08-05 12:16:33 +05:30
ruthra kumar
11b5a81170 Merge pull request #48927 from pps190/backport/version-14-hotfix/48926
fix: provide missing company in report records that require reference to Company:company:default_currency (Backport #48926)
2025-08-04 10:29:49 +05:30
Mihir Kandoi
27485b9472 Merge pull request #48329 from pps190/backport/version-14-hotfix/34909
Get incoming rate v14 fix (Backport #34909)
2025-08-02 22:09:30 +05:30
Devin Slauenwhite
0de4477ddf fix: payment ledger voucher seperator row currencies 2025-08-02 12:29:52 -04:00
Devin Slauenwhite
235f271729 fix: provide company for outstanding record. 2025-08-02 12:23:32 -04:00
Devin Slauenwhite
d38fd0779c fix: provide missing company in report records that require reference to Company:company:default_currency 2025-08-02 12:03:40 -04:00
Mihir Kandoi
093c6bb17e Merge pull request #48907 from frappe/st45332
fix: add flt to prevent NoneType errors
2025-08-01 17:07:50 +05:30
Mihir Kandoi
2c98081be6 fix: add flt to prevent NoneType errors 2025-08-01 16:39:56 +05:30
Frappe PR Bot
e5c821a822 chore(release): Bumped to Version 14.88.4
## [14.88.4](https://github.com/frappe/erpnext/compare/v14.88.3...v14.88.4) (2025-07-29)

### Bug Fixes

* import get_link_to_form from utils ([b43fbf2](b43fbf2a7d))
* include empty values in user permission ([4d12ae0](4d12ae069e))
* incorrect GL entries ([493c8ce](493c8ce04e))
* post gl entry on completion date of asset repair ([80ae982](80ae9820f0))
* resolved conflicts ([6cdc781](6cdc7811b8))
* resolved conflicts ([4524c74](4524c74968))
2025-07-29 15:11:30 +00:00
ruthra kumar
500ffbab09 Merge pull request #48831 from frappe/version-14-hotfix
chore: release v14
2025-07-29 20:40:08 +05:30
ruthra kumar
451326fdeb Merge pull request #48846 from frappe/mergify/bp/version-14-hotfix/pr-48835
fix: include empty values in user permission (backport #48835)
2025-07-29 20:17:18 +05:30
l0gesh29
4d12ae069e fix: include empty values in user permission
(cherry picked from commit f13d98fc7c)
2025-07-29 14:26:33 +00:00
Khushi Rawat
4297c58e5e Merge pull request #48834 from frappe/mergify/bp/version-14-hotfix/pr-48833
fix: post gl entry on completion date of asset repair (backport #48833)
2025-07-29 16:57:02 +05:30
Khushi Rawat
b43fbf2a7d fix: import get_link_to_form from utils 2025-07-29 15:48:41 +05:30
Khushi Rawat
6cdc7811b8 fix: resolved conflicts 2025-07-29 15:42:00 +05:30
Khushi Rawat
59ac7aeb23 chore: resolved conflicts 2025-07-29 15:41:20 +05:30
Khushi Rawat
4524c74968 fix: resolved conflicts 2025-07-29 15:39:10 +05:30
khushi8112
80ae9820f0 fix: post gl entry on completion date of asset repair
(cherry picked from commit 5a82b723c2)

# Conflicts:
#	erpnext/assets/doctype/asset_repair/asset_repair.json
#	erpnext/assets/doctype/asset_repair/asset_repair.py
#	erpnext/assets/doctype/asset_repair/test_asset_repair.py
2025-07-29 10:07:22 +00:00
rohitwaghchaure
5d92f38bbe Merge pull request #48807 from frappe/mergify/bp/version-14-hotfix/pr-48801
fix: incorrect GL entries (backport #48801)
2025-07-28 17:54:00 +05:30
rohitwaghchaure
a944eaf054 chore: fix conflicts 2025-07-28 16:35:39 +05:30
Rohit Waghchaure
493c8ce04e fix: incorrect GL entries
(cherry picked from commit 4c273fcc99)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
2025-07-28 10:58:37 +00:00
Frappe PR Bot
a711cd7a18 chore(release): Bumped to Version 14.88.3
## [14.88.3](https://github.com/frappe/erpnext/compare/v14.88.2...v14.88.3) (2025-07-23)

### Bug Fixes

* add validation for account key ([360f3b7](360f3b7c25))
* calculate due date based on payment term ([#46416](https://github.com/frappe/erpnext/issues/46416)) ([9e7a5bb](9e7a5bb1bb))
* performance issue while submitting the purchase invoice ([4fe09fd](4fe09fd7e8))
* **period closing voucher:** closing account head debit and debit in account currency should be equal ([76a233e](76a233e1b7))
* **production plan:** add company filter to sub assembly warehouse ([8934adf](8934adfef4))
* show amount for exchange gain or loss account ([581221f](581221f1ec))
2025-07-23 02:50:52 +00:00
ruthra kumar
942aca31f2 Merge pull request #48746 from frappe/version-14-hotfix
chore: release v14
2025-07-23 08:19:35 +05:30
ruthra kumar
77ea06dc7d Merge pull request #48740 from frappe/mergify/bp/version-14-hotfix/pr-48665
fix: show amount for exchange gain or loss account (backport #48665)
2025-07-22 12:56:31 +05:30
l0gesh29
360f3b7c25 fix: add validation for account key
(cherry picked from commit b6da350c20)
2025-07-22 06:44:03 +00:00
l0gesh29
581221f1ec fix: show amount for exchange gain or loss account
(cherry picked from commit 4f90f50eb2)
2025-07-22 06:44:03 +00:00
rohitwaghchaure
e0be83caa5 Merge pull request #48728 from frappe/mergify/bp/version-14-hotfix/pr-48704
fix(production plan): add company filter to sub assembly warehouse (backport #48704)
2025-07-21 20:04:07 +05:30
ravibharathi656
8934adfef4 fix(production plan): add company filter to sub assembly warehouse
(cherry picked from commit 1728a95111)
2025-07-21 14:27:40 +00:00
Frappe PR Bot
259251dfab chore(release): Bumped to Version 14.88.2
## [14.88.2](https://github.com/frappe/erpnext/compare/v14.88.1...v14.88.2) (2025-07-17)

### Bug Fixes

* calculate due date based on payment term ([#46416](https://github.com/frappe/erpnext/issues/46416)) ([9ce357f](9ce357f3bf))
2025-07-17 11:18:43 +00:00
rohitwaghchaure
f8c54f0a9b Merge pull request #48660 from frappe/mergify/bp/version-14/pr-48638
fix: calculate due date based on payment term (backport #46416) (backport #48638)
2025-07-17 16:47:21 +05:30
Sudharsanan Ashok
9ce357f3bf fix: calculate due date based on payment term (#46416)
(cherry picked from commit 9e808c832f)
(cherry picked from commit 9e7a5bb1bb)
2025-07-17 10:45:07 +00:00
Marica
2d6f4740be Merge pull request #48638 from frappe/mergify/bp/version-14-hotfix/pr-46416
fix: calculate due date based on payment term (backport #46416)
2025-07-16 17:18:04 +02:00
Frappe PR Bot
a3b38d9a91 chore(release): Bumped to Version 14.88.1
## [14.88.1](https://github.com/frappe/erpnext/compare/v14.88.0...v14.88.1) (2025-07-16)

### Bug Fixes

* **period closing voucher:** closing account head debit and debit in account currency should be equal ([18eea34](18eea3425c))
2025-07-16 15:09:51 +00:00
ruthra kumar
ed2e8c2cc6 Merge pull request #48640 from frappe/mergify/bp/version-14/pr-48615
fix(period closing voucher): closing account head debit and debit in account currency should be equal (backport #48615)
2025-07-16 20:38:16 +05:30
venkat102
18eea3425c fix(period closing voucher): closing account head debit and debit in account currency should be equal
(cherry picked from commit 76a233e1b7)
2025-07-16 14:46:15 +00:00
ruthra kumar
7aaea9f5b6 Merge pull request #48615 from aerele/backport-48612
fix(period closing voucher): closing account head debit and debit in account currency should be equal
2025-07-16 20:13:11 +05:30
Sudharsanan Ashok
9e7a5bb1bb fix: calculate due date based on payment term (#46416)
(cherry picked from commit 9e808c832f)
2025-07-16 14:40:15 +00:00
rohitwaghchaure
27105501fb Merge pull request #48636 from frappe/mergify/bp/version-14-hotfix/pr-48633
fix: performance issue while submitting the purchase invoice (backport #48633)
2025-07-16 17:10:28 +05:30
Rohit Waghchaure
4fe09fd7e8 fix: performance issue while submitting the purchase invoice
(cherry picked from commit 47979871de)
2025-07-16 11:16:37 +00:00
venkat102
76a233e1b7 fix(period closing voucher): closing account head debit and debit in account currency should be equal 2025-07-15 18:24:54 +05:30
Frappe PR Bot
bda447f20a chore(release): Bumped to Version 14.88.0
# [14.88.0](https://github.com/frappe/erpnext/compare/v14.87.0...v14.88.0) (2025-07-15)

### Bug Fixes

* **Employee:** add context to status in List View (backport [#48576](https://github.com/frappe/erpnext/issues/48576)) ([#48578](https://github.com/frappe/erpnext/issues/48578)) ([9dad082](9dad08274a))

### Features

* parent item group support in Stock Projected Qty report ([3b36be2](3b36be214f))
* update the modified date of the SLE after reposting ([8966c95](8966c956d5))
2025-07-15 12:50:14 +00:00
ruthra kumar
7db420cf9f Merge pull request #48601 from frappe/version-14-hotfix
chore: release v14
2025-07-15 18:18:44 +05:30
ruthra kumar
5ddfe3ce1d Merge pull request #48585 from frappe/mergify/bp/version-14-hotfix/pr-47892
refactor: use sql for building voucher balance in Receivable report (backport #47892)
2025-07-15 08:23:20 +05:30
ruthra kumar
ff998572e7 chore: resolve conflicts 2025-07-15 08:03:48 +05:30
ruthra kumar
f364a41490 chore: rename method
(cherry picked from commit fc8ca7d82c)

# Conflicts:
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
2025-07-15 01:52:45 +00:00
ruthra kumar
804edad233 refactor: build and pass match conditions as qb criterion
(cherry picked from commit 7efeed54de)

# Conflicts:
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
#	erpnext/accounts/utils.py
2025-07-15 01:52:45 +00:00
ruthra kumar
e533158a1c chore: drop unused utility method
(cherry picked from commit 52c0df24e3)
2025-07-15 01:52:45 +00:00
ruthra kumar
5bcf642dff refactor: dynamic DB field types
(cherry picked from commit 9d0ebe3427)

# Conflicts:
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
2025-07-15 01:52:44 +00:00
ruthra kumar
d7822f493b refactor: better variable name
(cherry picked from commit 1a90c0d031)
2025-07-15 01:52:44 +00:00
ruthra kumar
5188745c53 refactor: prefix-ed names for easy distinction
(cherry picked from commit c5e35cc330)
2025-07-15 01:52:44 +00:00
ruthra kumar
006a8c71fd refactor: utility to drop existing procedures and include cost center
(cherry picked from commit da32bb5f51)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.js
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.py
2025-07-15 01:52:44 +00:00
ruthra kumar
ba25d334b1 refactor: order by posting date
(cherry picked from commit 7b7440d44a)
2025-07-15 01:52:43 +00:00
ruthra kumar
dd1020ccfb refactor: call procedures based on config
(cherry picked from commit e90c6a33bd)

# Conflicts:
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
2025-07-15 01:52:43 +00:00
ruthra kumar
de2f80811f refactor: introduce sql option for data fetch
(cherry picked from commit 8cf8f6abad)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.py
2025-07-15 01:52:43 +00:00
ruthra kumar
12eaa64572 refactor: better readability
(cherry picked from commit 097e74979f)
2025-07-15 01:52:42 +00:00
ruthra kumar
da1dcb8b21 refactor: using sql procedures for AR report
- dynamic filters are passed

(cherry picked from commit e5920c57aa)

# Conflicts:
#	erpnext/accounts/report/accounts_receivable/accounts_receivable.py
2025-07-15 01:52:42 +00:00
mergify[bot]
9dad08274a fix(Employee): add context to status in List View (backport #48576) (#48578)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Employee): add context to status in List View (#48576)
2025-07-14 15:53:42 +02:00
rohitwaghchaure
d8d53bc43e Merge pull request #48496 from frappe/mergify/bp/version-14-hotfix/pr-48490
feat: update the modified date of the SLE after reposting (backport #48490)
2025-07-09 19:45:26 +05:30
Rohit Waghchaure
8966c956d5 feat: update the modified date of the SLE after reposting
(cherry picked from commit c2cd4934e7)
2025-07-09 13:52:11 +00:00
rohitwaghchaure
a518fc080a Merge pull request #48491 from frappe/mergify/bp/version-14-hotfix/pr-48488
feat: parent item group support in Stock Projected Qty report (backport #48488)
2025-07-09 18:59:55 +05:30
Rohit Waghchaure
3b36be214f feat: parent item group support in Stock Projected Qty report
(cherry picked from commit 6e80d89d13)
2025-07-09 11:19:41 +00:00
Frappe PR Bot
20af226947 chore(release): Bumped to Version 14.87.0
# [14.87.0](https://github.com/frappe/erpnext/compare/v14.86.5...v14.87.0) (2025-07-08)

### Bug Fixes

* fetch from parent optional in inventory dimension ([bb901ca](bb901cab88))
* incorrect backport ([94a17b6](94a17b6ec2))

### Features

* Period-wise closing entries for TB (backport [#39712](https://github.com/frappe/erpnext/issues/39712)) ([#48386](https://github.com/frappe/erpnext/issues/48386)) ([711e06b](711e06b537))

### Reverts

* do not convert exchange gain/loss amount to foreign currency ([083402e](083402e9a8))
* Revert "fix: stock reco qty with inventory dimension ([#47918](https://github.com/frappe/erpnext/issues/47918))" ([9207d79](9207d79ce6))
2025-07-08 12:54:12 +00:00
ruthra kumar
7f26b1d5a2 Merge pull request #48461 from frappe/version-14-hotfix
chore: release v14
2025-07-08 18:22:45 +05:30
ruthra kumar
c332fcdeff Merge pull request #48458 from frappe/mergify/bp/version-14-hotfix/pr-48361
revert: do not convert exchange gain/loss amount to foreign currency (backport #48361)
2025-07-08 15:45:19 +05:30
mergify[bot]
51adea3b89 refactor: remove do_reposting_for_each_stock_transaction feature (backport #48444) (#48451)
* refactor: remove do_reposting_for_each_stock_transaction feature

Co-authored-by: Mihir Kandoi <kandoimihir@gmail.com>
2025-07-08 15:06:00 +05:30
venkat102
083402e9a8 revert: do not convert exchange gain/loss amount to foreign currency
(cherry picked from commit c17ae703c7)

# Conflicts:
#	erpnext/accounts/report/general_ledger/test_general_ledger.py
2025-07-08 14:26:24 +05:30
rohitwaghchaure
1116a0fc8e Merge pull request #48442 from frappe/mergify/bp/version-14-hotfix/pr-48441
Revert "fix: stock reco qty with inventory dimension" (backport #48441)
2025-07-08 12:30:58 +05:30
rohitwaghchaure
b15d7e573e chore: fix conflicts 2025-07-08 10:45:49 +05:30
rohitwaghchaure
9207d79ce6 Revert "fix: stock reco qty with inventory dimension (#47918)"
This reverts commit 342cebc778.

(cherry picked from commit 8ba66c9833)

# Conflicts:
#	erpnext/stock/doctype/stock_reconciliation/stock_reconciliation.py
2025-07-08 05:07:53 +00:00
rohitwaghchaure
33eb72035b Merge pull request #48433 from frappe/mergify/bp/version-14-hotfix/pr-48432
fix: fetch from parent optional in inventory dimension (backport #48432)
2025-07-08 10:13:56 +05:30
rohitwaghchaure
2c6099e051 Merge pull request #48438 from rohitwaghchaure/fixed-sales-incoming-rate-issue
fix: incorrect backport
2025-07-08 09:55:06 +05:30
rohitwaghchaure
5f4aaed5a0 chore: fix conflicts 2025-07-08 08:34:16 +05:30
Rohit Waghchaure
94a17b6ec2 fix: incorrect backport 2025-07-08 08:32:12 +05:30
Rohit Waghchaure
bb901cab88 fix: fetch from parent optional in inventory dimension
(cherry picked from commit 8aac6a6b18)

# Conflicts:
#	erpnext/stock/doctype/inventory_dimension/inventory_dimension.json
2025-07-07 11:52:53 +00:00
Diptanil Saha
711e06b537 feat: Period-wise closing entries for TB (backport #39712) (#48386)
feat: Period-wise closing entries for TB

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2025-07-03 22:47:28 +05:30
Diptanil Saha
c54b65acc2 chore: fix flaky test in Tax Withholding Details (backport #48375) (#48387)
* fix(test): flaky budget test case

* chore(test): import get_accumulated_monthly_budget

* fix(test): tds_payable_monthly tests

---------

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2025-07-03 22:09:19 +05:30
Frappe PR Bot
179b8c7c61 chore(release): Bumped to Version 14.86.5
## [14.86.5](https://github.com/frappe/erpnext/compare/v14.86.4...v14.86.5) (2025-07-01)

### Bug Fixes

* accounting entries for standalone credit notes ([15ae019](15ae0196c6))
* add validation for exchange gain/loss entries ([b98cce8](b98cce8b9a))
* do not allow backdated transactions against serial numbers. ([#48281](https://github.com/frappe/erpnext/issues/48281)) ([945bdab](945bdabebb))
2025-07-01 11:59:12 +00:00
ruthra kumar
b107387dda Merge pull request #48337 from frappe/version-14-hotfix
chore: release v14
2025-07-01 17:27:40 +05:30
ruthra kumar
9fcca18bf3 Merge pull request #48334 from frappe/mergify/bp/version-14-hotfix/pr-48162
fix: add validation for exchange gain/loss entries (backport #48162)
2025-07-01 16:20:45 +05:30
i-am-vimal
b98cce8b9a fix: add validation for exchange gain/loss entries
(cherry picked from commit 5c9eddd31e)

# Conflicts:
#	erpnext/accounts/report/utils.py
2025-07-01 15:36:51 +05:30
Hossein Yousefian
bd9655a781 get_incoming_rate_voucher_no_fix 2025-06-30 17:11:04 -04:00
Hossein Yousefian
1df3b608ec get_incoming_rate_zero_in_rate_fix 2025-06-30 17:11:04 -04:00
rohitwaghchaure
62b7a8d21a Merge pull request #48313 from frappe/mergify/bp/version-14-hotfix/pr-48310
fix: accounting entries for standalone credit notes (backport #48310)
2025-06-30 10:09:23 +05:30
rohitwaghchaure
6b31e54891 chore: fix conflicts 2025-06-30 09:42:13 +05:30
Rohit Waghchaure
15ae0196c6 fix: accounting entries for standalone credit notes
(cherry picked from commit 52177cffcd)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
2025-06-30 04:09:39 +00:00
Frappe PR Bot
a06d705d75 chore(release): Bumped to Version 14.86.4
## [14.86.4](https://github.com/frappe/erpnext/compare/v14.86.3...v14.86.4) (2025-06-27)

### Bug Fixes

* do not allow backdated transactions against serial numbers. ([#48281](https://github.com/frappe/erpnext/issues/48281)) ([1393100](1393100a62))
2025-06-27 06:27:09 +00:00
rohitwaghchaure
9e3e3182f2 Merge pull request #48290 from frappe/mergify/bp/version-14/pr-48281
fix: do not allow backdated transactions against serial numbers. (backport #48281)
2025-06-27 11:55:38 +05:30
rohitwaghchaure
1393100a62 fix: do not allow backdated transactions against serial numbers. (#48281)
(cherry picked from commit 945bdabebb)
2025-06-27 06:03:52 +00:00
rohitwaghchaure
945bdabebb fix: do not allow backdated transactions against serial numbers. (#48281) 2025-06-27 11:33:03 +05:30
Frappe PR Bot
f07594b863 chore(release): Bumped to Version 14.86.3
## [14.86.3](https://github.com/frappe/erpnext/compare/v14.86.2...v14.86.3) (2025-06-24)

### Bug Fixes

* get already billed amount from current doc instead of database ([#48079](https://github.com/frappe/erpnext/issues/48079)) ([0790db7](0790db79fd))
2025-06-24 14:08:14 +00:00
ruthra kumar
25a382ec24 Merge pull request #48241 from frappe/version-14-hotfix
chore: release v14
2025-06-24 19:36:37 +05:30
ruthra kumar
d7c47e8ea5 Merge pull request #48234 from frappe/mergify/bp/version-14-hotfix/pr-48079
fix: get already billed amount from current doc instead of database (backport #48079)
2025-06-24 17:36:05 +05:30
ljain112
2627fb10ce chore: resolve conflicts 2025-06-24 16:14:24 +05:30
Lakshit Jain
0790db79fd fix: get already billed amount from current doc instead of database (#48079)
* fix: get already billed amount from current doc instead of database

* fix: throw overbilling validation for all items in single call

* refactor: minor fixes

---------

Co-authored-by: Sagar Vora <16315650+sagarvora@users.noreply.github.com>
(cherry picked from commit 47c3c4808e)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2025-06-24 10:11:43 +00:00
Frappe PR Bot
0dad2acfc8 chore(release): Bumped to Version 14.86.2
## [14.86.2](https://github.com/frappe/erpnext/compare/v14.86.1...v14.86.2) (2025-06-17)

### Bug Fixes

* incorrect warehouse set from SO to MR ([fbfc6a6](fbfc6a6f62))
2025-06-17 14:36:59 +00:00
ruthra kumar
193042ef07 Merge pull request #48099 from frappe/version-14-hotfix
chore: release v14
2025-06-17 20:05:31 +05:30
rohitwaghchaure
8208a9ec27 Merge pull request #48064 from frappe/mergify/bp/version-14-hotfix/pr-48061
fix: incorrect warehouse set from SO to MR (backport #48061)
2025-06-16 14:52:54 +05:30
Rohit Waghchaure
fbfc6a6f62 fix: incorrect warehouse set from SO to MR
(cherry picked from commit 0da8d9c869)
2025-06-16 04:42:26 +00:00
Frappe PR Bot
e9f9eaa2d0 chore(release): Bumped to Version 14.86.1
## [14.86.1](https://github.com/frappe/erpnext/compare/v14.86.0...v14.86.1) (2025-06-10)

### Bug Fixes

* available qty in BOM Stock Report ([186173a](186173a21e))
* incorrect warehouse in MR ([2cac05e](2cac05e56c))
* key-error for COGS By Item Group report (backport [#47914](https://github.com/frappe/erpnext/issues/47914)) ([#47916](https://github.com/frappe/erpnext/issues/47916)) ([f5ef376](f5ef376486))
* stock adjustment entry during reposting (backport [#47878](https://github.com/frappe/erpnext/issues/47878)) ([#47882](https://github.com/frappe/erpnext/issues/47882)) ([c9eeca2](c9eeca22f5))
* stock reco qty with inventory dimension (backport [#47918](https://github.com/frappe/erpnext/issues/47918)) ([#47921](https://github.com/frappe/erpnext/issues/47921)) ([6397c36](6397c366fd))
* throw permission error ([#47976](https://github.com/frappe/erpnext/issues/47976)) ([96c937b](96c937bf6a))
2025-06-10 14:31:53 +00:00
ruthra kumar
08d40ddb9b Merge pull request #47997 from frappe/version-14-hotfix
chore: release v14
2025-06-10 20:00:21 +05:30
rohitwaghchaure
d60ab92082 Merge pull request #48003 from frappe/mergify/bp/version-14-hotfix/pr-47998
fix: incorrect warehouse in MR (backport #47998)
2025-06-10 18:54:18 +05:30
rohitwaghchaure
85a0581145 chore: fix conflicts 2025-06-10 18:20:28 +05:30
Rohit Waghchaure
2cac05e56c fix: incorrect warehouse in MR
(cherry picked from commit 2b9ca79291)

# Conflicts:
#	erpnext/manufacturing/doctype/production_plan/production_plan.py
2025-06-10 12:41:16 +00:00
ruthra kumar
10e4e610db Merge pull request #47993 from frappe/mergify/bp/version-14-hotfix/pr-47981
refactor(Work Order): query_sales_order (backport #47981)
2025-06-10 15:01:22 +05:30
barredterra
9ab80cfd6c refactor(Work Order): query_sales_order
- Use `get_list` instead of `db.sql_list`

    The method is used for setting link options in the frontend and the Link field doesn't ignore permissions, so get_list should be fine here.

- Added type hints to enable argument validation

(cherry picked from commit 2dbdacf905)
2025-06-10 09:03:13 +00:00
rohitwaghchaure
8f2b83d434 Merge pull request #47986 from frappe/mergify/bp/version-14-hotfix/pr-47942
fix: available qty in BOM Stock Report (backport #47942)
2025-06-10 14:03:06 +05:30
Sagar Vora
7f0ebb37da Merge pull request #47977 from frappe/mergify/bp/version-14-hotfix/pr-47976
fix: throw permission error (backport #47976)
2025-06-10 07:39:53 +00:00
Sagar Vora
1d42c4a305 chore: fix conflicts 2025-06-10 13:08:39 +05:30
Rohit Waghchaure
186173a21e fix: available qty in BOM Stock Report
(cherry picked from commit ea689bbe3f)
2025-06-10 06:50:51 +00:00
Aayush Dalal
96c937bf6a fix: throw permission error (#47976)
Co-authored-by: Sagar Vora <16315650+sagarvora@users.noreply.github.com>
(cherry picked from commit 8b6a8d0c4f)

# Conflicts:
#	erpnext/accounts/doctype/bank_statement_import/bank_statement_import.py
#	erpnext/stock/utils.py
2025-06-09 17:29:42 +00:00
rohitwaghchaure
52aafc9410 Merge pull request #47932 from rohitwaghchaure/fixed-sabb-cond
chore: incorrect condition
2025-06-06 13:13:54 +05:30
Rohit Waghchaure
3232310c0f chore: incorrect condition 2025-06-06 12:30:03 +05:30
mergify[bot]
6397c366fd fix: stock reco qty with inventory dimension (backport #47918) (#47921)
fix: stock reco qty with inventory dimension (#47918)

(cherry picked from commit 342cebc778)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-06-06 09:50:20 +05:30
mergify[bot]
f5ef376486 fix: key-error for COGS By Item Group report (backport #47914) (#47916)
fix: key-error for COGS By Item Group report (#47914)

fix: keyerror for COGS By Item Group report
(cherry picked from commit 997ce4eaa7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-06-05 17:18:22 +05:30
mergify[bot]
c9eeca22f5 fix: stock adjustment entry during reposting (backport #47878) (#47882)
fix: stock adjustment entry during reposting (#47878)

fix: stock adjustment entry
(cherry picked from commit cbcd580daa)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-06-04 12:51:22 +05:30
Frappe PR Bot
b145638eca chore(release): Bumped to Version 14.86.0
# [14.86.0](https://github.com/frappe/erpnext/compare/v14.85.10...v14.86.0) (2025-06-03)

### Bug Fixes

* filter of item for manufacture type material request (backport [#47712](https://github.com/frappe/erpnext/issues/47712)) ([#47716](https://github.com/frappe/erpnext/issues/47716)) ([69463b4](69463b4798))
* incorrect actual qty in product bundle balance report (backport [#47791](https://github.com/frappe/erpnext/issues/47791)) ([#47813](https://github.com/frappe/erpnext/issues/47813)) ([df779bb](df779bb7dd))
* use `query.walk() `for escaping special chars in receiable/payable report ([ca48583](ca4858318e))

### Features

* add column "Item Name" to "BOM Stock Report" (backport [#47116](https://github.com/frappe/erpnext/issues/47116)) ([#47484](https://github.com/frappe/erpnext/issues/47484)) ([b664781](b664781fae))
2025-06-03 11:52:06 +00:00
ruthra kumar
b46fdc2645 Merge pull request #47867 from frappe/version-14-hotfix
chore: release v14
2025-06-03 17:20:36 +05:30
mergify[bot]
df779bb7dd fix: incorrect actual qty in product bundle balance report (backport #47791) (#47813)
fix: incorrect actual qty in product bundle balance report (#47791)

(cherry picked from commit c544c3e018)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-05-30 14:01:49 +05:30
ruthra kumar
20f701ff0b Merge pull request #47807 from frappe/mergify/bp/version-14-hotfix/pr-47794
fix: use `query.walk() `for escaping special chars in receiable/payable report (backport #47794)
2025-05-29 14:58:45 +05:30
ljain112
ca4858318e fix: use query.walk() for escaping special chars in receiable/payable report
(cherry picked from commit a0a51b5074)
2025-05-29 08:21:15 +00:00
mergify[bot]
b664781fae feat: add column "Item Name" to "BOM Stock Report" (backport #47116) (#47484)
Co-authored-by: Patrick Eißler <77415730+PatrickDEissler@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-05-27 19:21:20 +02:00
mergify[bot]
69463b4798 fix: filter of item for manufacture type material request (backport #47712) (#47716)
* fix: filter of item for manufacture type material request (#47712)

(cherry picked from commit 874750f9ce)

# Conflicts:
#	erpnext/stock/doctype/material_request/material_request.js

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-05-27 21:56:36 +05:30
Frappe PR Bot
caf0f2cd19 chore(release): Bumped to Version 14.85.10
## [14.85.10](https://github.com/frappe/erpnext/compare/v14.85.9...v14.85.10) (2025-05-27)

### Bug Fixes

* incorrect status in the serial no ([#47740](https://github.com/frappe/erpnext/issues/47740)) ([d37b12f](d37b12f385))
* incorrect valuation rate due to positive qty (backport [#47686](https://github.com/frappe/erpnext/issues/47686)) ([#47687](https://github.com/frappe/erpnext/issues/47687)) ([d5d4b3a](d5d4b3a7f3))
* only include advances within the tcs period ([43aeff3](43aeff38aa))
* patch to rename group_by filter in custom reports (backport [#47709](https://github.com/frappe/erpnext/issues/47709)) ([#47729](https://github.com/frappe/erpnext/issues/47729)) ([70bcfb4](70bcfb4748))
* rate changing while making PR (negative discount) (backport [#40539](https://github.com/frappe/erpnext/issues/40539)) ([#47735](https://github.com/frappe/erpnext/issues/47735)) ([70e6ea6](70e6ea6b3f))
* remove public access to list items (backport [#45838](https://github.com/frappe/erpnext/issues/45838)) ([5d9be73](5d9be7366b))
* skip last purchase rate for free item (backport [#47693](https://github.com/frappe/erpnext/issues/47693)) ([#47695](https://github.com/frappe/erpnext/issues/47695)) ([1f1cb33](1f1cb338fe))
* validation message format (backport [#47542](https://github.com/frappe/erpnext/issues/47542)) ([#47549](https://github.com/frappe/erpnext/issues/47549)) ([792f3af](792f3afa1b))
2025-05-27 11:46:57 +00:00
ruthra kumar
1cfb002de8 Merge pull request #47757 from frappe/version-14-hotfix
chore: release v14
2025-05-27 17:15:22 +05:30
ruthra kumar
3b686827e9 Merge pull request #47752 from frappe/mergify/bp/version-14-hotfix/pr-47736
fix: only include advances within the tcs period (backport #47736)
2025-05-27 14:10:45 +05:30
rohitwaghchaure
d37b12f385 fix: incorrect status in the serial no (#47740) 2025-05-27 13:23:40 +05:30
ljain112
43aeff38aa fix: only include advances within the tcs period
(cherry picked from commit 477ec9fdcc)
2025-05-27 07:49:16 +00:00
ruthra kumar
ad13dcd695 Merge pull request #47745 from frappe/mergify/bp/version-14-hotfix/pr-47549
fix: validation message format (backport #47542) (backport #47549)
2025-05-27 12:03:44 +05:30
mergify[bot]
792f3afa1b fix: validation message format (backport #47542) (#47549)
fix: validation message format (#47542)

(cherry picked from commit a18e1cffa7)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit f225e1986e)
2025-05-27 06:04:55 +00:00
ruthra kumar
43dda4a5d2 Merge pull request #47741 from frappe/mergify/bp/version-14-hotfix/pr-47697
refactor: Fetch party name for contract (backport #47697)
2025-05-26 19:56:16 +05:30
ruthra kumar
274ce10329 chore: resolve conflicts 2025-05-26 17:46:42 +05:30
ruthra kumar
caf145e3ca refactor: patch old contract with full party name
(cherry picked from commit 8e2221178b)

# Conflicts:
#	erpnext/patches.txt
2025-05-26 12:11:25 +00:00
ruthra kumar
05911ad563 refactor: fetch party name on selection
(cherry picked from commit 752024e222)
2025-05-26 12:11:24 +00:00
ruthra kumar
de937a6bad refactor: full name field in contract
(cherry picked from commit 016924361a)

# Conflicts:
#	erpnext/crm/doctype/contract/contract.json
#	erpnext/crm/doctype/contract/contract.py
2025-05-26 12:11:24 +00:00
mergify[bot]
70e6ea6b3f fix: rate changing while making PR (negative discount) (backport #40539) (#47735)
fix: rate changing while making PR (negative discount) (#40539)

(cherry picked from commit 8136954484)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-05-26 16:02:06 +05:30
mergify[bot]
70bcfb4748 fix: patch to rename group_by filter in custom reports (backport #47709) (#47729)
* fix: patch to rename group_by filter in custom reports

(cherry picked from commit 0d19c18c06)

# Conflicts:
#	erpnext/patches.txt
#	erpnext/patches/v14_0/rename_group_by_to_categorize_by_in_custom_reports.py

* fix: using python instead of sql query

(cherry picked from commit 48eccb1f73)

* chore: resolve conflict

---------

Co-authored-by: diptanilsaha <diptanil@frappe.io>
2025-05-26 13:29:28 +05:30
mergify[bot]
1f1cb338fe fix: skip last purchase rate for free item (backport #47693) (#47695)
fix: skip last purchase rate for free item (#47693)

(cherry picked from commit c3b17024bd)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-05-24 17:17:09 +05:30
mergify[bot]
d5d4b3a7f3 fix: incorrect valuation rate due to positive qty (backport #47686) (#47687)
fix: incorrect valuation rate due to positive qty (#47686)

(cherry picked from commit 6ed97b5fda)

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2025-05-22 16:17:42 +05:30
mergify[bot]
5d9be7366b fix: remove public access to list items (backport #45838)
* fix: remove public access to list items

(cherry picked from commit 2bd596ee3d)

# Conflicts:
#	erpnext/stock/doctype/item/item.json

* fix: resolve conflict

---------

Co-authored-by: CaseSolved <richard@casesolved.co.uk>
Co-authored-by: Sagar Vora <16315650+sagarvora@users.noreply.github.com>
2025-05-21 23:12:40 +05:30
Frappe PR Bot
79a4b597d4 chore(release): Bumped to Version 14.85.9
## [14.85.9](https://github.com/frappe/erpnext/compare/v14.85.8...v14.85.9) (2025-05-20)

### Bug Fixes

* asset image field updation issue (backport [#47615](https://github.com/frappe/erpnext/issues/47615)) ([d88feec](d88feecf46))
* better validation message with solution for BOM recursion (backport [#47472](https://github.com/frappe/erpnext/issues/47472)) ([#47476](https://github.com/frappe/erpnext/issues/47476)) ([537c917](537c917bfc))
* include only invoices with update_stock = 0  for billed amt in delivery note. ([54197ff](54197ff760))
* remove hardcoded doctype in `make_return_doc` ([9ce86b1](9ce86b135b))
2025-05-20 13:53:32 +00:00
ruthra kumar
0b0944cc06 Merge pull request #47635 from frappe/version-14-hotfix
chore: release v14
2025-05-20 19:22:04 +05:30
mergify[bot]
537c917bfc fix: better validation message with solution for BOM recursion (backport #47472) (#47476)
fix: better validation message with solution for BOM recursion

(cherry picked from commit 7103cdd84a)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2025-05-20 16:15:40 +05:30
ruthra kumar
13f393c59a Merge pull request #47624 from frappe/mergify/bp/version-14-hotfix/pr-47559
fix: include only invoices with update_stock = 0  for billed amt in delivery note. (backport #47559)
2025-05-20 11:24:52 +05:30
ljain112
54197ff760 fix: include only invoices with update_stock = 0 for billed amt in delivery note.
(cherry picked from commit 6dc459db58)
2025-05-20 05:31:56 +00:00
ruthra kumar
6f1109226d Merge pull request #47621 from frappe/mergify/bp/version-14-hotfix/pr-47614
fix: remove hardcoded doctype in `make_return_doc` (backport #47614)
2025-05-20 10:37:00 +05:30
barredterra
9ce86b135b fix: remove hardcoded doctype in make_return_doc
(cherry picked from commit 45a5c19dd4)

# Conflicts:
#	erpnext/controllers/sales_and_purchase_return.py
2025-05-20 10:11:21 +05:30
mergify[bot]
d88feecf46 fix: asset image field updation issue (backport #47615) 2025-05-20 10:08:26 +05:30
Frappe PR Bot
271d0a301f chore(release): Bumped to Version 14.85.8
## [14.85.8](https://github.com/frappe/erpnext/compare/v14.85.7...v14.85.8) (2025-05-13)

### Bug Fixes

* broken test suite due to incorrect OR filter ([949ed59](949ed59f84))
* ignore "Account Closing Balance" doctype on Period Closing Voucher cancellation ([a04feff](a04feff264))
* typo in event.js ([2389fd5](2389fd5145))
* warning message for COGS account in the stock entry ([1bbbd26](1bbbd261cb))
2025-05-13 14:02:11 +00:00
ruthra kumar
9d36166616 Merge pull request #47529 from frappe/version-14-hotfix
chore: release v14
2025-05-13 19:30:41 +05:30
ruthra kumar
00407cd0ee Merge pull request #47526 from frappe/mergify/bp/version-14-hotfix/pr-47520
fix: ignore "Account Closing Balance" doctype on Period Closing Voucher cancellation (backport #47520)
2025-05-13 15:22:32 +05:30
ljain112
a04feff264 fix: ignore "Account Closing Balance" doctype on Period Closing Voucher cancellation
(cherry picked from commit d6602d63fc)

# Conflicts:
#	erpnext/accounts/doctype/period_closing_voucher/period_closing_voucher.py
2025-05-13 15:00:36 +05:30
ruthra kumar
d6f5ac90b1 Merge pull request #47516 from frappe/mergify/bp/version-14-hotfix/pr-47367
fix: Use `Currency` instead of `Float` in GL report to show details (backport #47367)
2025-05-13 13:08:20 +05:30
Abdeali Chharchhodawala
c6c1b00559 Merge pull request #47367 from Abdeali099/gl-report-field-float-to-currency
fix: Use `Currency` instead of `Float` in GL report to show details
(cherry picked from commit e4e0bb68ec)
2025-05-13 12:49:52 +05:30
ruthra kumar
b86dc294f1 Merge pull request #47518 from frappe/mergify/bp/version-14-hotfix/pr-47380
fix: broken CI - uae vat 201 tests failing (backport #47380)
2025-05-13 12:45:41 +05:30
ruthra kumar
949ed59f84 fix: broken test suite due to incorrect OR filter
(cherry picked from commit 37d74e387d)
2025-05-13 06:39:22 +00:00
ruthra kumar
558225b027 Merge pull request #47466 from frappe/mergify/bp/version-14-hotfix/pr-47462
Update event.js (backport #47462)
2025-05-08 14:12:55 +05:30
Yaiphalemba Mangshatabam
2389fd5145 fix: typo in event.js
"Sales Partners" -> "Sales Partner"

(cherry picked from commit edee75c757)
2025-05-08 08:40:37 +00:00
rohitwaghchaure
d66a34411c Merge pull request #47453 from frappe/mergify/bp/version-14-hotfix/pr-47452
fix: warning message for COGS account in the stock entry (backport #47452)
2025-05-08 13:58:23 +05:30
Rohit Waghchaure
1bbbd261cb fix: warning message for COGS account in the stock entry
(cherry picked from commit bba6b0ff45)
2025-05-07 10:50:18 +00:00
Frappe PR Bot
182b9892fc chore(release): Bumped to Version 14.85.7
## [14.85.7](https://github.com/frappe/erpnext/compare/v14.85.6...v14.85.7) (2025-05-06)

### Bug Fixes

* backward compatibility for renamed group_by filter on reports (backport [#47362](https://github.com/frappe/erpnext/issues/47362)) ([#47402](https://github.com/frappe/erpnext/issues/47402)) ([378821d](378821d9e6))
* change shipping address fetching condition ([8e0bd97](8e0bd976c3))
* completed transactions showing in the list (backport [#47374](https://github.com/frappe/erpnext/issues/47374)) ([#47378](https://github.com/frappe/erpnext/issues/47378)) ([b507e63](b507e63375))
* do not allocate amount when ref's doctype or name are not set ([f278120](f278120aa0))
* rename unchanged group_by filter related to general ledger report (backport [#47366](https://github.com/frappe/erpnext/issues/47366)) ([#47404](https://github.com/frappe/erpnext/issues/47404)) ([d41fec7](d41fec7d2b))
* renaming group by fieldname and value in reports (backport [#47352](https://github.com/frappe/erpnext/issues/47352)) ([#47359](https://github.com/frappe/erpnext/issues/47359)) ([27a8856](27a8856dca))
* show party type in due date exceeding message ([4376fbc](4376fbc3ed))
* validation for difference account ([150cc5a](150cc5a664))
* warning message before changing the valuation method (backport [#47340](https://github.com/frappe/erpnext/issues/47340)) ([#47341](https://github.com/frappe/erpnext/issues/47341)) ([b13e0a6](b13e0a6b9f))
2025-05-06 14:13:22 +00:00
ruthra kumar
015525599f Merge pull request #47430 from frappe/version-14-hotfix
chore: release v14
2025-05-06 19:41:49 +05:30
mergify[bot]
3993525bf6 feat!: configure which rate is used to auto-update price list (backport #47417) (#47433)
* feat!: configure which rate is used to auto-update price list

(cherry picked from commit 3ebde4526a)

# Conflicts:
#	erpnext/selling/doctype/sales_order/test_sales_order.py
#	erpnext/setup/setup_wizard/operations/defaults_setup.py
#	erpnext/setup/setup_wizard/operations/install_fixtures.py
#	erpnext/stock/doctype/stock_settings/stock_settings.json
#	erpnext/stock/doctype/stock_settings/stock_settings.py
#	erpnext/stock/get_item_details.py

* fix: merge conflicts

---------

Co-authored-by: Sagar Vora <16315650+sagarvora@users.noreply.github.com>
2025-05-06 18:43:27 +05:30
ruthra kumar
8343c92ac5 Merge pull request #47425 from frappe/mergify/bp/version-14-hotfix/pr-47337
fix: do not allocate amount when ref's doctype or name are not set (backport #47337)
2025-05-06 15:01:05 +05:30
Abdeali Chharchhoda
f278120aa0 fix: do not allocate amount when ref's doctype or name are not set
(cherry picked from commit b9a02b466b)
2025-05-06 09:04:52 +00:00
ruthra kumar
862e6330ac Merge pull request #47415 from frappe/mergify/bp/version-14-hotfix/pr-47408
fix: show party type in due date exceeding message (backport #47408)
2025-05-06 14:32:58 +05:30
ruthra kumar
bd395e2406 chore: resolve conflicts and pass all parameters 2025-05-06 14:12:44 +05:30
Abdeali Chharchhoda
4376fbc3ed fix: show party type in due date exceeding message
(cherry picked from commit b6d9134014)

# Conflicts:
#	erpnext/accounts/party.py
2025-05-06 06:28:47 +00:00
ruthra kumar
c49ee563fd Merge pull request #47413 from frappe/mergify/bp/version-14-hotfix/pr-47358
fix: change shipping address fetching condition (backport #47358)
2025-05-06 11:29:16 +05:30
Vimal
8e0bd976c3 fix: change shipping address fetching condition
(cherry picked from commit 0b4add2f2b)
2025-05-06 05:28:40 +00:00
rohitwaghchaure
d66e8e8597 Merge pull request #47389 from frappe/mergify/bp/version-14-hotfix/pr-47376
fix: validation for difference account (backport #47376)
2025-05-05 18:39:04 +05:30
mergify[bot]
d41fec7d2b fix: rename unchanged group_by filter related to general ledger report (backport #47366) (#47404)
* fix: rename unchanged group_by filter related to general ledger report (#47366)

(cherry picked from commit 3de249dcba)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
#	erpnext/accounts/test/test_reports.py
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.js

* chore: resolve conflict

* chore: resolve conflict

* chore: resolve conflict

---------

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2025-05-05 18:18:23 +05:30
mergify[bot]
378821d9e6 fix: backward compatibility for renamed group_by filter on reports (backport #47362) (#47402)
fix: backward compatibility for renamed group_by filter on reports (#47362)

* fix: backward compatibility for renamed group_by filter in general ledger report

* fix: backward compatibility for renamed group_by filter in supplier quotation comparison report

(cherry picked from commit d4ffa54136)

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2025-05-05 18:01:06 +05:30
ruthra kumar
698e260526 Merge pull request #47146 from frappe/mergify/copy/version-14-hotfix/pr-47145
refactor: make AR / AP report more memory efficient (copy #47145)
2025-05-05 15:43:33 +05:30
ruthra kumar
fc793f0f25 refactor: set default for fetch methods 2025-05-05 15:04:48 +05:30
ruthra kumar
204d1d6a53 refactor: use fetch method based on configuration 2025-05-05 15:04:48 +05:30
ruthra kumar
aee917b790 refactor: configurable fetch method for AR / AP report 2025-05-05 15:04:45 +05:30
ruthra kumar
892d3980d3 refactor: use unbuffered cursor for fetching 2025-05-05 14:59:24 +05:30
rohitwaghchaure
e743d5f66b chore: fix linters issue 2025-05-05 14:19:20 +05:30
rohitwaghchaure
9adb863787 chore: fix linters issue 2025-05-05 14:12:07 +05:30
Rohit Waghchaure
150cc5a664 fix: validation for difference account
(cherry picked from commit fb819c558e)
2025-05-03 07:52:53 +00:00
mergify[bot]
b507e63375 fix: completed transactions showing in the list (backport #47374) (#47378)
* fix: completed transactions showing in the list (#47374)

(cherry picked from commit 97db9da10e)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/stock_entry.js

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-05-02 15:29:10 +05:30
mergify[bot]
27a8856dca fix: renaming group by fieldname and value in reports (backport #47352) (#47359)
* fix: renaming group by fieldname and value in reports (#47352)

* fix: renaming in general ledger report

* fix: renaming in supplier quotation comparison report

* fix: renaming group by to categorize by in process statement of accounts

* fix: added patch

* fix: patch update to all documents

* chore: added patches to patch.txt

* chore: removing patch from v14

(cherry picked from commit 13a84e7f82)

# Conflicts:
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.json
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
#	erpnext/accounts/report/general_ledger/general_ledger.py
#	erpnext/buying/report/supplier_quotation_comparison/supplier_quotation_comparison.py
#	erpnext/patches.txt
#	erpnext/patches/v14_0/rename_group_by_to_categorize_by.py

* chore: resolve conflict

* chore: resolve conflict

* chore: resolve conflict

* chore: resolve conflict

* chore: resolve conflict

* chore: resolve conflict

* chore: fixed path for patch file

---------

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2025-04-30 18:22:59 +05:30
mergify[bot]
b13e0a6b9f fix: warning message before changing the valuation method (backport #47340) (#47341)
fix: warning message before changing the valuation method (#47340)

(cherry picked from commit ffdc4347e8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2025-04-30 12:54:15 +05:30
Frappe PR Bot
04bb4f8415 chore(release): Bumped to Version 14.85.6
## [14.85.6](https://github.com/frappe/erpnext/compare/v14.85.5...v14.85.6) (2025-04-29)

### Bug Fixes

* allow to change valuation method from FIFO to Moving Average ([7130e5c](7130e5ccfb))
* calculate useful days of asset's life correctly for existing asset ([#47066](https://github.com/frappe/erpnext/issues/47066)) ([0bc3bc4](0bc3bc4851))
* item code not showing in the error message ([48748e7](48748e7142))
* remove invalid email account creation (backport [#47318](https://github.com/frappe/erpnext/issues/47318)) ([#47322](https://github.com/frappe/erpnext/issues/47322)) ([0c5c344](0c5c34409e))
2025-04-29 13:08:31 +00:00
ruthra kumar
6735ba0ab6 Merge pull request #47327 from frappe/version-14-hotfix
chore: release v14
2025-04-29 18:36:51 +05:30
mergify[bot]
0c5c34409e fix: remove invalid email account creation (backport #47318) (#47322)
fix: remove invalid email account creation (#47318)

(cherry picked from commit 7423e4187f)

Co-authored-by: Diptanil Saha <diptanil@frappe.io>
2025-04-29 12:40:25 +05:30
rohitwaghchaure
9dbc1cc5fb Merge pull request #47287 from frappe/mergify/bp/version-14-hotfix/pr-47268
fix: allow to change valuation method from FIFO to Moving Average (backport #47268)
2025-04-28 15:28:53 +05:30
Rohit Waghchaure
7130e5ccfb fix: allow to change valuation method from FIFO to Moving Average
(cherry picked from commit b454ed4b8f)
2025-04-28 09:06:30 +00:00
rohitwaghchaure
0e42516977 Merge pull request #47258 from rohitwaghchaure/fixed-support-46933
fix: item code not showing in the error message
2025-04-25 14:38:38 +05:30
Rohit Waghchaure
48748e7142 fix: item code not showing in the error message 2025-04-25 14:08:38 +05:30
Khushi Rawat
0bc3bc4851 fix: calculate useful days of asset's life correctly for existing asset (#47066)
* fix: calculate useful days of asset's life correctly for existing asset

* fix: test

* fix: test case correction
2025-04-23 12:30:59 +05:30
Frappe PR Bot
d791108649 chore(release): Bumped to Version 14.85.5
## [14.85.5](https://github.com/frappe/erpnext/compare/v14.85.4...v14.85.5) (2025-04-22)

### Bug Fixes

* create default warehouse ([#47125](https://github.com/frappe/erpnext/issues/47125)) ([a766aa0](a766aa0837))
* rate based on posting date in Tax Withholding Report ([17dc87a](17dc87a2df))
* respect mapped accounting dimensions ([e4c2442](e4c2442ba2))
2025-04-22 13:45:53 +00:00
ruthra kumar
0d84059fde Merge pull request #47205 from frappe/version-14-hotfix
chore: release v14
2025-04-22 19:14:23 +05:30
ruthra kumar
6868da5f6a Merge pull request #47198 from frappe/mergify/bp/version-14-hotfix/pr-47138
fix: rate based on posting date in Tax Withholding Report (backport #47138)
2025-04-22 14:07:19 +05:30
ljain112
f906568fea chore: added test case for date period in multiple tax withholding rules
(cherry picked from commit 515fe340a8)

# Conflicts:
#	erpnext/accounts/report/tds_payable_monthly/test_tds_payable_monthly.py
2025-04-22 13:33:16 +05:30
ljain112
17dc87a2df fix: rate based on posting date in Tax Withholding Report
(cherry picked from commit a32a79e90a)
2025-04-22 07:59:50 +00:00
Sagar Vora
522597d22b Merge pull request #47156 from frappe/mergify/bp/version-14-hotfix/pr-47154
fix: respect mapped accounting dimensions (backport #47154)
2025-04-19 13:03:56 +05:30
Sagar Vora
e4c2442ba2 fix: respect mapped accounting dimensions
(cherry picked from commit 7dbe27da19)
2025-04-19 07:22:23 +00:00
mergify[bot]
0d9bc4424c chore: migrate pre-commit config (backport #47132) (#47133)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-04-17 14:22:23 +02:00
Raffael Meyer
35c9375f0d Merge pull request #47130 from frappe/mergify/bp/version-14-hotfix/pr-47125
fix: create default warehouse (backport #47125)
2025-04-17 13:56:56 +02:00
barredterra
f04c73b9c2 ci: update linters
copy config from version-15
2025-04-17 13:38:19 +02:00
Raffael Meyer
a766aa0837 fix: create default warehouse (#47125) 2025-04-17 13:38:10 +02:00
Frappe PR Bot
3248415667 chore(release): Bumped to Version 14.85.4
## [14.85.4](https://github.com/frappe/erpnext/compare/v14.85.3...v14.85.4) (2025-04-16)

### Bug Fixes

* correct doctype in item_wise_purchase register ([6ec33c0](6ec33c0098))
* go for lower case "on" because we already have translations for that ([056cc35](056cc35379))
* make report's "printed on" translatable ([f1a8643](f1a864349e))
* **Payment Entry:** set account type if missing (backport [#47069](https://github.com/frappe/erpnext/issues/47069)) (backport [#47070](https://github.com/frappe/erpnext/issues/47070)) ([#47072](https://github.com/frappe/erpnext/issues/47072)) ([b88f6c1](b88f6c1252))
* remove redundant letter head ([033fa09](033fa09eb4))
* revert [#46900](https://github.com/frappe/erpnext/issues/46900) - against_voucher filter in general ledger ([5844aaf](5844aafd12))
* serial no validation for stock reconciliation ([a3d4d34](a3d4d34454))
* stock entry repack amount calculation ([253a067](253a067592))
* update the modified date in for SLEs and GLs after rename ([8801584](8801584c8d))

### Performance Improvements

* stock ageing report generation ([7a74dac](7a74dac2c2))
2025-04-16 04:02:43 +00:00
ruthra kumar
4fb12754ce Merge pull request #47090 from frappe/version-14-hotfix
chore: release v14
2025-04-16 09:31:20 +05:30
ruthra kumar
503b89a764 Merge pull request #46952 from frappe/mergify/bp/version-14-hotfix/pr-46949
fix: improve translatability of query report print formats (backport #46913) (backport #46949)
2025-04-15 15:59:10 +05:30
mergify[bot]
b88f6c1252 fix(Payment Entry): set account type if missing (backport #47069) (backport #47070) (#47072)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
fix(Payment Entry): set account type if missing (backport #47069) (#47070)
fix(Payment Entry): set account type if missing (#47069)
2025-04-14 19:19:50 +02:00
rohitwaghchaure
e5156e6666 Merge pull request #47068 from frappe/mergify/bp/version-14-hotfix/pr-46997
fix: update the modified date in for SLEs and GLs after rename (backport #46997)
2025-04-14 21:06:08 +05:30
Rohit Waghchaure
8801584c8d fix: update the modified date in for SLEs and GLs after rename
(cherry picked from commit dc5a5ef258)
2025-04-14 15:02:22 +00:00
rohitwaghchaure
55ac96ff09 Merge pull request #47062 from frappe/mergify/bp/version-14-hotfix/pr-46853
fix: stock entry repack amount calculation (backport #46853)
2025-04-14 20:30:38 +05:30
rohitwaghchaure
3f3fb323cf chore: fix conflicts 2025-04-14 18:02:24 +05:30
Rohit Waghchaure
253a067592 fix: stock entry repack amount calculation
(cherry picked from commit 544ceb93cd)

# Conflicts:
#	erpnext/stock/stock_ledger.py
2025-04-14 12:30:21 +00:00
Frappe PR Bot
d8f301f1db chore(release): Bumped to Version 14.85.3
## [14.85.3](https://github.com/frappe/erpnext/compare/v14.85.2...v14.85.3) (2025-04-14)

### Bug Fixes

* revert [#46900](https://github.com/frappe/erpnext/issues/46900) - against_voucher filter in general ledger ([27ecd3a](27ecd3a21b))
2025-04-14 08:24:00 +00:00
ruthra kumar
6d65c967da Merge pull request #47056 from frappe/mergify/bp/version-14/pr-47049
Revert "fix: remove against_voucher and against_voucher_type column from General Ledger Report" (backport #47049)
2025-04-14 13:52:35 +05:30
ruthra kumar
4ac5c7e5e7 Merge pull request #47054 from frappe/mergify/bp/version-14-hotfix/pr-47049
Revert "fix: remove against_voucher and against_voucher_type column from General Ledger Report" (backport #47049)
2025-04-14 13:51:45 +05:30
ruthra kumar
911014a54e chore: resolve conflict 2025-04-14 13:27:13 +05:30
ruthra kumar
694f158fc8 chore: resolve conflict 2025-04-14 13:25:36 +05:30
ruthra kumar
27ecd3a21b fix: revert #46900 - against_voucher filter in general ledger
(cherry picked from commit adb331ef71)

# Conflicts:
#	erpnext/accounts/report/general_ledger/general_ledger.py
2025-04-14 07:50:45 +00:00
ruthra kumar
5844aafd12 fix: revert #46900 - against_voucher filter in general ledger
(cherry picked from commit adb331ef71)

# Conflicts:
#	erpnext/accounts/report/general_ledger/general_ledger.py
2025-04-14 07:49:35 +00:00
Frappe PR Bot
e684807bc7 chore(release): Bumped to Version 14.85.2
## [14.85.2](https://github.com/frappe/erpnext/compare/v14.85.1...v14.85.2) (2025-04-12)

### Bug Fixes

* correct doctype in item_wise_purchase register ([0e1045e](0e1045e855))
2025-04-12 02:03:19 +00:00
ruthra kumar
3af506e0a9 Merge pull request #47030 from frappe/mergify/bp/version-14/pr-47012
fix: correct doctype in item_wise_purchase register (backport #47012)
2025-04-12 07:31:49 +05:30
ruthra kumar
98ffbfb432 Merge pull request #47032 from frappe/mergify/bp/version-14-hotfix/pr-47012
fix: correct doctype in item_wise_purchase register (backport #47012)
2025-04-12 07:29:28 +05:30
ljain112
6ec33c0098 fix: correct doctype in item_wise_purchase register
(cherry picked from commit b8b8dce733)
2025-04-12 01:41:16 +00:00
ljain112
0e1045e855 fix: correct doctype in item_wise_purchase register
(cherry picked from commit b8b8dce733)
2025-04-12 01:41:12 +00:00
Frappe PR Bot
34d3f58149 chore(release): Bumped to Version 14.85.1
## [14.85.1](https://github.com/frappe/erpnext/compare/v14.85.0...v14.85.1) (2025-04-10)

### Bug Fixes

* serial no validation for stock reconciliation ([c388b75](c388b7579c))

### Performance Improvements

* stock ageing report generation ([eaa2974](eaa297475f))
2025-04-10 06:02:52 +00:00
rohitwaghchaure
efd34817be Merge pull request #46986 from frappe/mergify/bp/version-14/pr-46971
fix: serial no validation for stock reconciliation (backport #46971)
2025-04-10 11:31:22 +05:30
rohitwaghchaure
124ad729ab Merge pull request #46984 from frappe/mergify/bp/version-14/pr-46983
perf: stock ageing report generation (backport #46983)
2025-04-10 11:31:13 +05:30
Rohit Waghchaure
c388b7579c fix: serial no validation for stock reconciliation
(cherry picked from commit a3d4d34454)
2025-04-10 05:36:45 +00:00
rohitwaghchaure
a2595350f6 Merge pull request #46971 from rohitwaghchaure/fixed-support-35746
fix: serial no validation for stock reconciliation
2025-04-10 11:05:45 +05:30
Rohit Waghchaure
eaa297475f perf: stock ageing report generation
(cherry picked from commit 7a74dac2c2)
2025-04-10 05:34:42 +00:00
rohitwaghchaure
ac7700dff0 Merge pull request #46983 from rohitwaghchaure/fixed-stock-ageing-report
perf: stock ageing report generation
2025-04-10 11:03:40 +05:30
Rohit Waghchaure
7a74dac2c2 perf: stock ageing report generation 2025-04-10 10:10:09 +05:30
Rohit Waghchaure
a3d4d34454 fix: serial no validation for stock reconciliation 2025-04-09 17:14:40 +05:30
barredterra
443ed5b2ce chore: add missing german translation
(cherry picked from commit d94ebd0c78)
2025-04-08 14:12:41 +00:00
barredterra
033fa09eb4 fix: remove redundant letter head
(cherry picked from commit 7896f8a855)
2025-04-08 14:12:41 +00:00
barredterra
056cc35379 fix: go for lower case "on" because we already have translations for that
(cherry picked from commit 7cf83ffce7)
2025-04-08 14:12:40 +00:00
barredterra
f1a864349e fix: make report's "printed on" translatable
(cherry picked from commit 18e9a9881c)
2025-04-08 14:12:40 +00:00
Frappe PR Bot
24681bd64f chore(release): Bumped to Version 14.85.0
# [14.85.0](https://github.com/frappe/erpnext/compare/v14.84.0...v14.85.0) (2025-04-08)

### Bug Fixes

* **accounting:** update outstanding amount based on update_outstanding_for_self ([8e2bfc6](8e2bfc6bcb))
* don't filter payment entries on Bank Account in Payment Clearance ([576ce7e](576ce7e882))
* empty party filter on change of party type in General Ledger Report. ([14b4d14](14b4d147a8))
* improved rounding adjustment when applying discount (backport [#46720](https://github.com/frappe/erpnext/issues/46720)) ([06c3299](06c32993ea))
* incorrect condition ([d1f9444](d1f9444be7))
* make message translatable (backport [#46863](https://github.com/frappe/erpnext/issues/46863)) ([#46865](https://github.com/frappe/erpnext/issues/46865)) ([70d117e](70d117e858))
* **payment term:** allocate payment amount when payment term is fetched from order ([36b951d](36b951d018))
* remove against_voucher from General Ledger Report ([9e3a041](9e3a04136c))
* removed customer_group query in customer.js ([3be0f00](3be0f00b3b))
* Translate UnReconcile dialog title (backport [#46818](https://github.com/frappe/erpnext/issues/46818)) ([#46862](https://github.com/frappe/erpnext/issues/46862)) ([5f467be](5f467be0c8))
* update outstanding with precision ([698d5be](698d5be840))
* update payment amount if automatically_fetch_payment_terms is enabled ([dda35b8](dda35b8e51))
* update posting date before running validations ([430d1e8](430d1e8b2e))
* use `grand_total_diff` instead of `rounding_adjustment` in `taxes_and_totals` (backport [#46829](https://github.com/frappe/erpnext/issues/46829)) ([233e0d8](233e0d8049))
* user permissions in sales and purchase report ([f26b22e](f26b22ee7f))

### Features

* asset filter in asset depreciation and balances report ([#46848](https://github.com/frappe/erpnext/issues/46848)) ([2fe9fa7](2fe9fa7ef7))
2025-04-08 13:05:14 +00:00
ruthra kumar
b0c742b64e Merge pull request #46941 from frappe/version-14-hotfix
chore: release v14
2025-04-08 18:33:42 +05:30
mergify[bot]
18282b2632 chore: fix german translations (backport #46912) (#46914)
* chore: fix german translations (#46912)

(cherry picked from commit 8276e8e8b3)

# Conflicts:
#	erpnext/translations/de.csv

* chore: resolve conflicts

* chore: delete duplicate translations

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-04-08 13:16:35 +02:00
ruthra kumar
46115d6f71 Merge pull request #46937 from frappe/mergify/bp/version-14-hotfix/pr-46631
fix: update outstanding for self (backport #46631)
2025-04-08 16:21:45 +05:30
ruthra kumar
f62905f7a7 chore: pass individual range 2025-04-08 15:53:30 +05:30
ruthra kumar
88facb7523 refactor: pass both doctype and name 2025-04-08 15:13:59 +05:30
ruthra kumar
512877ab46 chore: resolve conflicts 2025-04-08 14:34:59 +05:30
Bhavan23
c7e6b2356f test: add unit test to validate outstanding amount for update_outstanding_for_self checkbox enabled
(cherry picked from commit 7b0882600a)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2025-04-08 08:59:05 +00:00
Bhavan23
8e2bfc6bcb fix(accounting): update outstanding amount based on update_outstanding_for_self
fix(accounting): against voucher has been already paid show proper message and update update_outstanding_for_self as 1

(cherry picked from commit 222f1834f1)

# Conflicts:
#	erpnext/controllers/accounts_controller.py
2025-04-08 08:59:04 +00:00
ruthra kumar
98260b990c Merge pull request #46931 from frappe/mergify/bp/version-14-hotfix/pr-46821
fix: removed customer_group query in customer.js (backport #46821)
2025-04-08 13:10:04 +05:30
ljain112
3be0f00b3b fix: removed customer_group query in customer.js
(cherry picked from commit f49adfdd98)
2025-04-08 07:28:33 +00:00
ruthra kumar
f44478db78 Merge pull request #46924 from frappe/mergify/bp/version-14-hotfix/pr-46709
fix: user permissions in sales and purchase report (backport #46709)
2025-04-08 11:53:08 +05:30
ruthra kumar
db8cb70bd8 chore: resolve conflict 2025-04-08 11:13:44 +05:30
ljain112
f26b22ee7f fix: user permissions in sales and purchase report
(cherry picked from commit f4bc1dfd00)

# Conflicts:
#	erpnext/accounts/report/purchase_register/purchase_register.py
2025-04-08 05:40:47 +00:00
ruthra kumar
1e4807f16d Merge pull request #46920 from frappe/mergify/bp/version-14-hotfix/pr-46804
fix: update outstanding with precision (backport #46804)
2025-04-08 11:07:45 +05:30
ljain112
698d5be840 fix: update outstanding with precision
(cherry picked from commit aadda9f606)
2025-04-08 04:29:31 +00:00
ruthra kumar
59e46e22d3 Merge pull request #46904 from frappe/mergify/bp/version-14-hotfix/pr-46895
fix: empty party filter on change of party type in General Ledger Report (backport #46895)
2025-04-07 17:55:56 +05:30
ljain112
14b4d147a8 fix: empty party filter on change of party type in General Ledger Report.
(cherry picked from commit 9c68bc22fa)
2025-04-07 12:12:55 +00:00
ruthra kumar
2bed1c8336 Merge pull request #46901 from frappe/mergify/bp/version-14-hotfix/pr-46900
fix: remove against_voucher and against_voucher_type column from General Ledger Report (backport #46900)
2025-04-07 17:38:42 +05:30
ljain112
9e3a04136c fix: remove against_voucher from General Ledger Report
(cherry picked from commit 6d1f119a0f)
2025-04-07 17:14:49 +05:30
ruthra kumar
dcc53cea55 Merge pull request #46896 from frappe/mergify/bp/version-14-hotfix/pr-46728
fix: update posting date before running validations (backport #46728)
2025-04-07 14:54:37 +05:30
Dany Robert
430d1e8b2e fix: update posting date before running validations
(cherry picked from commit d04dbd8ed9)
2025-04-07 09:01:56 +00:00
ruthra kumar
36a366d962 Merge pull request #46890 from frappe/mergify/bp/version-14-hotfix/pr-46637
fix(payment term): allocate payment amount when payment term is fetched from order (backport #46637)
2025-04-07 11:25:58 +05:30
venkat102
dda35b8e51 fix: update payment amount if automatically_fetch_payment_terms is enabled
(cherry picked from commit 7bf1a39861)
2025-04-07 05:34:19 +00:00
venkat102
4e0d7d88ec test: validate payment schedule based on invoice amount
(cherry picked from commit 7785296573)
2025-04-07 05:34:19 +00:00
venkat102
36b951d018 fix(payment term): allocate payment amount when payment term is fetched from order
(cherry picked from commit 5618859bd8)
2025-04-07 05:34:18 +00:00
mergify[bot]
233e0d8049 fix: use grand_total_diff instead of rounding_adjustment in taxes_and_totals (backport #46829)
* fix: use `grand_total_diff` instead of `rounding_adjustment` in `taxes_and_totals`

(cherry picked from commit fd252da6b1)

* test: ensure correct grand total

---------

Co-authored-by: vishakhdesai <vishakhdesai@gmail.com>
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2025-04-06 09:11:06 +05:30
mergify[bot]
5f467be0c8 fix: Translate UnReconcile dialog title (backport #46818) (#46862)
fix: Translate UnReconcile dialog title

(cherry picked from commit f2cfb03c2c)

Co-authored-by: Corentin Forler <corentin@dokos.io>
2025-04-05 17:37:16 +02:00
mergify[bot]
70d117e858 fix: make message translatable (backport #46863) (#46865)
fix: make message translatable (#46863)

(cherry picked from commit 7d12e9afd4)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2025-04-05 17:36:16 +02:00
Khushi Rawat
2fe9fa7ef7 feat: asset filter in asset depreciation and balances report (#46848) 2025-04-04 10:39:16 +05:30
Sagar Vora
b4ca51ad4c Merge pull request #46813 from frappe/mergify/bp/version-14-hotfix/pr-46812
fix: revert resetting `rounding_adjustment` (backport #46812)
2025-03-31 15:56:27 +05:30
Vishakh Desai
fb5777cf10 Merge pull request #46812 from vishakhdesai/fix-taxes-and-totals
fix: revert resetting `rounding_adjustment`
(cherry picked from commit 3a9dca0563)
2025-03-31 10:25:00 +00:00
mergify[bot]
06c32993ea fix: improved rounding adjustment when applying discount (backport #46720)
* fix: improved rounding adjustment when applying discount (#46720)

* fix: rounding adjustment in apply_discount_amount taxes_and_totals

* refactor: minor changes

* fix: set the rounding difference while calculating tax total in the last tax row and add test case

* fix: failing test case

* fix: made changes in get_total_for_discount_amount in taxes_and_totals

* fix: failing test cases

* fix: changes as per review

* refactor: remove unnecessary use of flt

* refactor: improve logic

* refactor: minor change

* refactor: minor changes

* fix: add a test case for applying discount with previous row total in taxes

* fix: failing test case

* refactor: flatter code, remove `flt` usage for accuracy

---------

Co-authored-by: Vishakh Desai <78500008+vishakhdesai@users.noreply.github.com>
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2025-03-31 15:54:09 +05:30
rohitwaghchaure
466c6ee3d4 Merge pull request #46780 from frappe/mergify/bp/version-14-hotfix/pr-46777
fix: incorrect condition (backport #46777)
2025-03-29 12:17:59 +05:30
rohitwaghchaure
a8831351e3 chore: fix conflicts 2025-03-29 12:16:17 +05:30
Rohit Waghchaure
d1f9444be7 fix: incorrect condition
(cherry picked from commit 0c1a8e9c58)

# Conflicts:
#	erpnext/public/js/controllers/transaction.js
2025-03-28 18:19:41 +00:00
rohitwaghchaure
ceaea16d84 Merge pull request #46751 from frappe/mergify/bp/version-14/pr-46748
Revert "perf: timeout while renaming cost center (backport #46641)" (backport #46748)
2025-03-27 13:13:59 +05:30
rohitwaghchaure
119f2e7074 Revert "perf: timeout while renaming cost center (backport #46641)"
(cherry picked from commit da6affbba7)
2025-03-27 06:53:19 +00:00
rohitwaghchaure
9cadb89678 Merge pull request #46748 from frappe/revert-46646-mergify/bp/version-14-hotfix/pr-46641
Revert "perf: timeout while renaming cost center (backport #46641)"
2025-03-27 12:16:56 +05:30
rohitwaghchaure
da6affbba7 Revert "perf: timeout while renaming cost center (backport #46641)" 2025-03-27 11:57:24 +05:30
Sagar Vora
6293b08540 Merge pull request #46729 from vishakhdesai/bank-clearance-fix-v14-backport
fix: don't filter payment entries on Bank Account in Payment Clearance (backport #46669)
2025-03-26 13:00:57 +05:30
vishakhdesai
576ce7e882 fix: don't filter payment entries on Bank Account in Payment Clearance 2025-03-26 11:41:35 +05:30
Frappe PR Bot
67d7ffa430 chore(release): Bumped to Version 14.84.0
# [14.84.0](https://github.com/frappe/erpnext/compare/v14.83.4...v14.84.0) (2025-03-25)

### Bug Fixes

* assign dialog instance to a variable in update_child_items function ([690a939](690a939572))
* customer credit limit check based on `bypass_credit_limit_check` in Journal Entry ([331ecc1](331ecc1964))
* do not validate if conversion rate is 1 for different currency ([c3447c0](c3447c030a))
* fix lint issues with trailing whitespaces ([df64d2e](df64d2ef4e))
* removed test case ([509c5c4](509c5c4d17))

### Features

* repost accounting ledger for purchase receipt ([88e664b](88e664b79f))

### Performance Improvements

* timeout while renaming cost center ([b9b08c3](b9b08c35ef))
2025-03-25 12:25:57 +00:00
ruthra kumar
d90c8a9150 Merge pull request #46714 from frappe/version-14-hotfix
chore: release v14
2025-03-25 17:54:27 +05:30
ruthra kumar
15bb1fdb24 Merge pull request #46712 from frappe/mergify/bp/version-14-hotfix/pr-46616
fix: do not validate if conversion rate is 1 for different currency (backport #46616)
2025-03-25 16:06:08 +05:30
ljain112
509c5c4d17 fix: removed test case 2025-03-25 15:22:19 +05:30
ruthra kumar
cb028b8740 chore: resolve conflict 2025-03-25 14:26:14 +05:30
ljain112
c3447c030a fix: do not validate if conversion rate is 1 for different currency
(cherry picked from commit e8a66d03bc)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2025-03-25 08:42:17 +00:00
ruthra kumar
1d65f995e7 Merge pull request #46646 from frappe/mergify/bp/version-14-hotfix/pr-46641
perf: timeout while renaming cost center (backport #46641)
2025-03-25 13:27:09 +05:30
rohitwaghchaure
736b125e14 chore: fix conflicts 2025-03-22 20:49:56 +05:30
Rohit Waghchaure
b9b08c35ef perf: timeout while renaming cost center
(cherry picked from commit 92be7cbbbf)

# Conflicts:
#	erpnext/accounts/doctype/gl_entry/gl_entry.json
2025-03-21 12:38:52 +00:00
Frappe PR Bot
7e8d2dc0fc chore(release): Bumped to Version 14.83.4
## [14.83.4](https://github.com/frappe/erpnext/compare/v14.83.3...v14.83.4) (2025-03-19)

### Bug Fixes

* fetch quality inspection parameter group ([6e497f7](6e497f73f1))
* not able to make PR against stand alone Debit Note ([16fe53b](16fe53b8c7))
* order by condition ([af3089b](af3089b96e))
* repost future sle and gle after capitalization ([#46576](https://github.com/frappe/erpnext/issues/46576)) ([805549f](805549f793))
* set stock adjustment account in difference account ([6f0c67a](6f0c67a242))
* **Transaction Deletion Record:** sql syntax error while fetching lead address ([20b43b4](20b43b4d93))
2025-03-19 11:04:55 +00:00
ruthra kumar
39af6bd143 Merge pull request #46581 from frappe/version-14-hotfix
chore: release v14
2025-03-19 16:33:27 +05:30
Frappe PR Bot
609bfaefba chore(release): Bumped to Version 14.83.3
## [14.83.3](https://github.com/frappe/erpnext/compare/v14.83.2...v14.83.3) (2025-03-12)

### Bug Fixes

* **account:** update account number from parent company ([1f54c27](1f54c272ac))
* not able to save work order with alternative item ([6ca1f9b](6ca1f9bc73))
2025-03-12 14:13:24 +00:00
ruthra kumar
2546589b4c Merge pull request #46445 from frappe/version-14-hotfix
chore: release v14
2025-03-12 19:41:47 +05:30
Frappe PR Bot
b404f00ece chore(release): Bumped to Version 14.83.2
## [14.83.2](https://github.com/frappe/erpnext/compare/v14.83.1...v14.83.2) (2025-03-05)

### Bug Fixes

* Add permission check in POS's `Toggle Recent Orders` (backport [#46010](https://github.com/frappe/erpnext/issues/46010)) ([#46273](https://github.com/frappe/erpnext/issues/46273)) ([557a05b](557a05b0ad))
* auto allocation for negative amount outstanding for Customers in Payment Entry ([8e02dcf](8e02dcfcaa))
* change voucher_type and voucher_no field type to data ([df4f4d9](df4f4d9a31))
* consolidate gl entries by project in General Ledger Report (backport [#46314](https://github.com/frappe/erpnext/issues/46314)) ([#46320](https://github.com/frappe/erpnext/issues/46320)) ([b3b7e62](b3b7e62a90))
* do not include opening invoices in billed items to be received report ([cedf577](cedf577b4c))
* don't allow renaming account while system is actively in use (backport [#46176](https://github.com/frappe/erpnext/issues/46176)) ([#46209](https://github.com/frappe/erpnext/issues/46209)) ([167069b](167069b823))
* exclude cancelled gl entries ([369a692](369a692af9))
* incorrect batch picked in the pick list ([ac25d3e](ac25d3e1c4))
* incorrectly billed amount in the purchase receipt ([ca94ad3](ca94ad3a24))
* inventory dimension for maintence visit ([69a8e0d](69a8e0dfac))
* only include submitted docs for internal received quantity validation (backport [#46262](https://github.com/frappe/erpnext/issues/46262)) ([#46303](https://github.com/frappe/erpnext/issues/46303)) ([90b5f0b](90b5f0b7bf))
* **patch:** Ensure SLE indexes (backport [#46131](https://github.com/frappe/erpnext/issues/46131)) ([#46134](https://github.com/frappe/erpnext/issues/46134)) ([f8bbcab](f8bbcab3a5))

### Performance Improvements

* don't track seen for POS Invoice (backport [#46187](https://github.com/frappe/erpnext/issues/46187)) ([#46188](https://github.com/frappe/erpnext/issues/46188)) ([b41ee66](b41ee667b9))
2025-03-05 13:28:51 +00:00
ruthra kumar
0f56fbcf6d Merge pull request #46264 from frappe/version-14-hotfix
chore: release v14
2025-03-05 18:57:30 +05:30
Frappe PR Bot
19604e91c6 chore(release): Bumped to Version 14.83.1
## [14.83.1](https://github.com/frappe/erpnext/compare/v14.83.0...v14.83.1) (2025-02-26)

### Bug Fixes

* incorrect stock value difference for adjustment entry ([c734373](c734373c9f))
2025-02-26 12:43:06 +00:00
ruthra kumar
4f40939c15 Merge pull request #46133 from frappe/version-14-hotfix
chore: release v14
2025-02-26 18:11:42 +05:30
Frappe PR Bot
11da4372e2 chore(release): Bumped to Version 14.83.0
# [14.83.0](https://github.com/frappe/erpnext/compare/v14.82.2...v14.83.0) (2025-02-19)

### Bug Fixes

* '0' rate LDC's Invoice net totals should be ignored (backport [#45639](https://github.com/frappe/erpnext/issues/45639)) ([#45783](https://github.com/frappe/erpnext/issues/45783)) ([534b25c](534b25c448))
* add is_new in if condition ([ef37388](ef37388993))
* fetch child account data for selected parent ([#45904](https://github.com/frappe/erpnext/issues/45904)) ([e7d9786](e7d97865e5))
* include missing payment_gateway parameter in Payment Request URL ([a344b8b](a344b8b9ae))
* millisecond issue for posting datetime ([fc6f568](fc6f568a6c))
* on selection of batch qty is not fetching ([44a16bb](44a16bb544))
* pos return validation on v14 ([#45859](https://github.com/frappe/erpnext/issues/45859)) ([84432fc](84432fc035))
* **report:** add options to multiselectlist fields ([aa0ada9](aa0ada9670))
* **send_message:** escape HTML in the text ([703fd81](703fd816d1))
* serial no is mandatory for zero qty validation ([6f6133f](6f6133f2e2))
* set default value to 0 as per new logic ([4b16272](4b16272a01))
* tests ([e515b91](e515b91988))

### Features

* added ability to use custom html format for process statement of accounts ([#45746](https://github.com/frappe/erpnext/issues/45746)) ([a0cd08e](a0cd08e9ea))
* added option to enforce free item qty in pricing rule ([2edf083](2edf083c35))
2025-02-19 11:48:59 +00:00
ruthra kumar
4c74ac8738 Merge pull request #45982 from frappe/version-14-hotfix
chore: release v14
2025-02-19 17:17:34 +05:30
Frappe PR Bot
f109303f85 chore(release): Bumped to Version 14.82.2
## [14.82.2](https://github.com/frappe/erpnext/compare/v14.82.1...v14.82.2) (2025-02-12)

### Bug Fixes

* add total row in non_grouped_invoices ([49074aa](49074aa2fa))
* correct amt in account currency for lcv with manually distributed charges. (backport [#45532](https://github.com/frappe/erpnext/issues/45532)) ([#45863](https://github.com/frappe/erpnext/issues/45863)) ([c61e4e2](c61e4e2ddf))
* do not allow "Finance Book" in Accounting Dimensions (backport [#45696](https://github.com/frappe/erpnext/issues/45696)) ([#45855](https://github.com/frappe/erpnext/issues/45855)) ([08ba775](08ba77538b))
* do not validate party against  Receivable and Payable account for cancelled gl entries ([9f79da0](9f79da0015))
* map project from rfq to supplier quotation (backport [#45745](https://github.com/frappe/erpnext/issues/45745)) ([#45827](https://github.com/frappe/erpnext/issues/45827)) ([c4358c0](c4358c049a))
* Party name in Supplier Portal for Purchase Order (backport [#45772](https://github.com/frappe/erpnext/issues/45772)) ([#45857](https://github.com/frappe/erpnext/issues/45857)) ([46eba50](46eba50c8c))
* pos numpad editable action buttons (backport [#45823](https://github.com/frappe/erpnext/issues/45823)) ([#45825](https://github.com/frappe/erpnext/issues/45825)) ([6b9dad7](6b9dad7768))
* **regional:** removed payment schedule validation in sales invoice for italy (backport [#45852](https://github.com/frappe/erpnext/issues/45852)) ([#45853](https://github.com/frappe/erpnext/issues/45853)) ([de14bf1](de14bf1010))
* skip warning for free items ([2ed3bdc](2ed3bdcc2e))
* unable to remove image from employee ([91caca0](91caca05bb))
* update ctx to args ([573ce64](573ce645b2))

### Performance Improvements

* Ignore is_opening column in GL Queries ([#45327](https://github.com/frappe/erpnext/issues/45327)) ([9985a03](9985a03f39))
2025-02-12 12:08:02 +00:00
ruthra kumar
ab8fceb68d Merge pull request #45861 from frappe/version-14-hotfix
chore: release v14
2025-02-12 17:36:33 +05:30
Frappe PR Bot
f5a1041de2 chore(release): Bumped to Version 14.82.1
## [14.82.1](https://github.com/frappe/erpnext/compare/v14.82.0...v14.82.1) (2025-02-07)

### Bug Fixes

* update ctx to args ([1e13806](1e138064a8))
2025-02-07 14:27:35 +00:00
ruthra kumar
4880a83538 Merge pull request #45797 from frappe/mergify/bp/version-14/pr-45796
Fix: Update `ctx` to `args` for compatibility. (copy #45770) (backport #45796)
2025-02-07 19:56:10 +05:30
Sanket322
1e138064a8 fix: update ctx to args
(cherry picked from commit d4bc3d182f)
(cherry picked from commit 573ce645b2)
2025-02-07 14:21:46 +00:00
Frappe PR Bot
35fab8c23f chore(release): Bumped to Version 14.82.0
# [14.82.0](https://github.com/frappe/erpnext/compare/v14.81.0...v14.82.0) (2025-02-05)

### Bug Fixes

* allow multiple email ids ([9510758](9510758ce4))
* bind this to function ([83bce78](83bce785ff))
* check billing address ([2f33f6b](2f33f6bdf5))
* closing stock balance report not generating ([3f6beeb](3f6beebeec))
* correct error message in payment entry ([9f5d7e4](9f5d7e41ec))
* default payment terms template selected while duplicating ([82cfafb](82cfafb610))
* Gross Profit Report with Correct Totals and Gross Margin (backport [#45548](https://github.com/frappe/erpnext/issues/45548)) ([#45597](https://github.com/frappe/erpnext/issues/45597)) ([0086656](0086656748))
* handling company in bank reconciliation tool ([#45582](https://github.com/frappe/erpnext/issues/45582)) ([7823f1b](7823f1b06f))
* payment schedule table is empty while duplicating record ([d0ff91b](d0ff91b0e0))
* **pos:** add item in the existing item row when discount is applied ([3c6ed0a](3c6ed0a565))
* posting_date to posting_datetime in stock related queries ([bf3d68e](bf3d68e76d))
* renamed Commments Tab to Notes tab in Lead doctype ([0eddd1e](0eddd1e2d7))
* track employee changes ([#45674](https://github.com/frappe/erpnext/issues/45674)) ([43a5c33](43a5c33dbf))

### Features

* set bank account of company to default company bank account from masters ([dac5307](dac53074f2))
2025-02-05 11:45:31 +00:00
ruthra kumar
21b7833d57 Merge pull request #45704 from frappe/version-14-hotfix
chore: release v14
2025-02-05 17:14:10 +05:30
Frappe PR Bot
4eaaffe550 chore(release): Bumped to Version 14.81.0
# [14.81.0](https://github.com/frappe/erpnext/compare/v14.80.0...v14.81.0) (2025-01-29)

### Bug Fixes

* add condition to check if item is delivered by supplier in make_purchase_order_for_default_supplier() ([#45370](https://github.com/frappe/erpnext/issues/45370)) ([69464ab](69464ab7ff))
* add multiple item issue in stock entry (backport [#45544](https://github.com/frappe/erpnext/issues/45544)) ([#45579](https://github.com/frappe/erpnext/issues/45579)) ([1160df9](1160df9350))
* currency decimal on POS Past Order List (backport [#45524](https://github.com/frappe/erpnext/issues/45524)) ([#45526](https://github.com/frappe/erpnext/issues/45526)) ([4d2352a](4d2352af00))
* fix creating documents from sales invoice (backport [#45346](https://github.com/frappe/erpnext/issues/45346)) ([#45407](https://github.com/frappe/erpnext/issues/45407)) ([452b205](452b205021))
* get stock balance filtered by company for validating stock value in jv (backport [#45549](https://github.com/frappe/erpnext/issues/45549)) ([#45577](https://github.com/frappe/erpnext/issues/45577)) ([e682d2c](e682d2c9ae))
* heatmap for Customer and Supplier not rendering ([#44717](https://github.com/frappe/erpnext/issues/44717)) ([ecdff8f](ecdff8f320))
* Merge Conflicts ([35f801f](35f801feda))
* remove applied pricing rule ([c484563](c484563bea))
* resolved pos return setting to default mode of payment instead of user selection ([#45377](https://github.com/frappe/erpnext/issues/45377)) ([#45436](https://github.com/frappe/erpnext/issues/45436)) ([24dc1bf](24dc1bf1a3))
* secure bulk transaction (backport [#45386](https://github.com/frappe/erpnext/issues/45386)) ([#45425](https://github.com/frappe/erpnext/issues/45425)) ([c6bc928](c6bc928f50))
* set company related values ([03068ab](03068ab96c))
* set preferred email in Employee via backend controller (backport [#45320](https://github.com/frappe/erpnext/issues/45320)) ([#45378](https://github.com/frappe/erpnext/issues/45378)) ([1622fc8](1622fc8728))
* update fields on change of item code In `Update Items` of `Sales Order` ([#45125](https://github.com/frappe/erpnext/issues/45125)) ([8befe7f](8befe7f244))
* update voucher outstanding from payment ledger ([a015527](a0155279e0))
* use user defined discount amount or default ([914f4bf](914f4bffea))
* Wrong `bank_ac_no` filter + simplify convoluted logic ([b6b453c](b6b453ca5d))

### Features

* add company level validation for accounting dimension ([cca5fbd](cca5fbd81a))
2025-01-29 11:30:28 +00:00
ruthra kumar
2c693c638d Merge pull request #45567 from frappe/version-14-hotfix
chore: release v14
2025-01-29 16:58:57 +05:30
Frappe PR Bot
a22d3b9895 chore(release): Bumped to Version 14.80.0
# [14.80.0](https://github.com/frappe/erpnext/compare/v14.79.0...v14.80.0) (2025-01-22)

### Bug Fixes

* do not reset picked items ([fe5de30](fe5de30256))
* include pos invoice in modifing key for returned item validation ([431fa22](431fa225e3))
* pos search by term items price (backport [#45006](https://github.com/frappe/erpnext/issues/45006)) ([#45102](https://github.com/frappe/erpnext/issues/45102)) ([524a8d7](524a8d77f7))
* **Project:** re-phrase welcome email ([#45175](https://github.com/frappe/erpnext/issues/45175)) ([77e92b3](77e92b38eb))
* round off tax withholding amount ([#45271](https://github.com/frappe/erpnext/issues/45271)) ([667e659](667e659e3f))
* update query ([49e3865](49e3865265))
* validate linked sales person ([f9420db](f9420db3ca))

### Features

* add difference_posting_date field ([1753509](17535095e2))
* use difference_posting_date for journal entry posting_date ([0fdd681](0fdd6817a6))

### Reverts

* avoid change to translatable string ([20bb151](20bb15167d))
2025-01-22 03:34:40 +00:00
ruthra kumar
ad960c1470 Merge pull request #45358 from frappe/version-14-hotfix
chore: release v14
2025-01-22 09:03:17 +05:30
Frappe PR Bot
ff3425ead1 chore(release): Bumped to Version 14.79.0
# [14.79.0](https://github.com/frappe/erpnext/compare/v14.78.9...v14.79.0) (2025-01-15)

### Bug Fixes

* deduct tds on excess amount if checked ([6a52f79](6a52f79cce))
* do not add ordered items from Quotation to new Sales Order ([d42173b](d42173beb5))
* **Timesheet:** ignore permissions when updating Task and Project (backport [#45168](https://github.com/frappe/erpnext/issues/45168)) ([#45171](https://github.com/frappe/erpnext/issues/45171)) ([49ffecc](49ffeccafa))
* typo ([#45233](https://github.com/frappe/erpnext/issues/45233)) ([6bc210d](6bc210d9f4))

### Features

* validate discount date in payment schedule (backport [#44646](https://github.com/frappe/erpnext/issues/44646)) ([#44726](https://github.com/frappe/erpnext/issues/44726)) ([f4b7fa8](f4b7fa8980))
2025-01-15 12:09:13 +00:00
rohitwaghchaure
d098fd3fc3 Merge pull request #45264 from frappe/version-14-hotfix
chore: release v14
2025-01-15 17:37:57 +05:30
Frappe PR Bot
611c1f1ec2 chore(release): Bumped to Version 14.78.9
## [14.78.9](https://github.com/frappe/erpnext/compare/v14.78.8...v14.78.9) (2025-01-08)

### Bug Fixes

* add monthly distributation and write query in qb ([7d1d0c8](7d1d0c8e0c))
* discount resetting on date change ([01d2794](01d2794968)), closes [#44989](https://github.com/frappe/erpnext/issues/44989)
* header_img field schema ([eb55051](eb5505187e))
* Missing company filter breaks `get_account_balance` in Bank Reco ([821cfe2](821cfe2c39))
* Override pre-commit behaviour due to conflicts with CI ([46894a5](46894a5b86))
* **Project:** make status in confirmation dialog translatable ([#45118](https://github.com/frappe/erpnext/issues/45118)) ([07653c5](07653c54f3))
* Returned Qty in Work Order Consumed Materials report ([affa67e](affa67e74d))
* update customer contact details on pos (backport [#45071](https://github.com/frappe/erpnext/issues/45071)) ([#45105](https://github.com/frappe/erpnext/issues/45105)) ([2d63fc9](2d63fc98d0))
2025-01-08 10:27:38 +00:00
ruthra kumar
a05fb916ff Merge pull request #45132 from frappe/version-14-hotfix
chore: release v14
2025-01-08 15:56:16 +05:30
Frappe PR Bot
1f39bb9c7a chore(release): Bumped to Version 14.78.8
## [14.78.8](https://github.com/frappe/erpnext/compare/v14.78.7...v14.78.8) (2025-01-03)

### Bug Fixes

* BOM cost update issue ([4977843](49778432ea))
* removed unused code ([9efc1de](9efc1de40e))
* slow stock transactions (backport [#45025](https://github.com/frappe/erpnext/issues/45025)) ([#45026](https://github.com/frappe/erpnext/issues/45026)) ([b7509e3](b7509e326e))
2025-01-03 01:21:42 +00:00
ruthra kumar
9e60f67d25 Merge pull request #45064 from frappe/version-14-hotfix
chore: release v14
2025-01-03 06:50:19 +05:30
ruthra kumar
6a91f9155f Merge pull request #45059 from frappe/mergify/bp/version-14/pr-45056
chore: partial revert #44989 (backport #45056)
2025-01-02 21:04:58 +05:30
ruthra kumar
77f612354f chore: partial revert #44989
(cherry picked from commit 63d547fb4a)
2025-01-02 15:29:53 +00:00
Frappe PR Bot
0e8a04f2cc chore(release): Bumped to Version 14.78.7
## [14.78.7](https://github.com/frappe/erpnext/compare/v14.78.6...v14.78.7) (2025-01-01)

### Bug Fixes

* slow stock transactions (backport [#45025](https://github.com/frappe/erpnext/issues/45025)) ([#45026](https://github.com/frappe/erpnext/issues/45026)) ([a85a103](a85a103bad))
2025-01-01 10:48:12 +00:00
rohitwaghchaure
2a40845f65 Merge pull request #45029 from frappe/mergify/bp/version-14/pr-45026
fix: slow stock transactions (backport #45025) (backport #45026)
2025-01-01 16:16:46 +05:30
mergify[bot]
a85a103bad fix: slow stock transactions (backport #45025) (#45026)
* fix: slow stock transactions (#45025)

(cherry picked from commit e92af10f14)

# Conflicts:
#	erpnext/stock/stock_ledger.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit b7509e326e)
2025-01-01 10:00:11 +00:00
Frappe PR Bot
76ea858e72 chore(release): Bumped to Version 14.78.6
## [14.78.6](https://github.com/frappe/erpnext/compare/v14.78.5...v14.78.6) (2025-01-01)

### Bug Fixes

* apply apply_pricing_rule date change ([cca507f](cca507f0bd))
* clear payment schedule in purchase invoice for is_paid ([cdd3763](cdd3763a8b))
* duplicate validate for closing stock balance (backport [#45015](https://github.com/frappe/erpnext/issues/45015)) ([#45021](https://github.com/frappe/erpnext/issues/45021)) ([e2b6615](e2b6615e72))
* failing tests fixed ([498abf7](498abf7c83))
* get item tax template based on posting date ([56d0686](56d06861d0))
* load customer default price list in pos during item selection (backport [#44991](https://github.com/frappe/erpnext/issues/44991)) ([#44992](https://github.com/frappe/erpnext/issues/44992)) ([0f687f1](0f687f1db7))
* pos payment using non-default mode of payment (backport [#44920](https://github.com/frappe/erpnext/issues/44920)) ([#44970](https://github.com/frappe/erpnext/issues/44970)) ([a0063b3](a0063b31c2)), closes [#41108](https://github.com/frappe/erpnext/issues/41108)
* refactor query in get_total_allocated_amount in bank_transaction ([cc0a478](cc0a478559))
* resolve conflicts ([443a0b8](443a0b81f9))
* set paid amount in party currency in bank reco payment entry ([43a40b1](43a40b1e66))
* Show order tax amount in customer currency on the portal (backport [#44915](https://github.com/frappe/erpnext/issues/44915)) ([#44922](https://github.com/frappe/erpnext/issues/44922)) ([78e0799](78e0799a06))
* update item_tax_rate in backend ([cf980a1](cf980a1304))
* update payment amount for partial pos return (backport [#44065](https://github.com/frappe/erpnext/issues/44065)) ([#44961](https://github.com/frappe/erpnext/issues/44961)) ([1da4712](1da4712919))
2025-01-01 08:56:51 +00:00
ruthra kumar
97487eb6e1 Merge pull request #45004 from frappe/version-14-hotfix
chore: release v14
2025-01-01 14:25:31 +05:30
Frappe PR Bot
27b7de4854 chore(release): Bumped to Version 14.78.5
## [14.78.5](https://github.com/frappe/erpnext/compare/v14.78.4...v14.78.5) (2024-12-25)

### Bug Fixes

* 'str' object has no attribute 'get_sql' ([510e3ce](510e3cebc9))
* added docs.frappe.io in documentation_url ([#44776](https://github.com/frappe/erpnext/issues/44776)) ([82a3fd1](82a3fd13f2))
* buying rate for service item in gross profit report ([7fa3a78](7fa3a789b1))
* closing stock balance permissions (backport [#44791](https://github.com/frappe/erpnext/issues/44791)) ([#44792](https://github.com/frappe/erpnext/issues/44792)) ([4cb27b9](4cb27b97b4))
* correct tds rate with lower deduction certificate ([d55fe7d](d55fe7d33f))
* do not set cost_center update_voucher_balance as it is set in init_voucher_balance ([97d5d18](97d5d18041))
* fetch tax withholding category from the voucher ([1093c22](1093c227f1))
* permissions for marking Quotation as lost ([0179358](0179358f07))
* Remove typo ([422ada2](422ada2726))
* show profit and loss after period closing ([1a089da](1a089da51a))
* slow posting datetime update (backport [#44799](https://github.com/frappe/erpnext/issues/44799)) ([#44804](https://github.com/frappe/erpnext/issues/44804)) ([d2ede71](d2ede713e4))
* update correct cost center in Accounts Receivable Report ([197b13e](197b13eb87))
* use utility method to generate url ([d042330](d042330c30))
* **ux:** purchase invoice link in error message ([#44797](https://github.com/frappe/erpnext/issues/44797)) ([c9d43f4](c9d43f4c88))
* Warehouse wise Stock Value chart roles (backport [#44865](https://github.com/frappe/erpnext/issues/44865)) ([#44866](https://github.com/frappe/erpnext/issues/44866)) ([177ca6f](177ca6f431))
2024-12-25 03:34:28 +00:00
ruthra kumar
1b5384f8d4 Merge pull request #44886 from frappe/version-14-hotfix
chore: release v14
2024-12-25 09:03:10 +05:30
Frappe PR Bot
561fe5a171 chore(release): Bumped to Version 14.78.4
## [14.78.4](https://github.com/frappe/erpnext/compare/v14.78.3...v14.78.4) (2024-12-18)

### Bug Fixes

* 'str' object has no attribute 'get_sql' ([bd20ff5](bd20ff581b))
2024-12-18 09:07:38 +00:00
ruthra kumar
f8f2c39ed5 Merge pull request #44768 from frappe/mergify/bp/version-14/pr-44765
fix: 'str' object has no attribute 'get_sql' (backport #44765)
2024-12-18 14:36:18 +05:30
ljain112
bd20ff581b fix: 'str' object has no attribute 'get_sql'
(cherry picked from commit 9a43acb65c)
2024-12-18 08:43:15 +00:00
Frappe PR Bot
d241862f14 chore(release): Bumped to Version 14.78.3
## [14.78.3](https://github.com/frappe/erpnext/compare/v14.78.2...v14.78.3) (2024-12-18)

### Bug Fixes

* allow all dispatch address for drop ship invoice ([0688c0a](0688c0ab6b))
* better indicator base amount for Tax Witholding in Journal Entry ([4a261b5](4a261b5cef))
* broken CI ([c86174d](c86174d0f2))
* incorrect status of the purchase receipt ([#44689](https://github.com/frappe/erpnext/issues/44689)) ([4b4d5df](4b4d5dfa63))
* purchase return entry issue (backport [#44721](https://github.com/frappe/erpnext/issues/44721)) ([#44736](https://github.com/frappe/erpnext/issues/44736)) ([744f345](744f3457de))
* remove invalid filter in Account Receivable report ([b571c7a](b571c7af87))
* set company bank account if default account not set in mode of payment ([2d12f2c](2d12f2cebd))
* Stock Entry uses incorrect company when generated from Pick List ([#44679](https://github.com/frappe/erpnext/issues/44679)) ([00898be](00898be8e4))
* update discount when pricing rule is changed ([0a7832d](0a7832d8d3))
* User permissions in financial statements ([8a9c457](8a9c457d37))
* using query.walk() for escaping ([3a7e335](3a7e335d4b))
* Wrong allocated_amount for sales_team in gross_profit report ([#42989](https://github.com/frappe/erpnext/issues/42989)) ([d83cc57](d83cc57e58))
2024-12-18 05:01:40 +00:00
ruthra kumar
8e34e20b27 Merge pull request #44740 from frappe/version-14-hotfix
chore: release v14
2024-12-18 10:30:20 +05:30
Frappe PR Bot
225d4ccb63 chore(release): Bumped to Version 14.78.2
## [14.78.2](https://github.com/frappe/erpnext/compare/v14.78.1...v14.78.2) (2024-12-12)

### Bug Fixes

* add docstatus for translation ([0a4090a](0a4090a771))
* add label strings for translation in pos_controller.js ([8233e22](8233e22d8b))
* add labels for translation in production_analytics.py ([1a7f195](1a7f195d8f))
* add labels for translation in purchase_order_analysis.py ([f9974f9](f9974f9eb0))
* add labels for translation in quality_inspection_summary.py ([9986c26](9986c26a0c))
* add labels for translation in sales_order_analysis.py ([bad1b2a](bad1b2a164))
* add labels for translation in sales_order.js ([3620dda](3620ddab34))
* add string for translation in delayed_tasks_summary.py ([ce04f6d](ce04f6d7c9))
* add strings for translation in pos_item_cart.js ([1f0f31a](1f0f31a773))
* add strings for translation payment_terms_status_for_sales_order.py ([17dad01](17dad01ab7))
* add title for translation in  asset.js ([aed90f7](aed90f73d7))
* **Bank Transaction:** error in party matching should not block submitting (backport [#44416](https://github.com/frappe/erpnext/issues/44416)) ([#44573](https://github.com/frappe/erpnext/issues/44573)) ([ebc8bed](ebc8bede7f))
* description overwrite on qty change (backport [#44606](https://github.com/frappe/erpnext/issues/44606)) ([#44608](https://github.com/frappe/erpnext/issues/44608)) ([a460bf9](a460bf9433))
* incorrect stock UOM for BOM raw materials (backport [#44528](https://github.com/frappe/erpnext/issues/44528)) ([#44530](https://github.com/frappe/erpnext/issues/44530)) ([ecc756b](ecc756bd52))
* inv dimensions fields not creating for standard doctype (backport [#44504](https://github.com/frappe/erpnext/issues/44504)) ([#44514](https://github.com/frappe/erpnext/issues/44514)) ([c502b56](c502b562db))
* prevent set_payment_schedule on return documents ([3c8b637](3c8b637a8b))
* required by date in the reorder material request (backport [#44497](https://github.com/frappe/erpnext/issues/44497)) ([#44508](https://github.com/frappe/erpnext/issues/44508)) ([15e3663](15e3663633))
* strings for translation in pos_past_order_summary.js ([dfbb227](dfbb2279b6))
* variant qty while making work order from BOM (backport [#44548](https://github.com/frappe/erpnext/issues/44548)) ([#44550](https://github.com/frappe/erpnext/issues/44550)) ([e2aedc8](e2aedc85b4))
2024-12-12 10:37:15 +00:00
ruthra kumar
e09232234e Merge pull request #44639 from frappe/version-14-hotfix
chore: release v14
2024-12-12 16:05:12 +05:30
Frappe PR Bot
7a2b07a2a3 chore(release): Bumped to Version 14.78.1
## [14.78.1](https://github.com/frappe/erpnext/compare/v14.78.0...v14.78.1) (2024-12-05)

### Bug Fixes

* required by date in the reorder material request (backport [#44497](https://github.com/frappe/erpnext/issues/44497)) ([#44508](https://github.com/frappe/erpnext/issues/44508)) ([e0b8c27](e0b8c2788b))
2024-12-05 08:18:33 +00:00
rohitwaghchaure
86ff1545ce Merge pull request #44535 from frappe/mergify/bp/version-14/pr-44508
fix: required by date in the reorder material request (backport #44497) (backport #44508)
2024-12-05 13:47:02 +05:30
mergify[bot]
e0b8c2788b fix: required by date in the reorder material request (backport #44497) (#44508)
* fix: required by date in the reorder material request (#44497)

(cherry picked from commit 4001166ecc)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/test_stock_entry.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 15e3663633)
2024-12-05 07:24:59 +00:00
Frappe PR Bot
c1a1346e2a chore(release): Bumped to Version 14.78.0
# [14.78.0](https://github.com/frappe/erpnext/compare/v14.77.3...v14.78.0) (2024-12-04)

### Bug Fixes

* Add filter for `outstanding_amount` to fetch open PRs ([7e847f2](7e847f27dd))
* Add translation for showing mandatory fields in error msg ([de5b253](de5b253215))
* added fieldname to avoid fieldname to translate ([d7caa8d](d7caa8d51b))
* Added translation for `Account` column ([2061c7c](2061c7ca46))
* adjusted incoming rate for zero rated item in purchase receipt ([d7583e3](d7583e3993))
* correct buying amount for product bundel ([91f6393](91f6393104))
* Dashboard for `Payment Request` ([c911a70](c911a70a84))
* Data Should be Computed in Backend to Maintain Consistent Behaviour ([#44195](https://github.com/frappe/erpnext/issues/44195)) ([8529eb4](8529eb4573))
* handle multi currency in common party journal entry ([bed6dab](bed6dabecb))
* incorrect Gross Margin on project ([#44461](https://github.com/frappe/erpnext/issues/44461)) ([5533592](5533592b2b))
* remove queries ([7d724d7](7d724d7647))
* show "Send SMS" only when enabled (backport [#43941](https://github.com/frappe/erpnext/issues/43941)) ([#43969](https://github.com/frappe/erpnext/issues/43969)) ([9ae04df](9ae04dfed3))
* source warehouse not set in required items of WO (backport [#44426](https://github.com/frappe/erpnext/issues/44426)) ([#44433](https://github.com/frappe/erpnext/issues/44433)) ([cbce4e7](cbce4e72d9))
* Translate `Party Account` column label ([c4103d2](c4103d26be))
* typeerror on transaction.js ([147eb04](147eb047aa))

### Features

* add Company Contact Person in selling transactions (backport [#44362](https://github.com/frappe/erpnext/issues/44362)) ([#44397](https://github.com/frappe/erpnext/issues/44397)) ([78ab44c](78ab44ce1a))

### Performance Improvements

* cache product bundle items at document level ([#44440](https://github.com/frappe/erpnext/issues/44440)) ([df0dac5](df0dac5610))
* reduce queries during transaction save ([f884cf8](f884cf8a5e))

### Reverts

* remove default `Payment Request` indicator color ([9baaaca](9baaaca924))
2024-12-04 04:36:03 +00:00
ruthra kumar
1e02d06424 Merge pull request #44482 from frappe/version-14-hotfix
chore: release v14
2024-12-04 10:04:44 +05:30
Frappe PR Bot
0079bd282e chore(release): Bumped to Version 14.77.3
## [14.77.3](https://github.com/frappe/erpnext/compare/v14.77.2...v14.77.3) (2024-11-27)

### Bug Fixes

*  correct placeholder index in message ([d7e6b0e](d7e6b0e1b7))
* added Stock UOM field for RM in work order (backport [#44185](https://github.com/frappe/erpnext/issues/44185)) ([#44236](https://github.com/frappe/erpnext/issues/44236)) ([ee647f2](ee647f2381))
* billed qty and received amount in PO analysis report (backport [#44349](https://github.com/frappe/erpnext/issues/44349)) ([#44353](https://github.com/frappe/erpnext/issues/44353)) ([6aebe98](6aebe98020))
* change asset status correctly ([841df3b](841df3b1ce))
* Get submitted documents in validate_for_closed_fiscal_year ([b9efeeb](b9efeeb71a))
* gp for return invoice ([6e56343](6e563438bd))
* include current invoice amount when tax_on_excess_amount is checked ([071adcf](071adcf291))
* incorrect GL entry on sale of fully depreciated asset ([cc5ada1](cc5ada194e))
* make free qty round on large transaction qty ([2eb7002](2eb70026ae))
* patch ([#44191](https://github.com/frappe/erpnext/issues/44191)) ([3643c60](3643c60c67))
* test case ([7eafe7f](7eafe7f853))
* unify company address query in sales transactions (backport [#44361](https://github.com/frappe/erpnext/issues/44361)) ([#44366](https://github.com/frappe/erpnext/issues/44366)) ([fef7cfb](fef7cfb888))
* update gross profit for returned invoices ([0eb5e00](0eb5e001e1))
* Used `Fiscal Dates` instead of year's `Start` and `End` dates ([4f806f9](4f806f9a72))
2024-11-27 15:25:06 +00:00
ruthra kumar
2db54f0bb1 Merge pull request #44342 from frappe/version-14-hotfix
chore: release v14
2024-11-27 20:53:38 +05:30
Frappe PR Bot
4723fbfd57 chore(release): Bumped to Version 14.77.2
## [14.77.2](https://github.com/frappe/erpnext/compare/v14.77.1...v14.77.2) (2024-11-22)

### Bug Fixes

* patch ([#44191](https://github.com/frappe/erpnext/issues/44191)) ([d1295d1](d1295d1c79))
2024-11-22 11:28:10 +00:00
rohitwaghchaure
ab49ee2e05 Merge pull request #44289 from frappe/mergify/bp/version-14/pr-44288
fix: patch (backport #44191) (backport #44288)
2024-11-22 16:56:24 +05:30
rohitwaghchaure
d1295d1c79 fix: patch (#44191)
(cherry picked from commit 495528a758)
(cherry picked from commit 3643c60c67)
2024-11-22 10:56:37 +00:00
Frappe PR Bot
46a8500361 chore(release): Bumped to Version 14.77.1
## [14.77.1](https://github.com/frappe/erpnext/compare/v14.77.0...v14.77.1) (2024-11-22)

### Bug Fixes

* include current invoice amount when tax_on_excess_amount is checked ([43f59da](43f59da0a9))
2024-11-22 06:01:07 +00:00
ruthra kumar
88ba24f1cf Merge pull request #44270 from frappe/mergify/bp/version-14/pr-44194
fix: include current invoice amount when tax_on_excess_amount is checked (backport #44194)
2024-11-22 11:29:50 +05:30
venkat102
87bb403159 test: add unit test for tax on excess amount
(cherry picked from commit 4820273595)
2024-11-22 05:37:12 +00:00
venkat102
43f59da0a9 fix: include current invoice amount when tax_on_excess_amount is checked
(cherry picked from commit b74f2896cd)
2024-11-22 05:37:12 +00:00
Frappe PR Bot
2c865bcd49 chore(release): Bumped to Version 14.77.0
# [14.77.0](https://github.com/frappe/erpnext/compare/v14.76.0...v14.77.0) (2024-11-20)

### Bug Fixes

* added test cases ([5fa4fd8](5fa4fd8825))
* apply posting date sorting to invoices in Payment Reconciliation similar to payments ([cc9b22c](cc9b22ce9f))
* backport german translations from develop ([#44046](https://github.com/frappe/erpnext/issues/44046)) ([c23868a](c23868a14d))
* broken apply on other item pricing rule ([f03e301](f03e301250))
* broken UI on currency exchange ([36898f6](36898f6797))
* check if pricing rule matches with coupon code ([#44104](https://github.com/frappe/erpnext/issues/44104)) ([24b5b3c](24b5b3c8e0))
* correctly set 'cannot_add_rows' property on allocations table field ([137ef78](137ef78d96))
* disable conversion to user tz for sales order calender ([356da69](356da69179))
* Get Entries not showing accounts with no gain or loss in Exchange Rate Revaluation issue ([33e835c](33e835c4d3))
* linters ([c3e2ff2](c3e2ff2fa5))
* non group pos warehouse ([ec40131](ec40131d4d))
* payment reco for jv with negative dr or cr amount ([23fb4f3](23fb4f348f))
* remove trailing whitespace ([1019d98](1019d98c5a))
* set conversion factor before applying price list ([e09f101](e09f101336))
* set default party type in Payment Entry ([f3cbbef](f3cbbef346))
* stock ledger variance report filter options (backport [#44137](https://github.com/frappe/erpnext/issues/44137)) ([#44149](https://github.com/frappe/erpnext/issues/44149)) ([f871f08](f871f08f47))
* validate sales team to ensure all sales person are enabled ([bd0f11e](bd0f11ef4f))

### Features

* new DocTypes "Code List" and "Common Code" (backport [#43425](https://github.com/frappe/erpnext/issues/43425)) ([#44172](https://github.com/frappe/erpnext/issues/44172)) ([a7de8c1](a7de8c1143))
2024-11-20 08:37:41 +00:00
ruthra kumar
fc783f5acf Merge pull request #44210 from frappe/version-14-hotfix
chore: release v14
2024-11-20 14:06:14 +05:30
Frappe PR Bot
75d785f6b6 chore(release): Bumped to Version 14.76.0
# [14.76.0](https://github.com/frappe/erpnext/compare/v14.75.2...v14.76.0) (2024-11-13)

### Bug Fixes

* Drop Shipping address based on customer shopping address ([ea38a1f](ea38a1f36a))
* exception on register reports when filtered on cost center ([599581e](599581e09d))
* NoneType while updating ordered_qty in SO for removed items ([1446aa3](1446aa3636))
* populate payment schedule from payment terms (backport [#44082](https://github.com/frappe/erpnext/issues/44082)) ([#44084](https://github.com/frappe/erpnext/issues/44084)) ([6b149f5](6b149f5ddf))
* subcontracting receipt has no reference field for purchase order ([b1e205f](b1e205f4d1))
* task path (backport [#44073](https://github.com/frappe/erpnext/issues/44073)) ([#44077](https://github.com/frappe/erpnext/issues/44077)) ([c12d5f6](c12d5f613a))
* tyeerror while saving pick list ([d73cc83](d73cc83b91))
* update per_billed value in Purchase Receipt while creating Debit Note ([#43977](https://github.com/frappe/erpnext/issues/43977)) ([da6c6dc](da6c6dcfcb))

### Features

* Partly billed status in Purchase Receipt ([#39543](https://github.com/frappe/erpnext/issues/39543)) ([3e2fa16](3e2fa16d84))
2024-11-13 15:00:34 +00:00
ruthra kumar
a63a0e0d37 Merge pull request #44102 from frappe/version-14-hotfix
chore: release v14
2024-11-13 20:29:06 +05:30
Frappe PR Bot
e46834095b chore(release): Bumped to Version 14.75.2
## [14.75.2](https://github.com/frappe/erpnext/compare/v14.75.1...v14.75.2) (2024-11-08)

### Bug Fixes

* subcontracting receipt has no reference field for purchase order ([1633a31](1633a3176c))
2024-11-08 07:22:01 +00:00
rohitwaghchaure
2f969478e9 Merge pull request #44032 from frappe/mergify/bp/version-14/pr-44014
fix: Subcontracting Receipt has no reference field for Purchase Order (backport #44014)
2024-11-08 12:49:15 +05:30
Ninad1306
1633a3176c fix: subcontracting receipt has no reference field for purchase order
(cherry picked from commit b1e205f4d1)
2024-11-08 06:53:14 +00:00
Frappe PR Bot
ea634ec230 chore(release): Bumped to Version 14.75.1
## [14.75.1](https://github.com/frappe/erpnext/compare/v14.75.0...v14.75.1) (2024-11-07)

### Bug Fixes

* ensure list has items ([5c8af85](5c8af85086))
* error when saving POS merge log ([#43989](https://github.com/frappe/erpnext/issues/43989)) ([657bd37](657bd3712b))
* removed single quotes from deferred revenue ([#43985](https://github.com/frappe/erpnext/issues/43985)) ([aee8a23](aee8a23626))
* serial no ledger report ([#44006](https://github.com/frappe/erpnext/issues/44006)) ([9838eaa](9838eaa332))
* task showing limit in customer portal (backport [#44003](https://github.com/frappe/erpnext/issues/44003)) ([#44004](https://github.com/frappe/erpnext/issues/44004)) ([bc9f0f8](bc9f0f8368))
2024-11-07 12:44:44 +00:00
Sagar Vora
33a9c5e88d Merge pull request #44007 from frappe/version-14-hotfix 2024-11-07 18:13:19 +05:30
Frappe PR Bot
710771edf4 chore(release): Bumped to Version 14.75.0
# [14.75.0](https://github.com/frappe/erpnext/compare/v14.74.8...v14.75.0) (2024-11-06)

### Bug Fixes

* SO link on PO and add in missing dashboard references on both ([4f8a8a5](4f8a8a5e99))

### Features

* remove Payroll Entry from Bank Account dashboard (backport [#43931](https://github.com/frappe/erpnext/issues/43931)) ([#43932](https://github.com/frappe/erpnext/issues/43932)) ([42c2b84](42c2b84b28))

### Performance Improvements

* too many writes error during reposting (backport [#43978](https://github.com/frappe/erpnext/issues/43978)) ([#43982](https://github.com/frappe/erpnext/issues/43982)) ([57d35ec](57d35ec20e))
2024-11-06 05:11:31 +00:00
ruthra kumar
e6b97cad89 Merge pull request #43974 from frappe/version-14-hotfix
chore: release v14
2024-11-06 10:40:10 +05:30
Frappe PR Bot
80f2f5cd2f chore(release): Bumped to Version 14.74.8
## [14.74.8](https://github.com/frappe/erpnext/compare/v14.74.7...v14.74.8) (2024-10-30)

### Bug Fixes

* add company filter for project ([d3e29fe](d3e29fe828))
* add parenttype clause to invoice tax query in sales_register report ([cbe704c](cbe704c73c))
* added validation for UOM must be whole number (backport [#43710](https://github.com/frappe/erpnext/issues/43710)) ([#43711](https://github.com/frappe/erpnext/issues/43711)) ([aaae81f](aaae81f7e8))
* basic rate not editable in Stock Entry Detail (backport [#43837](https://github.com/frappe/erpnext/issues/43837)) ([#43839](https://github.com/frappe/erpnext/issues/43839)) ([51c1d03](51c1d032ba))
* calculate tds with net amount when invoice exceeds single threshold amount (backport [#43869](https://github.com/frappe/erpnext/issues/43869)) ([#43919](https://github.com/frappe/erpnext/issues/43919)) ([55c5f30](55c5f30d54))
* do not check for payment terms details for return invoices. ([fd63ace](fd63ace6c7))
* do not set payment terms for return invoices ([bd34a67](bd34a67871))
* get stock accounts from the doc instead of db in validate_stock_accounts ([ad04610](ad04610c94))
* hide payment terms for return and paid purchase invoices ([78db8c0](78db8c0029))
* not able to submit stock entry ([#43890](https://github.com/frappe/erpnext/issues/43890)) ([0742e6e](0742e6e193))
* purchase return validation issue ([#43871](https://github.com/frappe/erpnext/issues/43871)) ([a7cc7b2](a7cc7b28c0))
* remarks field in payment reconciliation ([93243b1](93243b1d95))
* **RFQ:** make strings translatable (backport [#43843](https://github.com/frappe/erpnext/issues/43843)) ([#43847](https://github.com/frappe/erpnext/issues/43847)) ([895f1bf](895f1bff01))
* set bill_no before `against_voucher` gets concatenated ([2f3c3d5](2f3c3d5519))
* work order finish button not showing (backport [#43875](https://github.com/frappe/erpnext/issues/43875)) ([#43877](https://github.com/frappe/erpnext/issues/43877)) ([76530de](76530de786))
2024-10-30 09:52:54 +00:00
ruthra kumar
4e85a79e42 Merge pull request #43892 from frappe/version-14-hotfix
chore: release v14
2024-10-30 15:21:35 +05:30
Frappe PR Bot
8c7ed37afd chore(release): Bumped to Version 14.74.7
## [14.74.7](https://github.com/frappe/erpnext/compare/v14.74.6...v14.74.7) (2024-10-23)

### Bug Fixes

* "show_remarks" checkbox in Process statement of accounts ([0833823](083382399f))
* coupon code validation logic ([c18beae](c18beaea6b))
* **deferred_revenue:** Escape account in query ([3d082c9](3d082c93bc))
* Freeze Screen on load invoices on POS Closing Entry ([725b6be](725b6beff3))
* get period estimate till service end date ([35c257a](35c257a7ae))
* incorrect amount in bank clearance ([98362d9](98362d9183))
* party_balance based on company in payment entry ([5333f33](5333f33c21))
* remove extra space ([719565c](719565c897))
* use correct variable in error message (backport [#43790](https://github.com/frappe/erpnext/issues/43790)) ([#43791](https://github.com/frappe/erpnext/issues/43791)) ([5b0a8fd](5b0a8fd2ce))
2024-10-23 04:45:56 +00:00
ruthra kumar
9da08df3ca Merge pull request #43773 from frappe/version-14-hotfix
chore: release v14
2024-10-23 10:14:40 +05:30
Frappe PR Bot
e401ad5b8f chore(release): Bumped to Version 14.74.6
## [14.74.6](https://github.com/frappe/erpnext/compare/v14.74.5...v14.74.6) (2024-10-16)

### Bug Fixes

* added parentheses for correct query formation for logical OR condition ([0f738de](0f738de5e5))
* added string for translation in bank reconciliation statement ([32f6eb7](32f6eb7ee7))
* conversion factor issue (backport [#43645](https://github.com/frappe/erpnext/issues/43645)) ([#43675](https://github.com/frappe/erpnext/issues/43675)) ([1262c32](1262c322d1))
* delete invalid pricing rule on change of applicable_for ([c7c2bdd](c7c2bdd159))
* ignore free item when qty is zero ([ae47fb9](ae47fb9617))
* missing child company accounts in consolidated balance sheet ([bb774ce](bb774cec58))
* removed unused query ([dcbfd4a](dcbfd4ae1d))
* run gl_entries and closing voucher processes in same function ([59c314c](59c314c98a))
* update formatings ([a8ad608](a8ad608fd8))
* update formatings ([699b098](699b09846a))
* update item details with actual quantity. ([c520a7c](c520a7c6c1))
* Use `ref_doc.get()` for `party_account_currency` ([01d6c10](01d6c1081b))
* validation for corrective job card (backport [#43555](https://github.com/frappe/erpnext/issues/43555)) (backport [#43558](https://github.com/frappe/erpnext/issues/43558)) ([#43628](https://github.com/frappe/erpnext/issues/43628)) ([1f09975](1f099752d2))
* zero incoming rate for delivery note return ([#43642](https://github.com/frappe/erpnext/issues/43642)) ([7eac9cc](7eac9cc1db))
2024-10-16 05:02:55 +00:00
ruthra kumar
9106c2fdd8 Merge pull request #43668 from frappe/version-14-hotfix
chore: release v14
2024-10-16 10:31:35 +05:30
Frappe PR Bot
7404911940 chore(release): Bumped to Version 14.74.5
## [14.74.5](https://github.com/frappe/erpnext/compare/v14.74.4...v14.74.5) (2024-10-12)

### Bug Fixes

* validation for corrective job card (backport [#43555](https://github.com/frappe/erpnext/issues/43555)) (backport [#43558](https://github.com/frappe/erpnext/issues/43558)) ([#43628](https://github.com/frappe/erpnext/issues/43628)) ([ea0f044](ea0f044c48))
2024-10-12 15:51:49 +00:00
rohitwaghchaure
136adcb793 Merge pull request #43629 from frappe/mergify/bp/version-14/pr-43628
fix: validation for corrective job card (backport #43555) (backport #43558) (backport #43628)
2024-10-12 21:20:29 +05:30
mergify[bot]
ea0f044c48 fix: validation for corrective job card (backport #43555) (backport #43558) (#43628)
fix: validation for corrective job card (backport #43555) (#43558)

* fix: validation for corrective job card (#43555)

(cherry picked from commit 7a0a893d08)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card/job_card.py

* chore: fix conflicts

* chore: fix linters issue

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit cf0fa0db7b)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
(cherry picked from commit 1f099752d2)
2024-10-12 13:04:35 +00:00
Frappe PR Bot
e9dbbbe324 chore(release): Bumped to Version 14.74.4
## [14.74.4](https://github.com/frappe/erpnext/compare/v14.74.3...v14.74.4) (2024-10-10)

### Bug Fixes

* add parenttype condition for item table in Purchase Register Report ([4586f03](4586f03bdc))
* Add removed test code `b41f10c1b9` ([8f5c191](8f5c191136))
* create Account Closing Balance even though there are no transaction in period ([2fc776d](2fc776d0f5))
* deduct advances adjusted for threshold check for tcs ([de15728](de15728741))
* do not include advances for tds vouchers ([9d950a9](9d950a9b77))
* get company from ref doc as it's not available in payment request ([078eb46](078eb46eb8))
* multiple issues in Payment Request ([#42427](https://github.com/frappe/erpnext/issues/42427)) ([ef52be2](ef52be2f17))
* Remove `advance_payment_status` uses ([36b4f68](36b4f68566))
* Remove unreference method ([d4421da](d4421dade1))
* Remove unused  field ([3a51cf4](3a51cf4e1a))
* Remove unused function `get_paid_amount_against_order` ([677aadd](677aadde7c))
* Separate `on_submit` and `before_submit` of PR ([d828ea6](d828ea6a1a))
2024-10-10 00:48:02 +00:00
ruthra kumar
4b1e3c96c2 Merge pull request #43562 from frappe/version-14-hotfix
chore: release v14
2024-10-10 06:16:42 +05:30
Frappe PR Bot
96cb08dba8 chore(release): Bumped to Version 14.74.3
## [14.74.3](https://github.com/frappe/erpnext/compare/v14.74.2...v14.74.3) (2024-10-04)

### Bug Fixes

* add company filter in Warehouse wise Item Balance Age and Value ([3cb8502](3cb85028d0))
* adjustmen entry for stock reco ([57925a1](57925a1315))
* conflicts ([02ce528](02ce528501))
* **Dunning:** logic for fetching text (backport [#43160](https://github.com/frappe/erpnext/issues/43160)) ([#43489](https://github.com/frappe/erpnext/issues/43489)) ([31ecdb2](31ecdb2104))
* Fix API endpoint for Frankfurter ([1c0843c](1c0843caee))
* patch to update Currency Exchange Settings for `frankfurter.app` ([b4706db](b4706db816))
* set margin fields for purchase documents when updating items ([97edadf](97edadfc4b))
* Stock Ledger Invariant Check report ([4426384](44263842f5))
2024-10-04 03:04:09 +00:00
ruthra kumar
b18ad94071 Merge pull request #43468 from frappe/version-14-hotfix
chore: release v14
2024-10-04 08:32:45 +05:30
Frappe PR Bot
20f9549247 chore(release): Bumped to Version 14.74.2
## [14.74.2](https://github.com/frappe/erpnext/compare/v14.74.1...v14.74.2) (2024-09-25)

### Bug Fixes

* add currency in financial statement ([6becaba](6becaba672))
* AR / AP report to ignore 0.0 outstanding ([79f95ba](79f95ba507))
* **Bank Account:** dashboard connections (backport [#43365](https://github.com/frappe/erpnext/issues/43365)) ([#43366](https://github.com/frappe/erpnext/issues/43366)) ([4146bdf](4146bdf324))
* change dynamic link doctype fieldtype to data ([c0dfda6](c0dfda6ccc))
* incorrect outstanding on non-pos invoice with write_off_account ([79235cd](79235cd688))
* incorrect stock balance for inventory dimension (backport [#43284](https://github.com/frappe/erpnext/issues/43284)) ([#43289](https://github.com/frappe/erpnext/issues/43289)) ([1bdbcc6](1bdbcc6703))
* partial return on POS invoice ([50e0f56](50e0f56d18))
* partial return on POS invoice ([ef7d4fe](ef7d4fe84a))
* Payment Ledger Report currency fieldtype fix ([7ac39dc](7ac39dc233))
* **Payment Reconciliation:** German translations ([32d4f96](32d4f96e02))
* Serial No reserved against historical sales order - unable to sell again ([#43294](https://github.com/frappe/erpnext/issues/43294)) ([8abc1f4](8abc1f4da9))
* show chart tool tip in report currency ([92438f8](92438f8dba))
* translate in js ([e43c357](e43c357c08))
* Translation for button SO to PO ([a8b5bcf](a8b5bcfe02))
* Translation for button SO to PO --conflicts ([b6ce922](b6ce9222aa))
2024-09-25 04:38:46 +00:00
ruthra kumar
644ada8225 Merge pull request #43362 from frappe/version-14-hotfix
chore: release v14
2024-09-25 10:07:32 +05:30
Frappe PR Bot
481610d400 chore(release): Bumped to Version 14.74.1
## [14.74.1](https://github.com/frappe/erpnext/compare/v14.74.0...v14.74.1) (2024-09-18)

### Bug Fixes

* add currency in options for rate field in pricing rule ([c9467f4](c9467f4c1f))
* cancel cost center allocation and journal entry after test ([4646f11](4646f11829))
* delete exchange gain loss journal entry while deleting payment entry ([62f1286](62f12861f1))
* fetch cost center allocation percentage only from the applicable allocation ([a26f0e9](a26f0e9973))
* hide and reset discount control on new POS order ([5434432](5434432cfc))
* invalid gp calculation ([9af2df3](9af2df3810))
2024-09-18 07:32:40 +00:00
ruthra kumar
829a42d679 Merge pull request #43255 from frappe/version-14-hotfix
chore: release v14
2024-09-18 13:01:22 +05:30
Frappe PR Bot
8f02b88119 chore(release): Bumped to Version 14.74.0
# [14.74.0](https://github.com/frappe/erpnext/compare/v14.73.2...v14.74.0) (2024-09-11)

### Bug Fixes

* `default_advance_account` field in Process Payment Reconciliation ([3691a50](3691a500eb))
* bom cost update is not working (backport [#43155](https://github.com/frappe/erpnext/issues/43155)) ([#43156](https://github.com/frappe/erpnext/issues/43156)) ([9110534](91105344bb))
* cancel common party advance jv while canceling the invoice ([f506952](f5069524f3))
* check multi-currency on jv for common party accounting with foreign currency ([a3a40fe](a3a40febf3))
* **Delivery Note:** translatability of validation errors ([5e33961](5e33961448))
* incorrect actual cost in Procurement Tracker report (backport [#43109](https://github.com/frappe/erpnext/issues/43109)) ([#43137](https://github.com/frappe/erpnext/issues/43137)) ([a4b9dda](a4b9dda4b2))
* incorrect qty after transaction in SLE (backport [#43103](https://github.com/frappe/erpnext/issues/43103)) ([#43104](https://github.com/frappe/erpnext/issues/43104)) ([77892f4](77892f4e24))
* return type of `get_party_details` (backport [#43131](https://github.com/frappe/erpnext/issues/43131)) ([#43135](https://github.com/frappe/erpnext/issues/43135)) ([e8aae50](e8aae5018a))
* set today in 'On This Date' in Available Batch Report ([36f65fc](36f65fc592))
* uncomment internal parties ([4dd06b6](4dd06b69a1))
* unreconcile allocation child table redirect url voucher no issue ([53496ed](53496ed79f))

### Features

* utility report to identify invalid ledger entries ([37b8715](37b8715096))
2024-09-11 05:11:21 +00:00
ruthra kumar
a91fb260e1 Merge pull request #43150 from frappe/version-14-hotfix
chore: release v14
2024-09-11 10:39:50 +05:30
Frappe PR Bot
7c37d4c71a chore(release): Bumped to Version 14.73.2
## [14.73.2](https://github.com/frappe/erpnext/compare/v14.73.1...v14.73.2) (2024-09-07)

### Bug Fixes

* incorrect qty after transaction in SLE (backport [#43103](https://github.com/frappe/erpnext/issues/43103)) ([#43104](https://github.com/frappe/erpnext/issues/43104)) ([f054261](f0542613e0))
2024-09-07 12:40:10 +00:00
rohitwaghchaure
873962a109 Merge pull request #43108 from frappe/mergify/bp/version-14/pr-43104
fix: incorrect qty after transaction in SLE (backport #43103) (backport #43104)
2024-09-07 18:08:45 +05:30
mergify[bot]
f0542613e0 fix: incorrect qty after transaction in SLE (backport #43103) (#43104)
fix: incorrect qty after transaction in SLE (#43103)

(cherry picked from commit 5ff87edc85)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 77892f4e24)
2024-09-07 12:05:10 +00:00
Frappe PR Bot
610f74ca62 chore(release): Bumped to Version 14.73.1
## [14.73.1](https://github.com/frappe/erpnext/compare/v14.73.0...v14.73.1) (2024-09-04)

### Bug Fixes

* adjust price insertion logic for internal suppliers/customers ([#42988](https://github.com/frappe/erpnext/issues/42988)) ([3912c68](3912c688ac))
* default fiscal year in report v14 ([#42960](https://github.com/frappe/erpnext/issues/42960)) ([9db7f7b](9db7f7b033))
* Discount and taxes in return document should follow the reference document (backport [#41911](https://github.com/frappe/erpnext/issues/41911)) ([#42573](https://github.com/frappe/erpnext/issues/42573)) ([c55f8e3](c55f8e3388))
* indentation ([e8cfb4d](e8cfb4d602))
* removed extra filter condition ([db319f9](db319f95f1))
* resolve gl entries duplication in asset purchase workflow ([#41845](https://github.com/frappe/erpnext/issues/41845)) ([b3c9697](b3c9697b7c))
* retain date filter when redirecting in Profit and Loss report ([c87f2d2](c87f2d2f7c))
* set up filters for dimensions ([450b3f3](450b3f338e))
* typeerror on Payment Entry ([dda4002](dda4002da4))
* typerror on default_currency ([22b283d](22b283d4a8))
2024-09-04 14:59:27 +00:00
ruthra kumar
012248bd12 Merge pull request #43025 from frappe/version-14-hotfix
chore: release v14
2024-09-04 20:28:07 +05:30
Frappe PR Bot
7648d8db80 chore(release): Bumped to Version 14.73.0
# [14.73.0](https://github.com/frappe/erpnext/compare/v14.72.2...v14.73.0) (2024-08-28)

### Bug Fixes

* call 'process' directly instead of creating 'process_subscripti ([8412938](8412938442))
* currency symbol on `amount` field suppose to show as `Company`'s currency not as default company's currency ([333c757](333c7577eb))
* do not copy date fields in opportunity doctype ([5186872](5186872b9b))
* german translations for incoterms ([003653c](003653c572))
* get amount with taxes and charges from payment entry ([094411f](094411f5f0))
* same posting date and time, creation causing incorrect balance qty (backport [#42904](https://github.com/frappe/erpnext/issues/42904)) ([#42919](https://github.com/frappe/erpnext/issues/42919)) ([c0b5f7c](c0b5f7c8eb))
* specify precision for net_amount ([#39481](https://github.com/frappe/erpnext/issues/39481)) ([cf34219](cf34219c71))
* stock reco with incorrect serial numbers ([#42865](https://github.com/frappe/erpnext/issues/42865)) ([54842ea](54842ea0b3))
* timeout while submitting stock entry (backport [#42929](https://github.com/frappe/erpnext/issues/42929)) ([#42930](https://github.com/frappe/erpnext/issues/42930)) ([73eab91](73eab91631))
* unsupported operand type(s) for *: 'float' and 'NoneType' (backport [#42916](https://github.com/frappe/erpnext/issues/42916)) ([#42917](https://github.com/frappe/erpnext/issues/42917)) ([2f4f2a8](2f4f2a8eec))
* update dimesions in exchange_gain_loss jv based on base document ([820dcd7](820dcd79bb))
* Update get_amount to return currency precision grand total ([0c2d7f2](0c2d7f2d9a))
* use of incorrect attribute ([ff14d72](ff14d72a46))

### Features

* report to identify incorrectly cleared cheques ([c29b95e](c29b95e306))

### Performance Improvements

* data import for stock entries (backport [#42711](https://github.com/frappe/erpnext/issues/42711)) ([#42903](https://github.com/frappe/erpnext/issues/42903)) ([12d5e24](12d5e247c5))
2024-08-28 05:02:39 +00:00
ruthra kumar
578f9b61c6 Merge pull request #42938 from frappe/version-14-hotfix
chore: release v14
2024-08-28 10:31:18 +05:30
Frappe PR Bot
c79088f46a chore(release): Bumped to Version 14.72.2
## [14.72.2](https://github.com/frappe/erpnext/compare/v14.72.1...v14.72.2) (2024-08-21)

### Bug Fixes

* disable rename from warehouse ([ed568fb](ed568fb01d))
* disable rename from warehouse ([a520d06](a520d06c3f))
* **patch:** replace repost with direct sql to update 'against_voucher ([c98ab15](c98ab15a44))
2024-08-21 05:21:14 +00:00
ruthra kumar
d5896cd8a0 Merge pull request #42833 from frappe/version-14-hotfix
chore: release v14
2024-08-21 10:49:56 +05:30
Frappe PR Bot
79edcb2a94 chore(release): Bumped to Version 14.72.1
## [14.72.1](https://github.com/frappe/erpnext/compare/v14.72.0...v14.72.1) (2024-08-16)

### Bug Fixes

* **patch:** replace repost with direct sql to update 'against_voucher ([f6f341a](f6f341ad58))
2024-08-16 11:09:57 +00:00
ruthra kumar
bd2f408f00 Merge pull request #42795 from frappe/mergify/bp/version-14/pr-42791
fix(patch): Use sql to update 'against_voucher' rather than reposting (backport #42791)
2024-08-16 16:38:39 +05:30
ruthra kumar
3b02f80a4e chore: resolve conflict 2024-08-16 16:04:52 +05:30
ruthra kumar
bebd1a0426 chore: update patches.txt
(cherry picked from commit 1721175a20)

# Conflicts:
#	erpnext/patches.txt
2024-08-16 10:26:22 +00:00
ruthra kumar
f6f341ad58 fix(patch): replace repost with direct sql to update 'against_voucher
(cherry picked from commit 13bb48434f)
2024-08-16 10:26:22 +00:00
Frappe PR Bot
2796aa8b57 chore(release): Bumped to Version 14.72.0
# [14.72.0](https://github.com/frappe/erpnext/compare/v14.71.0...v14.72.0) (2024-08-14)

### Bug Fixes

* dimensions in common party journal entry ([b73df8f](b73df8f5f0))
* expense causing p&l test case to fail ([a9fa9e8](a9fa9e86ea))
* force fetch updates for subcription ([f35bc43](f35bc43242))
* german translation of exit ([db27dd8](db27dd8702))
* ledger entries for pos return with update outstanding for self ([714a432](714a432c1c))
* Maintain same rate on qty change on Quotation to Sales Order ([29449cb](29449cbaf9))
* missing def expense if no exp in first month ([7cd6deb](7cd6debd0e))
* patch to fix incorrect against_voucher references in ledger ([5473546](54735469c1))
* pre-commit for better code formatting ([8f19832](8f19832aa5))
* Sort lists before calling itertools.groupby ([29cfb7c](29cfb7cf25))
* test case for zero deferred expense ([186701b](186701b54f))
* text color in sales funnel report based on theme ([2509618](25096185c9))
* typeerror on payment entry ([c4c001b](c4c001b6f9))
* update 'Paid Amount' on forex payment request ([365ef6b](365ef6b88a))
* warning message for negative stock (backport [#42683](https://github.com/frappe/erpnext/issues/42683)) ([#42709](https://github.com/frappe/erpnext/issues/42709)) ([e44daf7](e44daf73fb))

### Features

* changes in opportunity.py to show contacts and addresses from referenced and opportunities ([8d7e150](8d7e150afb))
2024-08-14 08:00:58 +00:00
ruthra kumar
a5ca5b5081 Merge pull request #42744 from frappe/version-14-hotfix
chore: release v14
2024-08-14 13:29:41 +05:30
Frappe PR Bot
a8a8a033a1 chore(release): Bumped to Version 14.71.0
# [14.71.0](https://github.com/frappe/erpnext/compare/v14.70.14...v14.71.0) (2024-08-07)

### Bug Fixes

* 'undefined' in PL and BS report summary on Consolidated report ([a5e1432](a5e14324da))
* company filter for filtring tax withheld vouchers ([b7731c8](b7731c8fd7))
* do not update item price and last purchase rate for inter transf… (backport [#42616](https://github.com/frappe/erpnext/issues/42616)) ([#42632](https://github.com/frappe/erpnext/issues/42632)) ([5c5349e](5c5349ed16))
* filter condition in item-wise purchase register ([bc9b461](bc9b46126b))
* fixed depreciation calculation as per income tax act ([8df1079](8df1079618))
* item_code filter in item-wise sales register ([f0f8a2f](f0f8a2f01b))
* min height for rows in sales funnel ([7086a96](7086a96462))
* set query filters for sales / purchase tax template on PE ([c8d8536](c8d85364b9))
* slowness in reposting dependent vouchers. (backport [#42282](https://github.com/frappe/erpnext/issues/42282)) ([#42569](https://github.com/frappe/erpnext/issues/42569)) ([3fb6f97](3fb6f97f66))

### Features

* expiry date column in Available Batch Report (backport [#42628](https://github.com/frappe/erpnext/issues/42628)) ([#42641](https://github.com/frappe/erpnext/issues/42641)) ([83928bb](83928bbf78))
2024-08-07 09:27:57 +00:00
ruthra kumar
f0230b2dfd Merge pull request #42648 from frappe/version-14-hotfix
chore: release v14
2024-08-07 14:56:41 +05:30
Frappe PR Bot
4089af5a7b chore(release): Bumped to Version 14.70.14
## [14.70.14](https://github.com/frappe/erpnext/compare/v14.70.13...v14.70.14) (2024-08-01)

### Bug Fixes

* slowness in reposting dependent vouchers. (backport [#42282](https://github.com/frappe/erpnext/issues/42282)) ([#42569](https://github.com/frappe/erpnext/issues/42569)) ([cccfbf1](cccfbf193e))
2024-08-01 09:12:20 +00:00
rohitwaghchaure
06c73ef2da Merge pull request #42570 from frappe/mergify/bp/version-14/pr-42569
fix: slowness in reposting dependent vouchers. (backport #42282) (backport #42569)
2024-08-01 14:40:58 +05:30
mergify[bot]
cccfbf193e fix: slowness in reposting dependent vouchers. (backport #42282) (#42569)
fix: slowness in reposting dependent vouchers. (#42282)

(cherry picked from commit b17696a8ae)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
(cherry picked from commit 3fb6f97f66)
2024-08-01 07:52:46 +00:00
Frappe PR Bot
37a7da3371 chore(release): Bumped to Version 14.70.13
## [14.70.13](https://github.com/frappe/erpnext/compare/v14.70.12...v14.70.13) (2024-07-31)

### Bug Fixes

* builtins.KeyError: ('ABC', 'Store - CP') (backport [#42505](https://github.com/frappe/erpnext/issues/42505)) ([#42508](https://github.com/frappe/erpnext/issues/42508)) ([0256c64](0256c64634))
* consider payment entries for checking if tds is deducted ([e7432fc](e7432fc60d))
* dynamic condition in the pricing rule not working (backport [#42467](https://github.com/frappe/erpnext/issues/42467)) ([#42543](https://github.com/frappe/erpnext/issues/42543)) ([53034c3](53034c332b))
* **gross profit:** incorrect valuation rate on different warehouses ([1a7efbb](1a7efbb654))
* ignore duplicates while creating default templates ([99bc8e8](99bc8e849c))
* incorrect cost_center on AR/AP report ([0e2abbd](0e2abbd08e))
* keep status as In Progress for RIV for Timeout Error (backport [#42274](https://github.com/frappe/erpnext/issues/42274)) ([#42504](https://github.com/frappe/erpnext/issues/42504)) ([8e8d0c7](8e8d0c7bd0))
* parenttype in item wise purchase and sales register ([97f2e88](97f2e88f4c))
* performance issue for the report Purchase Order Analysis report (backport [#42503](https://github.com/frappe/erpnext/issues/42503)) ([#42506](https://github.com/frappe/erpnext/issues/42506)) ([f42f1bb](f42f1bb35f))
* price_list_currency not found error (backport [#42534](https://github.com/frappe/erpnext/issues/42534)) ([#42538](https://github.com/frappe/erpnext/issues/42538)) ([3ba6f40](3ba6f40063))
* warehouse filter in Product Bundle Balance (backport [#42532](https://github.com/frappe/erpnext/issues/42532)) ([#42536](https://github.com/frappe/erpnext/issues/42536)) ([0441984](0441984405))
2024-07-31 06:00:37 +00:00
ruthra kumar
81c362dbe4 Merge pull request #42542 from frappe/version-14-hotfix
chore: release v14
2024-07-31 11:29:23 +05:30
Frappe PR Bot
fe4b2e36cc chore(release): Bumped to Version 14.70.12
## [14.70.12](https://github.com/frappe/erpnext/compare/v14.70.11...v14.70.12) (2024-07-24)

### Bug Fixes

* missing cr/dr notes on payment reconciliation ([90ee21f](90ee21f868))
* remove proprietorship and update it with individual (backport [#42307](https://github.com/frappe/erpnext/issues/42307)) ([8c1f619](8c1f6196b8))
* set pos data if not return doc ([6ecb064](6ecb064264))
* Show the rows in AR/AP report where outstanding equals to 0.01 ([2936988](2936988cc6))
2024-07-24 07:26:52 +00:00
ruthra kumar
6759b90f85 Merge pull request #42448 from frappe/version-14-hotfix
chore: release v14
2024-07-24 12:55:36 +05:30
Frappe PR Bot
12a31de25a chore(release): Bumped to Version 14.70.11
## [14.70.11](https://github.com/frappe/erpnext/compare/v14.70.10...v14.70.11) (2024-07-17)

### Bug Fixes

* missing discount on POS Credit Notes ([ac48c3d](ac48c3d4e7))
2024-07-17 05:11:39 +00:00
ruthra kumar
3b9400755e Merge pull request #42353 from frappe/version-14-hotfix
chore: release v14
2024-07-17 10:40:24 +05:30
Frappe PR Bot
1d66b7e5a3 chore(release): Bumped to Version 14.70.10
## [14.70.10](https://github.com/frappe/erpnext/compare/v14.70.9...v14.70.10) (2024-07-10)

### Bug Fixes

* add missing german translations ([d5c1c62](d5c1c62622))
* empty item-wise sales/purchase register reports on initial load ([13895fa](13895fa060))
* fetch expence account from asset category ([4d6a71a](4d6a71ab4b))
* group by in item-wise purchase register ([62ad466](62ad466a3b))
* **Holiday List:** sort holidays on save to avoid disorienting the user (backport [#42236](https://github.com/frappe/erpnext/issues/42236)) ([#42251](https://github.com/frappe/erpnext/issues/42251)) ([fcf6500](fcf6500144))
* manual pick allow to pick more than available stock (backport [#42155](https://github.com/frappe/erpnext/issues/42155)) ([#42158](https://github.com/frappe/erpnext/issues/42158)) ([454e147](454e147592))
* multiple free items on same Item Group ([701dd9e](701dd9e19b))
* removed max discount validation for sales return ([4195c50](4195c50f02))
* stock qty validation in SCR (backport [#42124](https://github.com/frappe/erpnext/issues/42124)) ([#42224](https://github.com/frappe/erpnext/issues/42224)) ([e2f8e02](e2f8e02c73))
* tax on stock_rbnb on repost of Purchase Receipt ([106c154](106c154a16))
* **tds:** use doctype reference when mapping keys across multiple doctypes ([51cbbee](51cbbee4ca))
* updated logic for calculating tax_withholding_net_total in payment entry ([49e5066](49e50662b6))
* use standard method to get `_doc_before_save` ([9fde733](9fde7330e0))
2024-07-10 10:43:56 +00:00
ruthra kumar
ab9bde86f9 Merge pull request #42254 from frappe/version-14-hotfix
chore: release v14
2024-07-10 16:12:40 +05:30
Frappe PR Bot
30cba7ee2c chore(release): Bumped to Version 14.70.9
## [14.70.9](https://github.com/frappe/erpnext/compare/v14.70.8...v14.70.9) (2024-07-05)

### Bug Fixes

* blank item-wise sales/purchase register reports on first load ([0f275a9](0f275a9ff0))
* group by in item-wise purchase register ([1840267](18402677da))
2024-07-05 02:47:14 +00:00
ruthra kumar
21a60c9927 Merge pull request #42190 from frappe/mergify/bp/version-14/pr-41975
fix: group by in item-wise purchase register (backport #41975)
2024-07-05 08:15:53 +05:30
ruthra kumar
0f275a9ff0 fix: blank item-wise sales/purchase register reports on first load 2024-07-05 07:50:37 +05:30
Nihantra C. Patel
18402677da fix: group by in item-wise purchase register
(cherry picked from commit 3fab00135b)
2024-07-05 02:05:26 +00:00
Frappe PR Bot
f2d113dcf2 chore(release): Bumped to Version 14.70.8
## [14.70.8](https://github.com/frappe/erpnext/compare/v14.70.7...v14.70.8) (2024-07-03)

### Bug Fixes

* always post to tax account heads if LCV is booked ([650b25f](650b25fc23))
* asset value correction in fixed asset register ([#41943](https://github.com/frappe/erpnext/issues/41943)) ([a2ee463](a2ee4631cc))
* consistent query field name in item wise purchase register with item wise sales register ([9665212](9665212607))
* **Delivery Note:** only show permitted actions ([0aa246c](0aa246c39e))
* dynamic_link for party in customer and supplier dashboard ([6de7a8d](6de7a8de10))
* incorrect against_account upon reposting ([6028a19](6028a19e6b))
* Re-open allows SO's to be over credit limit ([952a7b4](952a7b46d5))
* **Sales Order:** only show permitted actions ([5468a3b](5468a3b0b7))
* timeout while cancelling LCV ([#42030](https://github.com/frappe/erpnext/issues/42030)) ([21bf7fd](21bf7fd1f8))
2024-07-03 05:02:59 +00:00
ruthra kumar
97e4495f1f Merge pull request #42141 from frappe/version-14-hotfix
chore: release v14
2024-07-03 10:31:45 +05:30
Frappe PR Bot
b593f57637 chore: release v14 (#42023)
* fix(Sales Order): only show permitted actions

(cherry picked from commit c29d955371)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.js

* fix(Delivery Note): only show permitted actions

(cherry picked from commit 418bdc1dcc)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/delivery_note.js

* fix: consistent query field name in item wise purchase register with item wise sales register

* chore: resolve conflicts

* refactor: remove use of can_create for Payment Request (#41647)

(cherry picked from commit 47bc5691a1)

* fix: incorrect against_account upon reposting

(cherry picked from commit 20c4098399)

* fix: asset value correction in fixed asset register (#41943)

* fix: timeout while cancelling LCV (#42030)

fix: timeout while canelling LCV

---------

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
Co-authored-by: ljain112 <ljain112@gmail.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
Co-authored-by: ruthra kumar <ruthra@erpnext.com>
Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2024-06-26 18:02:23 +05:30
Frappe PR Bot
5ae9ec2657 chore(release): Bumped to Version 14.70.7
## [14.70.7](https://github.com/frappe/erpnext/compare/v14.70.6...v14.70.7) (2024-06-19)

### Bug Fixes

* add LCV flag to determine negative expenses ([20b8ee1](20b8ee1e90))
* allow Auditor to read a Fiscal Year ([b1a911a](b1a911aa9c))
* allow Auditor to select a company ([18b6d50](18b6d50a31))
* allow Employee role to select Department (backport [#41877](https://github.com/frappe/erpnext/issues/41877)) ([#41880](https://github.com/frappe/erpnext/issues/41880)) ([245c6d8](245c6d8672))
* migrate lead notes ([8f5278e](8f5278e3d4))
* only show user and date if available ([598c581](598c581623))
* parameters for PI references ([d484553](d48455393e))
* regional overide for updating item valution ([6441bc7](6441bc7862))
* reposting validation related PCV ([bcfc83d](bcfc83d8d5))
* reset perpetual inventory flag after test ([eae5f27](eae5f27ec8))
2024-06-19 06:25:45 +00:00
ruthra kumar
890289563a Merge pull request #41942 from frappe/version-14-hotfix
chore: release v14
2024-06-19 11:54:25 +05:30
Frappe PR Bot
32fba94b2a chore(release): Bumped to Version 14.70.6
## [14.70.6](https://github.com/frappe/erpnext/compare/v14.70.5...v14.70.6) (2024-06-11)

### Bug Fixes

* Add additional condition application ([e79e9e9](e79e9e94d0))
* fixing Item-wise sales register ([5d97c7c](5d97c7cff9))
* fixing Item-wise sales register [#41373](https://github.com/frappe/erpnext/issues/41373) ([ab90b81](ab90b815e3))
* fixing Item-wise sales register and purchase register [#41373](https://github.com/frappe/erpnext/issues/41373) ([ee47440](ee47440063))
* Item-wise Sales and Purchase register with no item codes [#41373](https://github.com/frappe/erpnext/issues/41373) ([bc24e75](bc24e75c24))
* terms and conditions for material request (backport [#41834](https://github.com/frappe/erpnext/issues/41834)) ([#41836](https://github.com/frappe/erpnext/issues/41836)) ([7234625](7234625d65))
2024-06-11 13:07:24 +00:00
rohitwaghchaure
a6ed10b712 Merge pull request #41853 from frappe/version-14-hotfix
chore: release v14
2024-06-11 18:36:07 +05:30
Frappe PR Bot
0c4a2af9ab chore(release): Bumped to Version 14.70.5
## [14.70.5](https://github.com/frappe/erpnext/compare/v14.70.4...v14.70.5) (2024-06-10)

### Bug Fixes

* Add additional condition application ([810378c](810378c899))
* fixing Item-wise sales register ([3823e0e](3823e0e494))
* fixing Item-wise sales register [#41373](https://github.com/frappe/erpnext/issues/41373) ([e8286d7](e8286d7b3c))
* fixing Item-wise sales register and purchase register [#41373](https://github.com/frappe/erpnext/issues/41373) ([fd73a8a](fd73a8a348))
* Item-wise Sales and Purchase register with no item codes [#41373](https://github.com/frappe/erpnext/issues/41373) ([91de469](91de46922d))
2024-06-10 04:55:25 +00:00
Deepesh Garg
5ba0082bc7 Merge pull request #41832 from frappe/mergify/bp/version-14/pr-41829
fix: Item-wise Sales and Purchase register with no item codes (#41424)
2024-06-10 10:24:04 +05:30
Deepesh Garg
47b3e96a37 chore: resolve conflicts
(cherry picked from commit e9b7d00afb)
2024-06-10 04:53:29 +00:00
Deepesh Garg
810378c899 fix: Add additional condition application
(cherry picked from commit 8ec364df6f)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
(cherry picked from commit e79e9e94d0)
2024-06-10 04:53:29 +00:00
Deepesh Garg
bdf198c94f chore: update condition queries in qb
(cherry picked from commit d2af36e1eb)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit e94e15259b)
2024-06-10 04:53:29 +00:00
Poorvi-R-Bhat
e8286d7b3c fix: fixing Item-wise sales register #41373
(cherry picked from commit eafa88b8e9)

# Conflicts:
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit ab90b815e3)
2024-06-10 04:53:29 +00:00
Poorvi-R-Bhat
fd73a8a348 fix: fixing Item-wise sales register and purchase register #41373
(cherry picked from commit 76073ae228)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
(cherry picked from commit ee47440063)
2024-06-10 04:53:29 +00:00
Poorvi-R-Bhat
91de46922d fix: Item-wise Sales and Purchase register with no item codes #41373
(cherry picked from commit 1b45ecfcae)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit bc24e75c24)
2024-06-10 04:53:29 +00:00
Poorvi
3823e0e494 fix: fixing Item-wise sales register
(cherry picked from commit c90185f533)
(cherry picked from commit 5d97c7cff9)
2024-06-10 04:53:28 +00:00
Frappe PR Bot
b6648eebfa chore(release): Bumped to Version 14.70.4
## [14.70.4](https://github.com/frappe/erpnext/compare/v14.70.3...v14.70.4) (2024-06-05)

### Bug Fixes

* Filters in account balance report ([570985f](570985f40e))
* get assets received but not billed account only if any asset item is received ([#41734](https://github.com/frappe/erpnext/issues/41734)) ([39885b2](39885b2b01))
* Ignore disabling default currency field while creating new company (backport [#41699](https://github.com/frappe/erpnext/issues/41699)) ([#41760](https://github.com/frappe/erpnext/issues/41760)) ([5ab5bd1](5ab5bd138f))
* payment term when creating PO from SO (backport [#41376](https://github.com/frappe/erpnext/issues/41376)) ([#41743](https://github.com/frappe/erpnext/issues/41743)) ([dc32657](dc3265751c))
2024-06-05 01:17:52 +00:00
ruthra kumar
faa3c7c3a4 Merge pull request #41774 from frappe/version-14-hotfix
chore: release v14
2024-06-05 06:46:34 +05:30
Frappe PR Bot
13dfbe3d80 chore(release): Bumped to Version 14.70.3
## [14.70.3](https://github.com/frappe/erpnext/compare/v14.70.2...v14.70.3) (2024-05-29)

### Bug Fixes

* add in some indices to speed up Purchase Order deletion ([c16c41e](c16c41ee59))
* Add to Cart button width for Mobile/Tablet ([819ced4](819ced4cb3))
* cost center filter according to the company in project ([7035969](7035969db7))
* cost center filter according to the company in project ([0cf97f2](0cf97f2559))
* cost center filter according to the company in project ([459d136](459d136368))
* dict can not be used as parameter ([#41598](https://github.com/frappe/erpnext/issues/41598)) ([649c192](649c192abe))
* Fetch outstanding and total amount for reference journal entry ([50f6afd](50f6afd588))
* set expense account as Assets RBNB only if it is booked in linked PR ([#41368](https://github.com/frappe/erpnext/issues/41368)) ([014486d](014486de39))
* Update depreciation schedule via asset repair ([#41344](https://github.com/frappe/erpnext/issues/41344)) ([eb418e8](eb418e8659))
2024-05-29 07:52:36 +00:00
ruthra kumar
7e3c15e0b6 Merge pull request #41665 from frappe/version-14-hotfix
chore: release v14
2024-05-29 13:21:18 +05:30
Frappe PR Bot
c910b8ab03 chore(release): Bumped to Version 14.70.2
## [14.70.2](https://github.com/frappe/erpnext/compare/v14.70.1...v14.70.2) (2024-05-23)

### Bug Fixes

* Fetch outstanding and total amount for reference journal entry ([94c3ee6](94c3ee645d))
2024-05-23 11:01:54 +00:00
ruthra kumar
b9ebb50a02 Merge pull request #41600 from frappe/mergify/bp/version-14/pr-40957
fix: Fetch correct outstanding and total amount for reference journal entry (backport #40920) (backport #40957)
2024-05-23 16:30:31 +05:30
ruthra kumar
38cc28a4c3 chore: resolve conflicts
(cherry picked from commit 5230d411bf)
2024-05-23 10:39:16 +00:00
ruthra kumar
bbb9b9e3b6 chore: remove unused imports
(cherry picked from commit a6bf7c1ebd)
2024-05-23 10:39:15 +00:00
Nabin Hait
94c3ee645d fix: Fetch outstanding and total amount for reference journal entry
(cherry picked from commit f331f9b15c)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
#	erpnext/accounts/doctype/payment_entry/payment_entry.py
(cherry picked from commit 50f6afd588)
2024-05-23 10:39:15 +00:00
Frappe PR Bot
b7d6a54bed chore(release): Bumped to Version 14.70.1
## [14.70.1](https://github.com/frappe/erpnext/compare/v14.70.0...v14.70.1) (2024-05-22)

### Bug Fixes

* minor Dr and Cr between Purchase Receipt and Purchase Invoice ([82d206b](82d206b709))
* possible sql error on General Ledger ([dfb4c47](dfb4c47089))
* print format bold for field "total" ([89d507e](89d507e07e))
* priority not working for multiple pricing rules (backport [#41516](https://github.com/frappe/erpnext/issues/41516)) ([#41524](https://github.com/frappe/erpnext/issues/41524)) ([97fdda8](97fdda8a7c))
* typerror on hide_fields ([331a743](331a743d69))
* validate reorder group warehouse (backport [#41478](https://github.com/frappe/erpnext/issues/41478)) ([#41479](https://github.com/frappe/erpnext/issues/41479)) ([2659535](26595351cc))
2024-05-22 08:46:30 +00:00
ruthra kumar
05e4dae1b8 Merge pull request #41575 from frappe/version-14-hotfix
chore: release v14
2024-05-22 14:15:11 +05:30
Frappe PR Bot
dfaca93292 chore(release): Bumped to Version 14.70.0
# [14.70.0](https://github.com/frappe/erpnext/compare/v14.69.1...v14.70.0) (2024-05-15)

### Bug Fixes

* "Based on" field always has the value "Not applicable" ([1078a98](1078a98cce))
* address filter and quotation to for prospect ([c9e7f45](c9e7f450c5))
* address filter and quotation to for prospect ([6902780](690278042d))
* address filter and quotation to for prospect ([754e193](754e193c76))
* consistent use of "Address & Contact" (backport [#41386](https://github.com/frappe/erpnext/issues/41386)) ([#41387](https://github.com/frappe/erpnext/issues/41387)) ([256d6a4](256d6a47ac))
* data getting override in delivery trip (backport [#41431](https://github.com/frappe/erpnext/issues/41431)) ([#41432](https://github.com/frappe/erpnext/issues/41432)) ([5366356](5366356400))
* Default dates in report ([c3244f0](c3244f009b))
* default fiscal year ([7a380f5](7a380f584d))
* Duplicate party name column in AR/AP report ([a8be5f0](a8be5f0789))
* PSOA ageing ([e69e540](e69e5404d3))

### Features

* allow to pick manually qty / batches / serial nos (backport [#40723](https://github.com/frappe/erpnext/issues/40723)) ([#41435](https://github.com/frappe/erpnext/issues/41435)) ([7b28d7d](7b28d7d2b8))
2024-05-15 05:12:14 +00:00
Deepesh Garg
40de3f3481 Merge pull request #41458 from frappe/version-14-hotfix
chore: release v14
2024-05-15 10:40:58 +05:30
Frappe PR Bot
9d5e4b3b3a chore(release): Bumped to Version 14.69.1
## [14.69.1](https://github.com/frappe/erpnext/compare/v14.69.0...v14.69.1) (2024-05-09)

### Bug Fixes

* added brand column in Warehouse wise Item Balance Age and Value … (backport [#41280](https://github.com/frappe/erpnext/issues/41280)) ([#41281](https://github.com/frappe/erpnext/issues/41281)) ([d727c52](d727c52421))
* Cost center not getting saved in PSOA ([e82ea12](e82ea12cbc))
* filter validation for batch-wise balance history report (backport [#41356](https://github.com/frappe/erpnext/issues/41356)) ([#41360](https://github.com/frappe/erpnext/issues/41360)) ([339256b](339256bc71))
* incorrect query for Purchase Invoice rate in GP ([93b30d9](93b30d9f11))
* missing Item Name on Save for Quotation created from Item (backport [#41233](https://github.com/frappe/erpnext/issues/41233)) ([#41303](https://github.com/frappe/erpnext/issues/41303)) ([a26ae64](a26ae64385))
* pricing rule rounding ([d2ce927](d2ce927891))
* reset rate for serial batch supplied items ([#41293](https://github.com/frappe/erpnext/issues/41293)) ([cd33199](cd33199da2))

### Performance Improvements

* index on item code for the Pick List Item doctype (backport [#41357](https://github.com/frappe/erpnext/issues/41357)) ([#41362](https://github.com/frappe/erpnext/issues/41362)) ([4647ec8](4647ec8892))
2024-05-09 05:30:06 +00:00
ruthra kumar
d7709cf4e4 Merge pull request #41354 from frappe/version-14-hotfix
chore: release v14
2024-05-09 10:58:39 +05:30
Frappe PR Bot
5ae29655f9 chore(release): Bumped to Version 14.69.0
# [14.69.0](https://github.com/frappe/erpnext/compare/v14.68.2...v14.69.0) (2024-05-02)

### Bug Fixes

* 'NoneType' object has no attribute '_read_rowdata_packet_unbuffered' ([949aa93](949aa9346c))
* args when get the delivery note in delivery trip ([abe64aa](abe64aa1ab))
* args when get the delivery note in delivery trip ([1a7b3c4](1a7b3c437d))
* display term name for single term invoices ([58b68b7](58b68b7597))
* duplicate column in the stock ledger report ([3fcdcef](3fcdcef178))
* handle stock balance unbuffered_cursor error (backport [#41186](https://github.com/frappe/erpnext/issues/41186)) ([#41187](https://github.com/frappe/erpnext/issues/41187)) ([59010c9](59010c9a61))
* incorrectly applying TDS when Advance is in previous FY ([eb22fb9](eb22fb9326))
* mode of payment has precedance ([33d38ba](33d38ba3a7))
* multiple pricing rules with discount amount and discount percentage not working ([#41211](https://github.com/frappe/erpnext/issues/41211)) ([54313b5](54313b5db9))
* negative stock qty error for stock reconciliation ([#41283](https://github.com/frappe/erpnext/issues/41283)) ([9aa054c](9aa054c400))
* permission issue when user permission restricts on company ([45c4167](45c4167c86))
* validation to prevent overallocation ([8318286](8318286865))

### Features

* allow to do reposting for all stock transactions (audit) (backport [#41165](https://github.com/frappe/erpnext/issues/41165)) ([#41205](https://github.com/frappe/erpnext/issues/41205)) ([1e13193](1e1319351d))

### Performance Improvements

* timeout issue while submitting purchase receipt (v14) ([113351e](113351e850))
2024-05-02 04:31:43 +00:00
ruthra kumar
81a99309d8 Merge pull request #41264 from frappe/version-14-hotfix
chore: release v14
2024-05-02 09:59:30 +05:30
Frappe PR Bot
d160f5b61a chore(release): Bumped to Version 14.68.2
## [14.68.2](https://github.com/frappe/erpnext/compare/v14.68.1...v14.68.2) (2024-04-26)

### Performance Improvements

* timeout issue while submitting purchase receipt (v14) ([c93840e](c93840eb56))
2024-04-26 06:53:19 +00:00
rohitwaghchaure
40ece3f5da Merge pull request #41193 from frappe/mergify/bp/version-14/pr-41174
perf: timeout issue while submitting purchase receipt (v14) (backport #41174)
2024-04-26 12:21:59 +05:30
Rohit Waghchaure
c93840eb56 perf: timeout issue while submitting purchase receipt (v14)
(cherry picked from commit 113351e850)
2024-04-26 05:27:47 +00:00
Frappe PR Bot
2026c986ba chore(release): Bumped to Version 14.68.1
## [14.68.1](https://github.com/frappe/erpnext/compare/v14.68.0...v14.68.1) (2024-04-25)

### Bug Fixes

* mode of payment has precedance ([7e52f72](7e52f72bed))
2024-04-25 03:43:28 +00:00
ruthra kumar
91c202f172 Merge pull request #41179 from frappe/mergify/bp/version-14/pr-41142
fix: mode of payment has precedance in Payment Entry (backport #41142)
2024-04-25 09:12:14 +05:30
ruthra kumar
7e52f72bed fix: mode of payment has precedance
Mode of Payment is given precedence over company/party bank account

(cherry picked from commit 4aef969879)
2024-04-25 09:06:04 +05:30
Frappe PR Bot
30b2cac423 chore(release): Bumped to Version 14.68.0
# [14.68.0](https://github.com/frappe/erpnext/compare/v14.67.2...v14.68.0) (2024-04-24)

### Bug Fixes

* account and stock manager read perm ([03ce9ee](03ce9ee321))
* allow Employee role to select cost center & project (accounting dimensions) (backport [#41160](https://github.com/frappe/erpnext/issues/41160)) ([#41161](https://github.com/frappe/erpnext/issues/41161)) ([bb48440](bb48440591))
* do not add actual expense twice for validating budget ([ec4f07f](ec4f07fd60))
* don't attempt to set gender from salutation (backport [#40997](https://github.com/frappe/erpnext/issues/40997)) ([#41072](https://github.com/frappe/erpnext/issues/41072)) ([5d05bf8](5d05bf8d4e))
* Missing args while fetching items from delivery note ([0df80ad](0df80ad923))
* Multiple partial payment requests against Purchase Invoice ([f1b75e8](f1b75e8c54))
* Party type in Payment Order ([a2e1d13](a2e1d132df))
* Permission for lower dedcution certificate ([a22be6f](a22be6f9b9))
* Test case ([5aef9d2](5aef9d2ef2))
* validate uom is integer for PR item (backport [#41074](https://github.com/frappe/erpnext/issues/41074)) ([#41076](https://github.com/frappe/erpnext/issues/41076)) ([9d0c1dc](9d0c1dc46f))

### Features

* Available batches report as on specific date ([8868cb1](8868cb147d))
* show expense breakup ([f087ec8](f087ec8df5))

### Performance Improvements

* stock ageing and batch-wise balance history report ([6017e7a](6017e7ac3e))
2024-04-24 07:32:43 +00:00
Deepesh Garg
67be2ba9dc Merge pull request #41151 from frappe/version-14-hotfix
chore: release v14
2024-04-24 13:01:19 +05:30
Frappe PR Bot
84789b7407 chore(release): Bumped to Version 14.67.2
## [14.67.2](https://github.com/frappe/erpnext/compare/v14.67.1...v14.67.2) (2024-04-17)

### Bug Fixes

* barcode not fetched on selection of item (backport [#40814](https://github.com/frappe/erpnext/issues/40814)) ([#41027](https://github.com/frappe/erpnext/issues/41027)) ([0bee921](0bee921d40))
* Delayed Order Report not working (backport [#41037](https://github.com/frappe/erpnext/issues/41037)) ([#41038](https://github.com/frappe/erpnext/issues/41038)) ([e956dbb](e956dbbf68))
* Don't call get_fiscal_year if setup is not done yet ([59cea9f](59cea9f4dd))
* Don't set delivery date as today while making SO from Quotation ([b47e224](b47e224a1c))
* exclude some query builder lines from ruff rules ([2425119](2425119b5e))
* expense account set as COGS for stock entry Material Issue (backport [#41026](https://github.com/frappe/erpnext/issues/41026)) ([#41028](https://github.com/frappe/erpnext/issues/41028)) ([153e0ba](153e0ba81b))
* get address if multiple companies ([c2b6b64](c2b6b64e2e))
* get address if multiple companies ([0493872](04938726d9))
* **gp:** SLEs not fetched for correct warehouse ([97e7b3f](97e7b3f3d3))
* incorrect exc gain/loss for PE against JE for payable accounts ([50a74ee](50a74ee7fe))
* Resolve merge conflicts ([cc925ae](cc925ae938))
* Subcontracting Receipt GL Entries (backport [#40773](https://github.com/frappe/erpnext/issues/40773)) ([#40978](https://github.com/frappe/erpnext/issues/40978)) ([c2c4548](c2c4548cc0))
* test cases ([79e23da](79e23dad2c))
* **treewide:** manual ruff fixes ([b087fb3](b087fb3d54))
* use 'eq' and isnull() on qb conditions ([b4ed2d2](b4ed2d2c16))
2024-04-17 06:12:30 +00:00
rohitwaghchaure
cd70c6c1b2 Merge pull request #41032 from frappe/version-14-hotfix
chore: release v14
2024-04-17 11:41:15 +05:30
149 changed files with 5497 additions and 2983 deletions

View File

@@ -9,15 +9,16 @@ jobs:
name: linters
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: Set up Python 3.10
uses: actions/setup-python@v2
uses: actions/setup-python@v4
with:
python-version: '3.10'
cache: pip
- name: Install and Run Pre-commit
uses: pre-commit/action@v2.0.3
uses: pre-commit/action@v3.0.0
- name: Download Semgrep rules
run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules

View File

@@ -1,5 +1,5 @@
exclude: 'node_modules|.git'
default_stages: [commit]
default_stages: [pre-commit]
fail_fast: false

View File

@@ -3,7 +3,7 @@ import inspect
import frappe
__version__ = "14.67.1"
__version__ = "14.92.0"
def get_default_company(user=None):

View File

@@ -3,4 +3,14 @@
frappe.ui.form.on("Accounts Settings", {
refresh: function (frm) {},
drop_ar_procedures: function (frm) {
frm.call({
doc: frm.doc,
method: "drop_ar_sql_procedures",
callback: function (r) {
frappe.show_alert(__("Procedures dropped"), 5);
},
});
},
});

View File

@@ -73,9 +73,14 @@
"reports_tab",
"remarks_section",
"general_ledger_remarks_length",
"ignore_is_opening_check_for_reporting",
"column_break_lvjk",
"receivable_payable_remarks_length"
"receivable_payable_remarks_length",
"accounts_receivable_payable_tuning_section",
"receivable_payable_fetch_method",
"column_break_ntmi",
"drop_ar_procedures",
"legacy_section",
"ignore_is_opening_check_for_reporting"
],
"fields": [
{
@@ -479,6 +484,34 @@
"fieldname": "ignore_is_opening_check_for_reporting",
"fieldtype": "Check",
"label": "Ignore Is Opening check for reporting"
},
{
"default": "Buffered Cursor",
"fieldname": "receivable_payable_fetch_method",
"fieldtype": "Select",
"label": "Data Fetch Method",
"options": "Buffered Cursor\nUnBuffered Cursor\nRaw SQL"
},
{
"fieldname": "accounts_receivable_payable_tuning_section",
"fieldtype": "Section Break",
"label": "Accounts Receivable / Payable Tuning"
},
{
"fieldname": "legacy_section",
"fieldtype": "Section Break",
"label": "Legacy Fields"
},
{
"fieldname": "column_break_ntmi",
"fieldtype": "Column Break"
},
{
"depends_on": "eval:doc.receivable_payable_fetch_method == \"Raw SQL\"",
"description": "Drops existing SQL Procedures and Function setup by Accounts Receivable report",
"fieldname": "drop_ar_procedures",
"fieldtype": "Button",
"label": "Drop Procedures"
}
],
"icon": "icon-cog",
@@ -486,7 +519,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2025-01-23 13:15:44.077853",
"modified": "2025-05-05 12:29:38.302027",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
@@ -515,4 +548,4 @@
"sort_order": "ASC",
"states": [],
"track_changes": 1
}
}

View File

@@ -65,3 +65,11 @@ class AccountsSettings(Document):
def validate_pending_reposts(self):
if self.acc_frozen_upto:
check_pending_reposting(self.acc_frozen_upto)
@frappe.whitelist()
def drop_ar_sql_procedures(self):
from erpnext.accounts.report.accounts_receivable.accounts_receivable import InitSQLProceduresForAR
frappe.db.sql(f"drop function if exists {InitSQLProceduresForAR.genkey_function_name}")
frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.init_procedure_name}")
frappe.db.sql(f"drop procedure if exists {InitSQLProceduresForAR.allocate_procedure_name}")

View File

@@ -46,9 +46,6 @@ class BankClearance(Document):
as_dict=1,
)
if self.bank_account:
condition += "and bank_account = %(bank_account)s"
payment_entries = frappe.db.sql(
f"""
select
@@ -70,7 +67,6 @@ class BankClearance(Document):
"account": self.account,
"from": self.from_date,
"to": self.to_date,
"bank_account": self.bank_account,
},
as_dict=1,
)
@@ -93,7 +89,7 @@ class BankClearance(Document):
.where(loan_disbursement.docstatus == 1)
.where(loan_disbursement.disbursement_date >= self.from_date)
.where(loan_disbursement.disbursement_date <= self.to_date)
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
.where(loan_disbursement.disbursement_account == self.account)
.orderby(loan_disbursement.disbursement_date)
.orderby(loan_disbursement.name, order=frappe.qb.desc)
)
@@ -121,7 +117,7 @@ class BankClearance(Document):
.where(loan_repayment.docstatus == 1)
.where(loan_repayment.posting_date >= self.from_date)
.where(loan_repayment.posting_date <= self.to_date)
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
.where(loan_repayment.payment_account == self.account)
)
if not self.include_reconciled_entries:

View File

@@ -6,7 +6,11 @@ import unittest
import frappe
from frappe.utils import now_datetime, nowdate
from erpnext.accounts.doctype.budget.budget import BudgetError, get_actual_expense
from erpnext.accounts.doctype.budget.budget import (
BudgetError,
get_accumulated_monthly_budget,
get_actual_expense,
)
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
from erpnext.accounts.utils import get_fiscal_year
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
@@ -96,6 +100,10 @@ class TestBudget(unittest.TestCase):
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
frappe.db.set_value("Budget", budget.name, "fiscal_year", fiscal_year)
accumulated_limit = get_accumulated_monthly_budget(
budget.monthly_distribution, nowdate(), budget.fiscal_year, budget.accounts[0].budget_amount
)
mr = frappe.get_doc(
{
"doctype": "Material Request",
@@ -109,7 +117,7 @@ class TestBudget(unittest.TestCase):
"uom": "_Test UOM",
"warehouse": "_Test Warehouse - _TC",
"schedule_date": nowdate(),
"rate": 100000,
"rate": accumulated_limit + 1,
"expense_account": "_Test Account Cost for Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
}

View File

@@ -448,9 +448,8 @@ def unset_existing_data(company):
"Sales Taxes and Charges Template",
"Purchase Taxes and Charges Template",
]:
frappe.db.sql(
f'''delete from `tab{doctype}` where `company`="%s"''' % (company) # nosec
)
dt = frappe.qb.DocType(doctype)
frappe.qb.from_(dt).where(dt.company == company).delete().run()
def set_default_accounts(company):

View File

@@ -4,6 +4,8 @@
import unittest
import frappe
from frappe.query_builder.functions import Sum
from frappe.tests.utils import change_settings
from frappe.utils import add_days, today
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
@@ -190,6 +192,31 @@ class TestCostCenterAllocation(unittest.TestCase):
coa2.cancel()
jv.cancel()
@change_settings("System Settings", {"rounding_method": "Commercial Rounding"})
def test_debit_credit_on_cost_center_allocation_for_commercial_rounding(self):
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
cca = create_cost_center_allocation(
"_Test Company",
"Main Cost Center 1 - _TC",
{"Sub Cost Center 2 - _TC": 50, "Sub Cost Center 3 - _TC": 50},
)
si = create_sales_invoice(rate=145.65, cost_center="Main Cost Center 1 - _TC")
gl_entry = frappe.qb.DocType("GL Entry")
gl_entries = (
frappe.qb.from_(gl_entry)
.select(Sum(gl_entry.credit).as_("cr"), Sum(gl_entry.debit).as_("dr"))
.where(gl_entry.voucher_type == "Sales Invoice")
.where(gl_entry.voucher_no == si.name)
).run(as_dict=1)
self.assertEqual(gl_entries[0].cr, gl_entries[0].dr)
si.cancel()
cca.cancel()
def create_cost_center_allocation(
company,

View File

@@ -55,46 +55,46 @@ class Dunning(AccountsController):
"conversion_rate",
"cost_center",
]
inv = frappe.db.get_value("Sales Invoice", self.sales_invoice, invoice_fields, as_dict=1)
accounting_dimensions = get_accounting_dimensions()
invoice_fields.extend(accounting_dimensions)
inv = frappe.db.get_value("Sales Invoice", self.sales_invoice, invoice_fields, as_dict=1)
dunning_in_company_currency = flt(self.dunning_amount * inv.conversion_rate)
default_cost_center = frappe.get_cached_value("Company", self.company, "cost_center")
gl_entries.append(
self.get_gl_dict(
{
"account": inv.debit_to,
"party_type": "Customer",
"party": self.customer,
"due_date": self.due_date,
"against": self.income_account,
"debit": dunning_in_company_currency,
"debit_in_account_currency": self.dunning_amount,
"against_voucher": self.name,
"against_voucher_type": "Dunning",
"cost_center": inv.cost_center or default_cost_center,
"project": inv.project,
},
inv.party_account_currency,
item=inv,
)
)
gl_entries.append(
self.get_gl_dict(
{
"account": self.income_account,
"against": self.customer,
"credit": dunning_in_company_currency,
"cost_center": inv.cost_center or default_cost_center,
"credit_in_account_currency": self.dunning_amount,
"project": inv.project,
},
item=inv,
)
)
debit = {
"account": inv.debit_to,
"party_type": "Customer",
"party": self.customer,
"due_date": self.due_date,
"against": self.income_account,
"debit": dunning_in_company_currency,
"debit_in_account_currency": self.dunning_amount,
"against_voucher": self.name,
"against_voucher_type": "Dunning",
"cost_center": inv.cost_center or default_cost_center,
"project": inv.project,
}
credit = {
"account": self.income_account,
"against": self.customer,
"credit": dunning_in_company_currency,
"credit_in_account_currency": self.dunning_amount,
"cost_center": inv.cost_center or default_cost_center,
"project": inv.project,
}
for dimension in accounting_dimensions:
if val := inv.get(dimension):
debit[dimension] = credit[dimension] = val
gl_entries = [
self.get_gl_dict(debit, inv.party_account_currency, item=inv),
self.get_gl_dict(credit, item=inv),
]
make_gl_entries(
gl_entries, cancel=(self.docstatus == 2), update_outstanding="No", merge_entries=False
)

View File

@@ -7,7 +7,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.model.meta import get_field_precision
from frappe.model.naming import set_name_from_naming_options
from frappe.utils import flt, fmt_money
from frappe.utils import flt, fmt_money, now
import erpnext
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
@@ -261,7 +261,7 @@ def validate_balance_type(account, adv_adj=False):
if balance_must_be:
balance = frappe.db.sql(
"""select sum(debit) - sum(credit)
from `tabGL Entry` where account = %s""",
from `tabGL Entry` where is_cancelled = 0 and account = %s""",
account,
)[0][0]
@@ -405,7 +405,7 @@ def rename_temporarily_named_docs(doctype):
set_name_from_naming_options(frappe.get_meta(doctype).autoname, doc)
newname = doc.name
frappe.db.sql(
f"UPDATE `tab{doctype}` SET name = %s, to_rename = 0 where name = %s",
(newname, oldname),
f"UPDATE `tab{doctype}` SET name = %s, to_rename = 0, modified = %s where name = %s",
(newname, now(), oldname),
auto_commit=True,
)

View File

@@ -197,7 +197,7 @@ frappe.ui.form.on("Invoice Discounting", {
from_date: frm.doc.posting_date,
to_date: moment(frm.doc.modified).format("YYYY-MM-DD"),
company: frm.doc.company,
group_by: "Group by Voucher (Consolidated)",
categorize_by: "Categorize by Voucher (Consolidated)",
show_cancelled_entries: frm.doc.docstatus === 2,
};
frappe.set_route("query-report", "General Ledger");

View File

@@ -34,7 +34,7 @@ frappe.ui.form.on("Journal Entry", {
to_date: moment(frm.doc.modified).format("YYYY-MM-DD"),
company: frm.doc.company,
finance_book: frm.doc.finance_book,
group_by: "",
categorize_by: "",
show_cancelled_entries: frm.doc.docstatus === 2,
};
frappe.set_route("query-report", "General Ledger");

View File

@@ -5,6 +5,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.utils import flt, today
@@ -18,22 +19,30 @@ def get_loyalty_details(
if not expiry_date:
expiry_date = today()
condition = ""
if company:
condition = " and company=%s " % frappe.db.escape(company)
if not include_expired_entry:
condition += " and expiry_date>='%s' " % expiry_date
LoyaltyPointEntry = frappe.qb.DocType("Loyalty Point Entry")
loyalty_point_details = frappe.db.sql(
f"""select sum(loyalty_points) as loyalty_points,
sum(purchase_amount) as total_spent from `tabLoyalty Point Entry`
where customer=%s and loyalty_program=%s and posting_date <= %s
{condition}
group by customer""",
(customer, loyalty_program, expiry_date),
as_dict=1,
query = (
frappe.qb.from_(LoyaltyPointEntry)
.select(
Sum(LoyaltyPointEntry.loyalty_points).as_("loyalty_points"),
Sum(LoyaltyPointEntry.purchase_amount).as_("total_spent"),
)
.where(
(LoyaltyPointEntry.customer == customer)
& (LoyaltyPointEntry.loyalty_program == loyalty_program)
& (LoyaltyPointEntry.posting_date <= expiry_date)
)
.groupby(LoyaltyPointEntry.customer)
)
if company:
query = query.where(LoyaltyPointEntry.company == company)
if not include_expired_entry:
query = query.where(LoyaltyPointEntry.expiry_date >= expiry_date)
loyalty_point_details = query.run(as_dict=True)
if loyalty_point_details:
return loyalty_point_details[0]
else:

View File

@@ -60,6 +60,6 @@ def create_party_link(primary_role, primary_party, secondary_party):
party_link.secondary_role = "Customer" if primary_role == "Supplier" else "Supplier"
party_link.secondary_party = secondary_party
party_link.save(ignore_permissions=True)
party_link.save()
return party_link

View File

@@ -319,7 +319,7 @@ frappe.ui.form.on('Payment Entry', {
"from_date": frm.doc.posting_date,
"to_date": moment(frm.doc.modified).format('YYYY-MM-DD'),
"company": frm.doc.company,
"group_by": "",
"categorize_by": "",
"show_cancelled_entries": frm.doc.docstatus === 2
};
frappe.set_route("query-report", "General Ledger");
@@ -330,7 +330,7 @@ frappe.ui.form.on('Payment Entry', {
payment_type: function(frm) {
set_default_party_type(frm);
if(frm.doc.payment_type == "Internal Transfer") {
$.each(["party", "party_balance", "paid_from", "paid_to",
$.each(["party", "party_type", "party_balance", "paid_from", "paid_to",
"references", "total_allocated_amount"], function(i, field) {
frm.set_value(field, null);
});

View File

@@ -350,15 +350,25 @@ class PaymentEntry(AccountsController):
self.set(self.party_account_field, party_account)
self.party_account = party_account
if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
if self.paid_from and (
not self.paid_from_account_currency
or not self.paid_from_account_balance
or not self.paid_from_account_type
):
acc = get_account_details(self.paid_from, self.posting_date, self.cost_center)
self.paid_from_account_currency = acc.account_currency
self.paid_from_account_balance = acc.account_balance
self.paid_from_account_type = acc.account_type
if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
if self.paid_to and (
not self.paid_to_account_currency
or not self.paid_to_account_balance
or not self.paid_to_account_type
):
acc = get_account_details(self.paid_to, self.posting_date, self.cost_center)
self.paid_to_account_currency = acc.account_currency
self.paid_to_account_balance = acc.account_balance
self.paid_to_account_type = acc.account_type
self.party_account_currency = (
self.paid_from_account_currency
@@ -1580,7 +1590,7 @@ class PaymentEntry(AccountsController):
# Re allocate amount to those references which have PR set (Higher priority)
for ref in self.references:
if not ref.payment_request:
if not (ref.reference_doctype and ref.reference_name and ref.payment_request):
continue
# fetch outstanding_amount of `Reference` (Payment Term) and `Payment Request` to allocate new amount
@@ -1631,7 +1641,7 @@ class PaymentEntry(AccountsController):
)
# Re allocate amount to those references which have no PR (Lower priority)
for ref in self.references:
if ref.payment_request:
if ref.payment_request or not (ref.reference_doctype and ref.reference_name):
continue
key = (ref.reference_doctype, ref.reference_name, ref.get("payment_term"))

View File

@@ -10,14 +10,19 @@
"description",
"section_break_4",
"due_date",
"invoice_portion",
"mode_of_payment",
"column_break_5",
"invoice_portion",
"due_date_based_on",
"credit_days",
"credit_months",
"section_break_6",
"discount_type",
"discount_date",
"column_break_9",
"discount",
"discount_type",
"column_break_9",
"discount_validity_based_on",
"discount_validity",
"section_break_9",
"payment_amount",
"outstanding",
@@ -155,12 +160,50 @@
"fieldtype": "Currency",
"label": "Payment Amount (Company Currency)",
"options": "Company:company:default_currency"
},
{
"fieldname": "due_date_based_on",
"fieldtype": "Select",
"label": "Due Date Based On",
"options": "\nDay(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
"read_only": 1
},
{
"depends_on": "eval:in_list(['Day(s) after invoice date', 'Day(s) after the end of the invoice month'], doc.due_date_based_on)",
"fieldname": "credit_days",
"fieldtype": "Int",
"label": "Credit Days",
"non_negative": 1,
"read_only": 1
},
{
"depends_on": "eval:doc.due_date_based_on=='Month(s) after the end of the invoice month'",
"fieldname": "credit_months",
"fieldtype": "Int",
"label": "Credit Months",
"non_negative": 1,
"read_only": 1
},
{
"depends_on": "discount",
"fieldname": "discount_validity_based_on",
"fieldtype": "Select",
"label": "Discount Validity Based On",
"options": "\nDay(s) after invoice date\nDay(s) after the end of the invoice month\nMonth(s) after the end of the invoice month",
"read_only": 1
},
{
"depends_on": "discount_validity_based_on",
"fieldname": "discount_validity",
"fieldtype": "Int",
"label": "Discount Validity",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-09-16 13:57:06.382859",
"modified": "2025-07-31 08:38:25.820701",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Schedule",
@@ -171,4 +214,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -161,4 +161,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

@@ -29,7 +29,7 @@ frappe.ui.form.on("Period Closing Voucher", {
from_date: frm.doc.posting_date,
to_date: moment(frm.doc.modified).format("YYYY-MM-DD"),
company: frm.doc.company,
group_by: "",
categorize_by: "",
show_cancelled_entries: frm.doc.docstatus === 2,
};
frappe.set_route("query-report", "General Ledger");

View File

@@ -32,8 +32,13 @@ class PeriodClosingVoucher(AccountsController):
def on_cancel(self):
self.validate_future_closing_vouchers()
self.ignore_linked_doctypes = (
"GL Entry",
"Stock Ledger Entry",
"Payment Ledger Entry",
"Account Closing Balance",
)
self.db_set("gle_processing_status", "In Progress")
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Payment Ledger Entry")
gle_count = frappe.db.count(
"GL Entry",
{"voucher_type": "Period Closing Voucher", "voucher_no": self.name, "is_cancelled": 0},
@@ -201,6 +206,9 @@ class PeriodClosingVoucher(AccountsController):
return gl_entry
def get_gle_for_closing_account(self, acc):
debit = abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0
credit = abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0
gl_entry = self.get_gl_dict(
{
"company": self.company,
@@ -209,16 +217,10 @@ class PeriodClosingVoucher(AccountsController):
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) > 0
else 0,
"debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) < 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) < 0
else 0,
"debit_in_account_currency": debit,
"debit": debit,
"credit_in_account_currency": credit,
"credit": credit,
"is_period_closing_voucher_entry": 1,
},
item=acc,

View File

@@ -560,7 +560,13 @@ class POSInvoice(SalesInvoice):
"Account", self.debit_to, "account_currency", cache=True
)
if not self.due_date and self.customer:
self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company)
self.due_date = get_due_date(
self.posting_date,
"Customer",
self.customer,
self.company,
template_name=self.payment_terms_template,
)
super(SalesInvoice, self).set_missing_values(for_validate)

View File

@@ -12,7 +12,7 @@
"posting_date",
"company",
"account",
"group_by",
"categorize_by",
"cost_center",
"territory",
"ignore_exchange_rate_revaluation_journals",
@@ -172,14 +172,6 @@
"fieldtype": "Date",
"label": "Start Date"
},
{
"default": "Group by Voucher (Consolidated)",
"depends_on": "eval:(doc.report == 'General Ledger');",
"fieldname": "group_by",
"fieldtype": "Select",
"label": "Group By",
"options": "\nGroup by Voucher\nGroup by Voucher (Consolidated)"
},
{
"depends_on": "eval: (doc.report == 'General Ledger');",
"fieldname": "currency",
@@ -395,10 +387,18 @@
"fieldname": "show_remarks",
"fieldtype": "Check",
"label": "Show Remarks"
},
{
"default": "Categorize by Voucher (Consolidated)",
"depends_on": "eval:(doc.report == 'General Ledger');",
"fieldname": "categorize_by",
"fieldtype": "Select",
"label": "Categorize By",
"options": "\nCategorize by Voucher\nCategorize by Voucher (Consolidated)"
}
],
"links": [],
"modified": "2024-10-18 17:51:39.108481",
"modified": "2025-04-30 14:43:23.643006",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Statement Of Accounts",
@@ -433,4 +433,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

@@ -145,7 +145,7 @@ def get_gl_filters(doc, entry, tax_id, presentation_currency):
"party": [entry.customer],
"party_name": [entry.customer_name] if entry.customer_name else None,
"presentation_currency": presentation_currency,
"group_by": doc.group_by,
"categorize_by": doc.categorize_by,
"currency": doc.currency,
"project": [p.project_name for p in doc.project],
"show_opening_entries": 0,

View File

@@ -29,7 +29,10 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
this.frm.set_query("expense_account", "items", function () {
return {
query: "erpnext.controllers.queries.get_expense_account",
filters: { company: doc.company },
filters: {
company: doc.company,
disabled: 0,
},
};
});
}

View File

@@ -173,7 +173,12 @@ class PurchaseInvoice(BuyingController):
)
if not self.due_date:
self.due_date = get_due_date(
self.posting_date, "Supplier", self.supplier, self.company, self.bill_date
self.posting_date,
"Supplier",
self.supplier,
self.company,
self.bill_date,
template_name=self.payment_terms_template,
)
tds_category = frappe.db.get_value("Supplier", self.supplier, "tax_withholding_category")
@@ -781,7 +786,7 @@ class PurchaseInvoice(BuyingController):
self.get_provisional_accounts()
for item in self.get("items"):
if flt(item.base_net_amount):
if flt(item.base_net_amount) or (self.get("update_stock") and item.valuation_rate):
account_currency = get_account_currency(item.expense_account)
if item.item_code:
frappe.get_cached_value("Item", item.item_code, "asset_category")
@@ -1016,6 +1021,9 @@ class PurchaseInvoice(BuyingController):
def get_provisional_accounts(self):
self.provisional_accounts = frappe._dict()
linked_purchase_receipts = set([d.purchase_receipt for d in self.items if d.purchase_receipt])
if not linked_purchase_receipts:
return
pr_items = frappe.get_all(
"Purchase Receipt Item",
filters={"parent": ("in", linked_purchase_receipts)},
@@ -1124,6 +1132,30 @@ class PurchaseInvoice(BuyingController):
warehouse_debit_amount = stock_amount
elif self.is_return and self.update_stock and (self.is_internal_supplier or not self.return_against):
net_rate = item.base_net_amount
stock_amount = net_rate + item.item_tax_amount + flt(item.landed_cost_voucher_amount)
if flt(stock_amount, net_amt_precision) != flt(warehouse_debit_amount, net_amt_precision):
cost_of_goods_sold_account = self.get_company_default("default_expense_account")
stock_adjustment_amt = stock_amount - warehouse_debit_amount
gl_entries.append(
self.get_gl_dict(
{
"account": cost_of_goods_sold_account,
"against": item.expense_account,
"debit": stock_adjustment_amt,
"debit_in_transaction_currency": stock_adjustment_amt / self.conversion_rate,
"remarks": self.get("remarks") or _("Stock Adjustment"),
"cost_center": item.cost_center,
"project": item.project or self.project,
},
account_currency,
item=item,
)
)
return warehouse_debit_amount
def make_tax_gl_entries(self, gl_entries):

View File

@@ -1816,19 +1816,16 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
rate = flt(sle.stock_value_difference) / flt(sle.actual_qty)
self.assertAlmostEqual(rate, 500)
@change_settings("Accounts Settings", {"automatically_fetch_payment_terms": 1})
def test_payment_allocation_for_payment_terms(self):
from erpnext.buying.doctype.purchase_order.test_purchase_order import (
create_pr_against_po,
create_purchase_order,
)
from erpnext.selling.doctype.sales_order.test_sales_order import (
automatically_fetch_payment_terms,
)
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
make_purchase_invoice as make_pi_from_pr,
)
automatically_fetch_payment_terms()
frappe.db.set_value(
"Payment Terms Template",
"_Test Payment Term Template",
@@ -1852,9 +1849,8 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
1,
)
pi = make_pi_from_pr(pr.name)
self.assertEqual(pi.payment_schedule[0].payment_amount, 2500)
self.assertEqual(pi.payment_schedule[0].payment_amount, 1000)
automatically_fetch_payment_terms(enable=0)
frappe.db.set_value(
"Payment Terms Template",
"_Test Payment Term Template",
@@ -1984,6 +1980,78 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
self.assertRaises(frappe.ValidationError, dr_note.save)
def test_apply_discount_on_grand_total(self):
"""
To test if after applying discount on grand total,
the grand total is calculated correctly without any rounding errors
"""
invoice = make_purchase_invoice(qty=2, rate=100, do_not_save=True, do_not_submit=True)
invoice.append(
"items",
{
"item_code": "_Test Item",
"qty": 1,
"rate": 21.39,
},
)
invoice.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "_Test Account VAT - _TC",
"description": "VAT",
"rate": 15.5,
},
)
# the grand total here will be 255.71
invoice.disable_rounded_total = 1
# apply discount on grand total to adjust the grand total to 255
invoice.discount_amount = 0.71
invoice.save()
# check if grand total is 496 and not something like 254.99 due to rounding errors
self.assertEqual(invoice.grand_total, 255)
def test_apply_discount_on_grand_total_with_previous_row_total_tax(self):
"""
To test if after applying discount on grand total,
where the tax is calculated on previous row total, the grand total is calculated correctly
"""
invoice = make_purchase_invoice(qty=2, rate=100, do_not_save=True, do_not_submit=True)
invoice.extend(
"taxes",
[
{
"charge_type": "Actual",
"account_head": "_Test Account VAT - _TC",
"description": "VAT",
"tax_amount": 100,
},
{
"charge_type": "On Previous Row Amount",
"account_head": "_Test Account VAT - _TC",
"description": "VAT",
"row_id": 1,
"rate": 10,
},
{
"charge_type": "On Previous Row Total",
"account_head": "_Test Account VAT - _TC",
"description": "VAT",
"row_id": 1,
"rate": 10,
},
],
)
# the total here will be 340, so applying 40 discount
invoice.discount_amount = 40
invoice.save()
self.assertEqual(invoice.grand_total, 300)
def check_gl_entries(
doc,

View File

@@ -151,7 +151,7 @@ def start_repost(account_repost_doc=str) -> None:
if doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
if not repost_doc.delete_cancelled_entries:
doc.docstatus = 2
doc.make_gl_entries_on_cancel()
doc.make_gl_entries_on_cancel(from_repost=True)
doc.docstatus = 1
if doc.doctype == "Sales Invoice":
@@ -163,7 +163,7 @@ def start_repost(account_repost_doc=str) -> None:
elif doc.doctype == "Purchase Receipt":
if not repost_doc.delete_cancelled_entries:
doc.docstatus = 2
doc.make_gl_entries_on_cancel()
doc.make_gl_entries_on_cancel(from_repost=True)
doc.docstatus = 1
doc.make_gl_entries(from_repost=True)

View File

@@ -91,8 +91,8 @@ class SalesInvoice(SellingController):
self.indicator_title = _("Paid")
def validate(self):
super().validate()
self.validate_auto_set_posting_time()
super().validate()
if not (self.is_pos or self.is_debit_note):
self.so_dn_required()
@@ -498,7 +498,13 @@ class SalesInvoice(SellingController):
"Account", self.debit_to, "account_currency", cache=True
)
if not self.due_date and self.customer:
self.due_date = get_due_date(self.posting_date, "Customer", self.customer, self.company)
self.due_date = get_due_date(
self.posting_date,
"Customer",
self.customer,
self.company,
template_name=self.payment_terms_template,
)
super().set_missing_values(for_validate)
@@ -1019,7 +1025,6 @@ class SalesInvoice(SellingController):
self.make_exchange_gain_loss_journal()
elif self.docstatus == 2:
cancel_exchange_gain_loss_journal(frappe._dict(doctype=self.doctype, name=self.name))
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
if update_outstanding == "No":

View File

@@ -416,9 +416,9 @@ class TestSalesInvoice(FrappeTestCase):
for i, k in enumerate(expected_values["keys"]):
self.assertEqual(d.get(k), expected_values[d.account_head][i])
self.assertEqual(si.base_grand_total, 1500.01)
self.assertEqual(si.grand_total, 1500.01)
self.assertEqual(si.rounding_adjustment, -0.01)
self.assertEqual(si.base_grand_total, 1500)
self.assertEqual(si.grand_total, 1500)
self.assertEqual(si.rounding_adjustment, 0)
def test_discount_amount_gl_entry(self):
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
@@ -1773,17 +1773,6 @@ class TestSalesInvoice(FrappeTestCase):
self.assertTrue(gle)
def test_invoice_exchange_rate(self):
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=1,
do_not_save=1,
)
self.assertRaises(frappe.ValidationError, si.save)
def test_invalid_currency(self):
# Customer currency = USD
@@ -3298,6 +3287,7 @@ class TestSalesInvoice(FrappeTestCase):
si.posting_date = getdate()
si.submit()
@change_settings("Accounts Settings", {"over_billing_allowance": 0})
def test_over_billing_case_against_delivery_note(self):
"""
Test a case where duplicating the item with qty = 1 in the invoice
@@ -3305,24 +3295,23 @@ class TestSalesInvoice(FrappeTestCase):
"""
from erpnext.stock.doctype.delivery_note.test_delivery_note import create_delivery_note
over_billing_allowance = frappe.db.get_single_value("Accounts Settings", "over_billing_allowance")
frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", 0)
dn = create_delivery_note()
dn.submit()
si = make_sales_invoice(dn.name)
# make a copy of first item and add it to invoice
item_copy = frappe.copy_doc(si.items[0])
si.save()
si.items = [] # Clear existing items
si.append("items", item_copy)
si.save()
si.append("items", item_copy)
with self.assertRaises(frappe.ValidationError) as err:
si.submit()
si.save()
self.assertTrue("cannot overbill" in str(err.exception).lower())
frappe.db.set_value("Accounts Settings", None, "over_billing_allowance", over_billing_allowance)
dn.cancel()
@change_settings(
"Accounts Settings",
@@ -3871,6 +3860,89 @@ class TestSalesInvoice(FrappeTestCase):
doc = frappe.get_doc("Project", project.name)
self.assertEqual(doc.total_billed_amount, si.grand_total)
def test_create_return_invoice_for_self_update(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.controllers.sales_and_purchase_return import make_return_doc
invoice = create_sales_invoice()
payment_entry = get_payment_entry(dt=invoice.doctype, dn=invoice.name)
payment_entry.reference_no = "test001"
payment_entry.reference_date = getdate()
payment_entry.save()
payment_entry.submit()
r_invoice = make_return_doc(invoice.doctype, invoice.name)
r_invoice.update_outstanding_for_self = 0
r_invoice.save()
self.assertEqual(r_invoice.update_outstanding_for_self, 1)
r_invoice.submit()
self.assertNotEqual(r_invoice.outstanding_amount, 0)
invoice.reload()
self.assertEqual(invoice.outstanding_amount, 0)
def test_system_generated_exchange_gain_or_loss_je_after_repost(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.doctype.repost_accounting_ledger.test_repost_accounting_ledger import (
update_repost_settings,
)
update_repost_settings()
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=80,
)
pe = get_payment_entry("Sales Invoice", si.name)
pe.reference_no = "10"
pe.reference_date = nowdate()
pe.paid_from_account_currency = si.currency
pe.paid_to_account_currency = "INR"
pe.source_exchange_rate = 85
pe.target_exchange_rate = 1
pe.paid_amount = si.outstanding_amount
pe.received_amount = 8500
pe.insert()
pe.submit()
ral = frappe.new_doc("Repost Accounting Ledger")
ral.company = si.company
ral.append("vouchers", {"voucher_type": si.doctype, "voucher_no": si.name})
ral.save()
ral.submit()
je = frappe.qb.DocType("Journal Entry")
jea = frappe.qb.DocType("Journal Entry Account")
q = (
(
frappe.qb.from_(je)
.join(jea)
.on(je.name == jea.parent)
.select(je.docstatus)
.where(
(je.voucher_type == "Exchange Gain Or Loss")
& (jea.reference_name == si.name)
& (jea.reference_type == "Sales Invoice")
& (je.is_system_generated == 1)
)
)
.limit(1)
.run()
)
self.assertEqual(q[0][0], 1)
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
gl_entries = frappe.db.sql(

View File

@@ -75,7 +75,7 @@
},
{
"default": "0",
"description": "Even invoices with apply tax withholding unchecked will be considered for checking cumulative threshold breach",
"description": "Only payment entries with apply tax withholding unchecked will be considered for checking cumulative threshold breach",
"fieldname": "consider_party_ledger_amount",
"fieldtype": "Check",
"label": "Consider Entire Party Ledger Amount",
@@ -102,10 +102,11 @@
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-07-27 21:47:34.396071",
"modified": "2025-07-30 07:13:51.785735",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Withholding Category",
"naming_rule": "Set by user",
"owner": "Administrator",
"permissions": [
{
@@ -148,4 +149,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

@@ -622,6 +622,7 @@ def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
conditions.append(ple.party.isin(parties))
conditions.append(ple.voucher_no == ple.against_voucher_no)
conditions.append(ple.company == inv.company)
conditions.append(ple.posting_date[tax_details.from_date : tax_details.to_date])
advance_amt = (
qb.from_(ple).select(Abs(Sum(ple.amount))).where(Criterion.all(conditions)).run()[0][0] or 0.0

View File

@@ -243,17 +243,18 @@ class TestTaxWithholdingCategory(FrappeTestCase):
frappe.db.set_value(
"Customer", "Test TCS Customer", "tax_withholding_category", "Cumulative Threshold TCS"
)
fiscal_year = get_fiscal_year(today(), company="_Test Company")
vouchers = []
# create advance payment
pe = create_payment_entry(
pe1 = create_payment_entry(
payment_type="Receive", party_type="Customer", party="Test TCS Customer", paid_amount=20000
)
pe.paid_from = "Debtors - _TC"
pe.paid_to = "Cash - _TC"
pe.submit()
vouchers.append(pe)
pe1.paid_from = "Debtors - _TC"
pe1.paid_to = "Cash - _TC"
pe1.submit()
vouchers.append(pe1)
# create invoice
si1 = create_sales_invoice(customer="Test TCS Customer", rate=5000)
@@ -275,6 +276,17 @@ class TestTaxWithholdingCategory(FrappeTestCase):
# make another invoice
# sum of unallocated amount from payment entry and this sales invoice will breach cumulative threashold
# TDS should be calculated
# this payment should not be considered for TCS calculation as it is outside of fiscal year
pe2 = create_payment_entry(
payment_type="Receive", party_type="Customer", party="Test TCS Customer", paid_amount=10000
)
pe2.paid_from = "Debtors - _TC"
pe2.paid_to = "Cash - _TC"
pe2.posting_date = add_days(fiscal_year[1], -10)
pe2.submit()
vouchers.append(pe2)
si2 = create_sales_invoice(customer="Test TCS Customer", rate=15000)
si2.submit()
vouchers.append(si2)

View File

@@ -179,6 +179,15 @@ def process_gl_map(gl_map, merge_entries=True, precision=None):
def distribute_gl_based_on_cost_center_allocation(gl_map, precision=None):
round_off_account, default_currency = frappe.get_cached_value(
"Company", gl_map[0].company, ["round_off_account", "default_currency"]
)
if not precision:
precision = get_field_precision(
frappe.get_meta("GL Entry").get_field("debit"),
currency=default_currency,
)
new_gl_map = []
for d in gl_map:
cost_center = d.get("cost_center")
@@ -192,6 +201,11 @@ def distribute_gl_based_on_cost_center_allocation(gl_map, precision=None):
new_gl_map.append(d)
continue
if d.account == round_off_account:
d.cost_center = cost_center_allocation[0][0]
new_gl_map.append(d)
continue
for sub_cost_center, percentage in cost_center_allocation:
gle = copy.deepcopy(d)
gle.cost_center = sub_cost_center

View File

@@ -552,12 +552,13 @@ def validate_party_accounts(doc):
@frappe.whitelist()
def get_due_date(posting_date, party_type, party, company=None, bill_date=None):
def get_due_date(posting_date, party_type, party, company=None, bill_date=None, template_name=None):
"""Get due date from `Payment Terms Template`"""
due_date = None
if (bill_date or posting_date) and party:
due_date = bill_date or posting_date
template_name = get_payment_terms_template(party, party_type, company)
if not template_name:
template_name = get_payment_terms_template(party, party_type, company)
if template_name:
due_date = get_due_date_from_template(template_name, posting_date, bill_date).strftime("%Y-%m-%d")
@@ -597,35 +598,34 @@ def get_due_date_from_template(template_name, posting_date, bill_date):
def validate_due_date(
posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None
posting_date, due_date, party_type, party, company=None, bill_date=None, template_name=None, doctype=None
):
if getdate(due_date) < getdate(posting_date):
frappe.throw(_("Due Date cannot be before Posting / Supplier Invoice Date"))
else:
if not template_name:
return
validate_due_date_with_template(posting_date, due_date, bill_date, template_name, doctype)
default_due_date = get_due_date_from_template(template_name, posting_date, bill_date).strftime(
"%Y-%m-%d"
)
if not default_due_date:
return
def validate_due_date_with_template(posting_date, due_date, bill_date, template_name, doctype=None):
if not template_name:
return
if default_due_date != posting_date and getdate(due_date) > getdate(default_due_date):
is_credit_controller = (
frappe.db.get_single_value("Accounts Settings", "credit_controller") in frappe.get_roles()
default_due_date = format(get_due_date_from_template(template_name, posting_date, bill_date))
if not default_due_date:
return
if default_due_date != posting_date and getdate(due_date) > getdate(default_due_date):
if frappe.db.get_single_value("Accounts Settings", "credit_controller") in frappe.get_roles():
party_type = "supplier" if doctype == "Purchase Invoice" else "customer"
msgprint(
_("Note: Due Date exceeds allowed {0} credit days by {1} day(s)").format(
party_type, date_diff(due_date, default_due_date)
)
)
if is_credit_controller:
msgprint(
_("Note: Due / Reference Date exceeds allowed customer credit days by {0} day(s)").format(
date_diff(due_date, default_due_date)
)
)
else:
frappe.throw(
_("Due / Reference Date cannot be after {0}").format(formatdate(default_due_date))
)
else:
frappe.throw(_("Due Date cannot be after {0}").format(formatdate(default_due_date)))
@frappe.whitelist()
@@ -903,12 +903,16 @@ def get_party_shipping_address(doctype: str, name: str) -> str | None:
["is_shipping_address", "=", 1],
["address_type", "=", "Shipping"],
],
pluck="name",
limit=1,
fields=["name", "is_shipping_address"],
order_by="is_shipping_address DESC",
)
return shipping_addresses[0] if shipping_addresses else None
if shipping_addresses and shipping_addresses[0].is_shipping_address == 1:
return shipping_addresses[0].name
if len(shipping_addresses) == 1:
return shipping_addresses[0].name
else:
return None
def get_partywise_advanced_payment_amount(

View File

@@ -282,4 +282,4 @@
{% } %}
</tbody>
</table>
<p class="text-right text-muted">{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
<p class="text-right text-muted">{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}</p>

View File

@@ -6,6 +6,7 @@ from collections import OrderedDict
import frappe
from frappe import _, qb, query_builder, scrub
from frappe.database.schema import get_definition
from frappe.query_builder import Criterion
from frappe.query_builder.functions import Date, Substring, Sum
from frappe.utils import cint, cstr, flt, getdate, nowdate
@@ -14,7 +15,10 @@ from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
get_dimension_with_children,
)
from erpnext.accounts.utils import get_currency_precision
from erpnext.accounts.utils import (
build_qb_match_conditions,
get_currency_precision,
)
# This report gives a summary of all Outstanding Invoices considering the following
@@ -49,6 +53,10 @@ class ReceivablePayableReport:
self.age_as_on = (
getdate(nowdate()) if self.filters.report_date > getdate(nowdate()) else self.filters.report_date
)
self.ple_fetch_method = (
frappe.db.get_single_value("Accounts Settings", "receivable_payable_fetch_method")
or "Buffered Cursor"
) # Fail Safe
def run(self, args):
self.filters.update(args)
@@ -85,13 +93,7 @@ class ReceivablePayableReport:
self.skip_total_row = 1
def get_data(self):
self.get_ple_entries()
self.get_sales_invoices_or_customers_based_on_sales_person()
self.voucher_balance = OrderedDict()
self.init_voucher_balance() # invoiced, paid, credit_note, outstanding
# Build delivery note map against all sales invoices
self.build_delivery_note_map()
# Get invoice details like bill_no, due_date etc for all invoices
self.get_invoice_details()
@@ -105,12 +107,45 @@ class ReceivablePayableReport:
# Get Exchange Rate Revaluations
self.get_exchange_rate_revaluations()
self.prepare_ple_query()
self.data = []
self.voucher_balance = OrderedDict()
if self.ple_fetch_method == "Buffered Cursor":
self.fetch_ple_in_buffered_cursor()
elif self.ple_fetch_method == "UnBuffered Cursor":
self.fetch_ple_in_unbuffered_cursor()
elif self.ple_fetch_method == "Raw SQL":
self.fetch_ple_in_sql_procedures()
# Build delivery note map against all sales invoices
self.build_delivery_note_map()
self.build_data()
def fetch_ple_in_buffered_cursor(self):
self.ple_entries = self.ple_query.run(as_dict=True)
for ple in self.ple_entries:
self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding
# This is unavoidable. Initialization and allocation cannot happen in same loop
for ple in self.ple_entries:
self.update_voucher_balance(ple)
self.build_data()
delattr(self, "ple_entries")
def fetch_ple_in_unbuffered_cursor(self):
self.ple_entries = []
with frappe.db.unbuffered_cursor():
for ple in self.ple_query.run(as_dict=True, as_iterator=True):
self.init_voucher_balance(ple) # invoiced, paid, credit_note, outstanding
self.ple_entries.append(ple)
# This is unavoidable. Initialization and allocation cannot happen in same loop
for ple in self.ple_entries:
self.update_voucher_balance(ple)
delattr(self, "ple_entries")
def build_voucher_dict(self, ple):
return frappe._dict(
@@ -131,26 +166,22 @@ class ReceivablePayableReport:
outstanding_in_account_currency=0.0,
)
def init_voucher_balance(self):
# build all keys, since we want to exclude vouchers beyond the report date
for ple in self.ple_entries:
# get the balance object for voucher_type
def init_voucher_balance(self, ple):
if self.filters.get("ignore_accounts"):
key = (ple.voucher_type, ple.voucher_no, ple.party)
else:
key = (ple.account, ple.voucher_type, ple.voucher_no, ple.party)
if self.filters.get("ignore_accounts"):
key = (ple.voucher_type, ple.voucher_no, ple.party)
else:
key = (ple.account, ple.voucher_type, ple.voucher_no, ple.party)
if key not in self.voucher_balance:
self.voucher_balance[key] = self.build_voucher_dict(ple)
if key not in self.voucher_balance:
self.voucher_balance[key] = self.build_voucher_dict(ple)
if ple.voucher_type == ple.against_voucher_type and ple.voucher_no == ple.against_voucher_no:
self.voucher_balance[key].cost_center = ple.cost_center
if ple.voucher_type == ple.against_voucher_type and ple.voucher_no == ple.against_voucher_no:
self.voucher_balance[key].cost_center = ple.cost_center
self.get_invoices(ple)
self.get_invoices(ple)
if self.filters.get("group_by_party"):
self.init_subtotal_row(ple.party)
if self.filters.get("group_by_party"):
self.init_subtotal_row(ple.party)
if self.filters.get("group_by_party") and not self.filters.get("in_party_currency"):
self.init_subtotal_row("Total")
@@ -272,6 +303,79 @@ class ReceivablePayableReport:
row.paid -= amount
row.paid_in_account_currency -= amount_in_account_currency
def fetch_ple_in_sql_procedures(self):
self.proc = InitSQLProceduresForAR()
build_balance = f"""
begin not atomic
declare done boolean default false;
declare rec1 row type of `{self.proc._row_def_table_name}`;
declare ple cursor for {self.ple_query.get_sql()};
declare continue handler for not found set done = true;
open ple;
fetch ple into rec1;
while not done do
call {self.proc.init_procedure_name}(rec1);
fetch ple into rec1;
end while;
close ple;
set done = false;
open ple;
fetch ple into rec1;
while not done do
call {self.proc.allocate_procedure_name}(rec1);
fetch ple into rec1;
end while;
close ple;
end;
"""
frappe.db.sql(build_balance)
balances = frappe.db.sql(
f"""select
name,
voucher_type,
voucher_no,
party,
party_account `account`,
posting_date,
account_currency,
cost_center,
sum(invoiced) `invoiced`,
sum(paid) `paid`,
sum(credit_note) `credit_note`,
sum(invoiced) - sum(paid) - sum(credit_note) `outstanding`,
sum(invoiced_in_account_currency) `invoiced_in_account_currency`,
sum(paid_in_account_currency) `paid_in_account_currency`,
sum(credit_note_in_account_currency) `credit_note_in_account_currency`,
sum(invoiced_in_account_currency) - sum(paid_in_account_currency) - sum(credit_note_in_account_currency) `outstanding_in_account_currency`
from `{self.proc._voucher_balance_name}` group by name order by posting_date;""",
as_dict=True,
)
for x in balances:
if self.filters.get("ignore_accounts"):
key = (x.voucher_type, x.voucher_no, x.party)
else:
key = (x.account, x.voucher_type, x.voucher_no, x.party)
_d = self.build_voucher_dict(x)
for field in [
"invoiced",
"paid",
"credit_note",
"outstanding",
"invoiced_in_account_currency",
"paid_in_account_currency",
"credit_note_in_account_currency",
"outstanding_in_account_currency",
"cost_center",
]:
_d[field] = x.get(field)
self.voucher_balance[key] = _d
def update_sub_total_row(self, row, party):
total_row = self.total_row_map.get(party)
@@ -764,7 +868,7 @@ class ReceivablePayableReport:
index = 4
row["range" + str(index + 1)] = row.outstanding
def get_ple_entries(self):
def prepare_ple_query(self):
# get all the GL entries filtered by the given filters
self.prepare_conditions()
@@ -812,12 +916,15 @@ class ReceivablePayableReport:
else:
query = query.select(ple.remarks)
if match_conditions := build_qb_match_conditions("Payment Ledger Entry"):
query = query.where(Criterion.all(match_conditions))
if self.filters.get("group_by_party"):
query = query.orderby(self.ple.party, self.ple.posting_date)
else:
query = query.orderby(self.ple.posting_date, self.ple.party)
self.ple_entries = query.run(as_dict=True)
self.ple_query = query
def get_sales_invoices_or_customers_based_on_sales_person(self):
if self.filters.get("sales_person"):
@@ -1204,3 +1311,134 @@ def get_customer_group_with_children(customer_groups):
frappe.throw(_("Customer Group: {0} does not exist").format(d))
return list(set(all_customer_groups))
class InitSQLProceduresForAR:
"""
Initialize SQL Procedures, Functions and Temporary tables to build Receivable / Payable report
"""
_varchar_type = get_definition("Data")
_currency_type = get_definition("Currency")
# Temporary Tables
_voucher_balance_name = "_ar_voucher_balance"
_voucher_balance_definition = f"""
create temporary table `{_voucher_balance_name}`(
name {_varchar_type},
voucher_type {_varchar_type},
voucher_no {_varchar_type},
party {_varchar_type},
party_account {_varchar_type},
posting_date date,
account_currency {_varchar_type},
cost_center {_varchar_type},
invoiced {_currency_type},
paid {_currency_type},
credit_note {_currency_type},
invoiced_in_account_currency {_currency_type},
paid_in_account_currency {_currency_type},
credit_note_in_account_currency {_currency_type}) engine=memory;
"""
_row_def_table_name = "_ar_ple_row"
_row_def_table_definition = f"""
create temporary table `{_row_def_table_name}`(
name {_varchar_type},
account {_varchar_type},
voucher_type {_varchar_type},
voucher_no {_varchar_type},
against_voucher_type {_varchar_type},
against_voucher_no {_varchar_type},
party_type {_varchar_type},
cost_center {_varchar_type},
party {_varchar_type},
posting_date date,
due_date date,
account_currency {_varchar_type},
amount {_currency_type},
amount_in_account_currency {_currency_type}) engine=memory;
"""
# Function
genkey_function_name = "ar_genkey"
genkey_function_sql = f"""
create function `{genkey_function_name}`(rec row type of `{_row_def_table_name}`, allocate bool) returns char(40)
begin
if allocate then
return sha1(concat_ws(',', rec.account, rec.against_voucher_type, rec.against_voucher_no, rec.party));
else
return sha1(concat_ws(',', rec.account, rec.voucher_type, rec.voucher_no, rec.party));
end if;
end
"""
# Procedures
init_procedure_name = "ar_init_tmp_table"
init_procedure_sql = f"""
create procedure ar_init_tmp_table(in ple row type of `{_row_def_table_name}`)
begin
if not exists (select name from `{_voucher_balance_name}` where name = `{genkey_function_name}`(ple, false))
then
insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, false), ple.voucher_type, ple.voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency, ple.cost_center, 0, 0, 0, 0, 0, 0);
end if;
end;
"""
allocate_procedure_name = "ar_allocate_to_tmp_table"
allocate_procedure_sql = f"""
create procedure ar_allocate_to_tmp_table(in ple row type of `{_row_def_table_name}`)
begin
declare invoiced {_currency_type} default 0;
declare invoiced_in_account_currency {_currency_type} default 0;
declare paid {_currency_type} default 0;
declare paid_in_account_currency {_currency_type} default 0;
declare credit_note {_currency_type} default 0;
declare credit_note_in_account_currency {_currency_type} default 0;
if ple.amount > 0 then
if (ple.voucher_type in ("Journal Entry", "Payment Entry") and (ple.voucher_no != ple.against_voucher_no)) then
set paid = -1 * ple.amount;
set paid_in_account_currency = -1 * ple.amount_in_account_currency;
else
set invoiced = ple.amount;
set invoiced_in_account_currency = ple.amount_in_account_currency;
end if;
else
if ple.voucher_type in ("Sales Invoice", "Purchase Invoice") then
if (ple.voucher_no = ple.against_voucher_no) then
set paid = -1 * ple.amount;
set paid_in_account_currency = -1 * ple.amount_in_account_currency;
else
set credit_note = -1 * ple.amount;
set credit_note_in_account_currency = -1 * ple.amount_in_account_currency;
end if;
else
set paid = -1 * ple.amount;
set paid_in_account_currency = -1 * ple.amount_in_account_currency;
end if;
end if;
insert into `{_voucher_balance_name}` values (`{genkey_function_name}`(ple, true), ple.against_voucher_type, ple.against_voucher_no, ple.party, ple.account, ple.posting_date, ple.account_currency,'', invoiced, paid, 0, invoiced_in_account_currency, paid_in_account_currency, 0);
end;
"""
def __init__(self):
existing_procedures = frappe.db.get_routines()
if self.genkey_function_name not in existing_procedures:
frappe.db.sql(self.genkey_function_sql)
if self.init_procedure_name not in existing_procedures:
frappe.db.sql(self.init_procedure_sql)
if self.allocate_procedure_name not in existing_procedures:
frappe.db.sql(self.allocate_procedure_sql)
frappe.db.sql(f"drop table if exists `{self._voucher_balance_name}`")
frappe.db.sql(self._voucher_balance_definition)
frappe.db.sql(f"drop table if exists `{self._row_def_table_name}`")
frappe.db.sql(self._row_def_table_definition)

View File

@@ -21,7 +21,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
def tearDown(self):
frappe.db.rollback()
def create_sales_invoice(self, no_payment_schedule=False, do_not_submit=False):
def create_sales_invoice(self, no_payment_schedule=False, do_not_submit=False, **args):
frappe.set_user("Administrator")
si = create_sales_invoice(
item=self.item,
@@ -34,6 +34,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
rate=100,
price_list_rate=100,
do_not_save=1,
**args,
)
if not no_payment_schedule:
si.append(
@@ -111,7 +112,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
self.assertEqual(expected_data[0], [row.invoiced, row.paid, row.credit_note])
pos_inv.cancel()
def test_accounts_receivable(self):
def test_accounts_receivable_with_payment(self):
filters = {
"company": self.company,
"based_on_payment_terms": 1,
@@ -151,11 +152,15 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
cr_note = self.create_credit_note(si.name, do_not_submit=True)
cr_note.update_outstanding_for_self = False
cr_note.save().submit()
# as the invoice partially paid and returning the full amount so the outstanding amount should be True
self.assertEqual(cr_note.update_outstanding_for_self, True)
report = execute(filters)
expected_data_after_credit_note = [100, 0, 0, 40, -40, self.debit_to]
expected_data_after_credit_note = [0, 0, 100, 0, -100, self.debit_to]
row = report[1][0]
row = report[1][-1]
self.assertEqual(
expected_data_after_credit_note,
[
@@ -168,6 +173,105 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
],
)
def test_accounts_receivable_without_payment(self):
filters = {
"company": self.company,
"based_on_payment_terms": 1,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
"show_remarks": True,
}
# check invoice grand total and invoiced column's value for 3 payment terms
si = self.create_sales_invoice()
report = execute(filters)
expected_data = [[100, 30, "No Remarks"], [100, 50, "No Remarks"], [100, 20, "No Remarks"]]
for i in range(3):
row = report[1][i - 1]
self.assertEqual(expected_data[i - 1], [row.invoice_grand_total, row.invoiced, row.remarks])
# check invoice grand total, invoiced, paid and outstanding column's value after credit note
cr_note = self.create_credit_note(si.name, do_not_submit=True)
cr_note.update_outstanding_for_self = False
cr_note.save().submit()
self.assertEqual(cr_note.update_outstanding_for_self, False)
report = execute(filters)
row = report[1]
self.assertTrue(len(row) == 0)
def test_accounts_receivable_with_partial_payment(self):
filters = {
"company": self.company,
"based_on_payment_terms": 1,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
"show_remarks": True,
}
# check invoice grand total and invoiced column's value for 3 payment terms
si = self.create_sales_invoice(qty=2)
report = execute(filters)
expected_data = [[200, 60, "No Remarks"], [200, 100, "No Remarks"], [200, 40, "No Remarks"]]
for i in range(3):
row = report[1][i - 1]
self.assertEqual(expected_data[i - 1], [row.invoice_grand_total, row.invoiced, row.remarks])
# check invoice grand total, invoiced, paid and outstanding column's value after payment
self.create_payment_entry(si.name)
report = execute(filters)
expected_data_after_payment = [[200, 60, 40, 20], [200, 100, 0, 100], [200, 40, 0, 40]]
for i in range(3):
row = report[1][i - 1]
self.assertEqual(
expected_data_after_payment[i - 1],
[row.invoice_grand_total, row.invoiced, row.paid, row.outstanding],
)
# check invoice grand total, invoiced, paid and outstanding column's value after credit note
cr_note = self.create_credit_note(si.name, do_not_submit=True)
cr_note.update_outstanding_for_self = False
cr_note.save().submit()
self.assertFalse(cr_note.update_outstanding_for_self)
report = execute(filters)
expected_data_after_credit_note = [
[200, 100, 0, 80, 20, self.debit_to],
[200, 40, 0, 0, 40, self.debit_to],
]
for i in range(2):
row = report[1][i - 1]
self.assertEqual(
expected_data_after_credit_note[i - 1],
[
row.invoice_grand_total,
row.invoiced,
row.paid,
row.credit_note,
row.outstanding,
row.party_account,
],
)
def test_cr_note_flag_to_update_self(self):
filters = {
"company": self.company,

View File

@@ -25,11 +25,26 @@ frappe.query_reports["Asset Depreciations and Balances"] = {
default: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
reqd: 1,
},
{
fieldname: "group_by",
label: __("Group By"),
fieldtype: "Select",
options: ["Asset Category", "Asset"],
default: "Asset Category",
},
{
fieldname: "asset_category",
label: __("Asset Category"),
fieldtype: "Link",
options: "Asset Category",
depends_on: "eval: doc.group_by == 'Asset Category'",
},
{
fieldname: "asset",
label: __("Asset"),
fieldtype: "Link",
options: "Asset",
depends_on: "eval: doc.group_by == 'Asset'",
},
],
};

View File

@@ -14,21 +14,28 @@ def execute(filters=None):
def get_data(filters):
if filters.get("group_by") == "Asset Category":
return get_group_by_asset_category_data(filters)
elif filters.get("group_by") == "Asset":
return get_group_by_asset_data(filters)
def get_group_by_asset_category_data(filters):
data = []
asset_categories = get_asset_categories(filters)
assets = get_assets(filters)
asset_categories = get_asset_categories_for_grouped_by_category(filters)
assets = get_assets_for_grouped_by_category(filters)
for asset_category in asset_categories:
row = frappe._dict()
# row.asset_category = asset_category
row.update(asset_category)
row.cost_as_on_to_date = (
flt(row.cost_as_on_from_date)
+ flt(row.cost_of_new_purchase)
- flt(row.cost_of_sold_asset)
- flt(row.cost_of_scrapped_asset)
row.value_as_on_to_date = (
flt(row.value_as_on_from_date)
+ flt(row.value_of_new_purchase)
- flt(row.value_of_sold_asset)
- flt(row.value_of_scrapped_asset)
- flt(row.value_of_capitalized_asset)
)
row.update(
@@ -38,17 +45,19 @@ def get_data(filters):
if asset["asset_category"] == asset_category.get("asset_category", "")
)
)
row.accumulated_depreciation_as_on_to_date = (
flt(row.accumulated_depreciation_as_on_from_date)
+ flt(row.depreciation_amount_during_the_period)
- flt(row.depreciation_eliminated_during_the_period)
- flt(row.depreciation_eliminated_via_reversal)
)
row.net_asset_value_as_on_from_date = flt(row.cost_as_on_from_date) - flt(
row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt(
row.accumulated_depreciation_as_on_from_date
)
row.net_asset_value_as_on_to_date = flt(row.cost_as_on_to_date) - flt(
row.net_asset_value_as_on_to_date = flt(row.value_as_on_to_date) - flt(
row.accumulated_depreciation_as_on_to_date
)
@@ -57,52 +66,71 @@ def get_data(filters):
return data
def get_asset_categories(filters):
def get_asset_categories_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition += " and asset_category = %(asset_category)s"
condition += " and a.asset_category = %(asset_category)s"
# nosemgrep
return frappe.db.sql(
f"""
SELECT asset_category,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
SELECT a.asset_category,
ifnull(sum(case when a.purchase_date < %(from_date)s then
case when ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
end), 0) as value_as_on_from_date,
ifnull(sum(case when a.purchase_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
end), 0) as value_of_new_purchase,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Sold" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
end), 0) as value_of_sold_asset,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Scrapped" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {condition}
group by asset_category
end), 0) as value_of_scrapped_asset,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Capitalized" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as value_of_capitalized_asset
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition}
and not exists(
select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name
where acai.asset = a.name
and ac.posting_date < %(from_date)s
and ac.docstatus=1
)
group by a.asset_category
""",
{
"to_date": filters.to_date,
@@ -114,14 +142,17 @@ def get_asset_categories(filters):
)
def get_assets(filters):
def get_assets_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition = " and a.asset_category = '{}'".format(filters.get("asset_category"))
condition = f" and a.asset_category = '{filters.get('asset_category')}'"
# nosemgrep
return frappe.db.sql(
"""
f"""
SELECT results.asset_category,
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
sum(results.depreciation_eliminated_via_reversal) as depreciation_eliminated_via_reversal,
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
from (SELECT a.asset_category,
@@ -130,6 +161,11 @@ def get_assets(filters):
else
0
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when gle.posting_date <= %(to_date)s and ifnull(a.disposal_date, 0) = 0 then
gle.credit
else
0
end), 0) as depreciation_eliminated_via_reversal,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
gle.debit
@@ -149,15 +185,22 @@ def get_assets(filters):
aca.parent = a.asset_category and aca.company_name = %(company)s
join `tabCompany` company on
company.name = %(company)s
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s and gle.debit != 0 and gle.is_cancelled = 0 and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account) {0}
where
a.docstatus=1
and a.company=%(company)s
and a.purchase_date <= %(to_date)s
and gle.is_cancelled = 0
and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account)
{condition}
group by a.asset_category
union
SELECT a.asset_category,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and (a.disposal_date < %(from_date)s or a.disposal_date > %(to_date)s) then
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date < %(from_date)s then
0
else
a.opening_accumulated_depreciation
end), 0) as accumulated_depreciation_as_on_from_date,
0 as depreciation_eliminated_via_reversal,
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
a.opening_accumulated_depreciation
else
@@ -165,51 +208,272 @@ def get_assets(filters):
end), 0) as depreciation_eliminated_during_the_period,
0 as depreciation_amount_during_the_period
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {0}
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition}
group by a.asset_category) as results
group by results.asset_category
""".format(condition),
{"to_date": filters.to_date, "from_date": filters.from_date, "company": filters.company},
""",
{
"to_date": filters.to_date,
"from_date": filters.from_date,
"company": filters.company,
},
as_dict=1,
)
def get_group_by_asset_data(filters):
data = []
asset_details = get_asset_details_for_grouped_by_category(filters)
assets = get_assets_for_grouped_by_asset(filters)
for asset_detail in asset_details:
row = frappe._dict()
row.update(asset_detail)
row.value_as_on_to_date = (
flt(row.value_as_on_from_date)
+ flt(row.value_of_new_purchase)
- flt(row.value_of_sold_asset)
- flt(row.value_of_scrapped_asset)
- flt(row.value_of_capitalized_asset)
)
row.update(next(asset for asset in assets if asset["asset"] == asset_detail.get("name", "")))
row.accumulated_depreciation_as_on_to_date = (
flt(row.accumulated_depreciation_as_on_from_date)
+ flt(row.depreciation_amount_during_the_period)
- flt(row.depreciation_eliminated_during_the_period)
- flt(row.depreciation_eliminated_via_reversal)
)
row.net_asset_value_as_on_from_date = flt(row.value_as_on_from_date) - flt(
row.accumulated_depreciation_as_on_from_date
)
row.net_asset_value_as_on_to_date = flt(row.value_as_on_to_date) - flt(
row.accumulated_depreciation_as_on_to_date
)
data.append(row)
return data
def get_asset_details_for_grouped_by_category(filters):
condition = ""
if filters.get("asset"):
condition += " and a.name = %(asset)s"
# nosemgrep
return frappe.db.sql(
f"""
SELECT a.name,
ifnull(sum(case when a.purchase_date < %(from_date)s then
case when ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as value_as_on_from_date,
ifnull(sum(case when a.purchase_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end), 0) as value_of_new_purchase,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Sold" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as value_of_sold_asset,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Scrapped" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as value_of_scrapped_asset,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Capitalized" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as value_of_capitalized_asset
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition}
and not exists(
select 1 from `tabAsset Capitalization Asset Item` acai join `tabAsset Capitalization` ac on acai.parent=ac.name
where acai.asset = a.name
and ac.posting_date < %(from_date)s
and ac.docstatus=1
)
group by a.name
""",
{
"to_date": filters.to_date,
"from_date": filters.from_date,
"company": filters.company,
"asset": filters.get("asset"),
},
as_dict=1,
)
def get_assets_for_grouped_by_asset(filters):
condition = ""
if filters.get("asset"):
condition = f" and a.name = '{filters.get('asset')}'"
# nosemgrep
return frappe.db.sql(
f"""
SELECT results.name as asset,
sum(results.accumulated_depreciation_as_on_from_date) as accumulated_depreciation_as_on_from_date,
sum(results.depreciation_eliminated_via_reversal) as depreciation_eliminated_via_reversal,
sum(results.depreciation_eliminated_during_the_period) as depreciation_eliminated_during_the_period,
sum(results.depreciation_amount_during_the_period) as depreciation_amount_during_the_period
from (SELECT a.name as name,
ifnull(sum(case when gle.posting_date < %(from_date)s and (ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s) then
gle.debit
else
0
end), 0) as accumulated_depreciation_as_on_from_date,
ifnull(sum(case when gle.posting_date <= %(to_date)s and ifnull(a.disposal_date, 0) = 0 then
gle.credit
else
0
end), 0) as depreciation_eliminated_via_reversal,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s and gle.posting_date <= a.disposal_date then
gle.debit
else
0
end), 0) as depreciation_eliminated_during_the_period,
ifnull(sum(case when gle.posting_date >= %(from_date)s and gle.posting_date <= %(to_date)s
and (ifnull(a.disposal_date, 0) = 0 or gle.posting_date <= a.disposal_date) then
gle.debit
else
0
end), 0) as depreciation_amount_during_the_period
from `tabGL Entry` gle
join `tabAsset` a on
gle.against_voucher = a.name
join `tabAsset Category Account` aca on
aca.parent = a.asset_category and aca.company_name = %(company)s
join `tabCompany` company on
company.name = %(company)s
where
a.docstatus=1
and a.company=%(company)s
and a.purchase_date <= %(to_date)s
and gle.is_cancelled = 0
and gle.account = ifnull(aca.depreciation_expense_account, company.depreciation_expense_account)
{condition}
group by a.name
union
SELECT a.name as name,
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0 and a.disposal_date < %(from_date)s then
0
else
a.opening_accumulated_depreciation
end), 0) as accumulated_depreciation_as_on_from_date,
0 as depreciation_as_on_from_date_credit,
ifnull(sum(case when a.disposal_date >= %(from_date)s and a.disposal_date <= %(to_date)s then
a.opening_accumulated_depreciation
else
0
end), 0) as depreciation_eliminated_during_the_period,
0 as depreciation_amount_during_the_period
from `tabAsset` a
where a.docstatus=1 and a.company=%(company)s and a.purchase_date <= %(to_date)s {condition}
group by a.name) as results
group by results.name
""",
{
"to_date": filters.to_date,
"from_date": filters.from_date,
"company": filters.company,
},
as_dict=1,
)
def get_columns(filters):
return [
columns = []
if filters.get("group_by") == "Asset Category":
columns.append(
{
"label": _("Asset Category"),
"fieldname": "asset_category",
"fieldtype": "Link",
"options": "Asset Category",
"width": 120,
}
)
elif filters.get("group_by") == "Asset":
columns.append(
{
"label": _("Asset"),
"fieldname": "asset",
"fieldtype": "Link",
"options": "Asset",
"width": 120,
}
)
columns += [
{
"label": _("Asset Category"),
"fieldname": "asset_category",
"fieldtype": "Link",
"options": "Asset Category",
"width": 120,
},
{
"label": _("Cost as on") + " " + formatdate(filters.day_before_from_date),
"fieldname": "cost_as_on_from_date",
"label": _("Value as on") + " " + formatdate(filters.day_before_from_date),
"fieldname": "value_as_on_from_date",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Cost of New Purchase"),
"fieldname": "cost_of_new_purchase",
"label": _("Value of New Purchase"),
"fieldname": "value_of_new_purchase",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Cost of Sold Asset"),
"fieldname": "cost_of_sold_asset",
"label": _("Value of Sold Asset"),
"fieldname": "value_of_sold_asset",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Cost of Scrapped Asset"),
"fieldname": "cost_of_scrapped_asset",
"label": _("Value of Scrapped Asset"),
"fieldname": "value_of_scrapped_asset",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Cost as on") + " " + formatdate(filters.to_date),
"fieldname": "cost_as_on_to_date",
"label": _("Value of New Capitalized Asset"),
"fieldname": "value_of_capitalized_asset",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Value as on") + " " + formatdate(filters.to_date),
"fieldname": "value_as_on_to_date",
"fieldtype": "Currency",
"width": 140,
},
@@ -237,6 +501,12 @@ def get_columns(filters):
"fieldtype": "Currency",
"width": 270,
},
{
"label": _("Depreciation eliminated via reversal"),
"fieldname": "depreciation_eliminated_via_reversal",
"fieldtype": "Currency",
"width": 270,
},
{
"label": _("Net Asset value as on") + " " + formatdate(filters.day_before_from_date),
"fieldname": "net_asset_value_as_on_from_date",
@@ -250,3 +520,5 @@ def get_columns(filters):
"width": 200,
},
]
return columns

View File

@@ -1,6 +1,3 @@
<div style="margin-bottom: 7px;">
{%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %}
</div>
<h2 class="text-center">{%= __("Bank Reconciliation Statement") %}</h2>
<h4 class="text-center">{%= filters.account && (filters.account + ", "+filters.report_date) || "" %} {%= filters.company %}</h4>
<hr>
@@ -46,4 +43,4 @@
{% } %}
</tbody>
</table>
<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
<p class="text-right text-muted">{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}</p>

View File

@@ -67,5 +67,5 @@
</tbody>
</table>
<p class="text-right text-muted">
Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}
{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}
</p>

View File

@@ -78,4 +78,4 @@
{% } %}
</tbody>
</table>
<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
<p class="text-right text-muted">{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}</p>

View File

@@ -49,9 +49,14 @@ frappe.query_reports["General Ledger"] = {
label: __("Voucher No"),
fieldtype: "Data",
on_change: function () {
frappe.query_report.set_filter_value("group_by", "Group by Voucher (Consolidated)");
frappe.query_report.set_filter_value("categorize_by", "Categorize by Voucher (Consolidated)");
},
},
{
fieldname: "against_voucher_no",
label: __("Against Voucher No"),
fieldtype: "Data",
},
{
fieldtype: "Break",
},
@@ -61,7 +66,7 @@ frappe.query_reports["General Ledger"] = {
fieldtype: "Autocomplete",
options: Object.keys(frappe.boot.party_account_types),
on_change: function () {
frappe.query_report.set_filter_value("party", "");
frappe.query_report.set_filter_value("party", []);
},
},
{
@@ -107,29 +112,29 @@ frappe.query_reports["General Ledger"] = {
hidden: 1,
},
{
fieldname: "group_by",
label: __("Group by"),
fieldname: "categorize_by",
label: __("Categorize by"),
fieldtype: "Select",
options: [
"",
{
label: __("Group by Voucher"),
value: "Group by Voucher",
label: __("Categorize by Voucher"),
value: "Categorize by Voucher",
},
{
label: __("Group by Voucher (Consolidated)"),
value: "Group by Voucher (Consolidated)",
label: __("Categorize by Voucher (Consolidated)"),
value: "Categorize by Voucher (Consolidated)",
},
{
label: __("Group by Account"),
value: "Group by Account",
label: __("Categorize by Account"),
value: "Categorize by Account",
},
{
label: __("Group by Party"),
value: "Group by Party",
label: __("Categorize by Party"),
value: "Categorize by Party",
},
],
default: "Group by Voucher (Consolidated)",
default: "Categorize by Voucher (Consolidated)",
},
{
fieldname: "tax_id",
@@ -192,6 +197,11 @@ frappe.query_reports["General Ledger"] = {
label: __("Show Net Values in Party Account"),
fieldtype: "Check",
},
{
fieldname: "show_amount_in_company_currency",
label: __("Show Credit / Debit in Company Currency"),
fieldtype: "Check",
},
{
fieldname: "show_remarks",
label: __("Show Remarks"),

View File

@@ -72,13 +72,17 @@ def validate_filters(filters, account_details):
if not account_details.get(account):
frappe.throw(_("Account {0} does not exists").format(account))
if filters.get("account") and filters.get("group_by") == "Group by Account":
if not filters.get("categorize_by") and filters.get("group_by"):
filters["categorize_by"] = filters["group_by"]
filters["categorize_by"] = filters["categorize_by"].replace("Group by", "Categorize by")
if filters.get("account") and filters.get("categorize_by") == "Categorize by Account":
filters.account = frappe.parse_json(filters.get("account"))
for account in filters.account:
if account_details[account].is_group == 0:
frappe.throw(_("Can not filter based on Child Account, if grouped by Account"))
if filters.get("voucher_no") and filters.get("group_by") in ["Group by Voucher"]:
if filters.get("voucher_no") and filters.get("categorize_by") in ["Categorize by Voucher"]:
frappe.throw(_("Can not filter based on Voucher No, if grouped by Voucher"))
if filters.from_date > filters.to_date:
@@ -172,9 +176,9 @@ def get_gl_entries(filters, accounting_dimensions):
if filters.get("include_dimensions"):
order_by_statement = "order by posting_date, creation"
if filters.get("group_by") == "Group by Voucher":
if filters.get("categorize_by") == "Categorize by Voucher":
order_by_statement = "order by posting_date, voucher_type, voucher_no"
if filters.get("group_by") == "Group by Account":
if filters.get("categorize_by") == "Categorize by Account":
order_by_statement = "order by account, posting_date, creation"
if filters.get("include_default_book_entries"):
@@ -201,7 +205,7 @@ def get_gl_entries(filters, accounting_dimensions):
)
if filters.get("presentation_currency"):
return convert_to_presentation_currency(gl_entries, currency_map)
return convert_to_presentation_currency(gl_entries, currency_map, filters)
else:
return gl_entries
@@ -225,6 +229,9 @@ def get_conditions(filters):
if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s")
if filters.get("against_voucher_no"):
conditions.append("against_voucher=%(against_voucher_no)s")
if filters.get("ignore_err"):
err_journals = frappe.db.get_all(
"Journal Entry",
@@ -258,7 +265,7 @@ def get_conditions(filters):
if filters.get("voucher_no_not_in"):
conditions.append("voucher_no not in %(voucher_no_not_in)s")
if filters.get("group_by") == "Group by Party" and not filters.get("party_type"):
if filters.get("categorize_by") == "Categorize by Party" and not filters.get("party_type"):
conditions.append("party_type in ('Customer', 'Supplier')")
if filters.get("party_type"):
@@ -270,7 +277,7 @@ def get_conditions(filters):
if not (
filters.get("account")
or filters.get("party")
or filters.get("group_by") in ["Group by Account", "Group by Party"]
or filters.get("categorize_by") in ["Categorize by Account", "Categorize by Party"]
):
if not ignore_is_opening:
conditions.append("(posting_date >=%(from_date)s or is_opening = 'Yes')")
@@ -365,13 +372,13 @@ def get_data_with_opening_closing(filters, account_details, accounting_dimension
# Opening for filtered account
data.append(totals.opening)
if filters.get("group_by") != "Group by Voucher (Consolidated)":
if filters.get("categorize_by") != "Categorize by Voucher (Consolidated)":
for _acc, acc_dict in gle_map.items():
# acc
if acc_dict.entries:
# opening
data.append({})
if filters.get("group_by") != "Group by Voucher":
if filters.get("categorize_by") != "Categorize by Voucher":
data.append(acc_dict.totals.opening)
data += acc_dict.entries
@@ -380,7 +387,7 @@ def get_data_with_opening_closing(filters, account_details, accounting_dimension
data.append(acc_dict.totals.total)
# closing
if filters.get("group_by") != "Group by Voucher":
if filters.get("categorize_by") != "Categorize by Voucher":
data.append(acc_dict.totals.closing)
data.append({})
else:
@@ -413,9 +420,9 @@ def get_totals_dict():
def group_by_field(group_by):
if group_by == "Group by Party":
if group_by == "Categorize by Party":
return "party"
elif group_by in ["Group by Voucher (Consolidated)", "Group by Account"]:
elif group_by in ["Categorize by Voucher (Consolidated)", "Categorize by Account"]:
return "account"
else:
return "voucher_no"
@@ -423,7 +430,7 @@ def group_by_field(group_by):
def initialize_gle_map(gl_entries, filters):
gle_map = OrderedDict()
group_by = group_by_field(filters.get("group_by"))
group_by = group_by_field(filters.get("categorize_by"))
for gle in gl_entries:
gle_map.setdefault(gle.get(group_by), _dict(totals=get_totals_dict(), entries=[]))
@@ -434,8 +441,8 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
totals = get_totals_dict()
entries = []
consolidated_gle = OrderedDict()
group_by = group_by_field(filters.get("group_by"))
group_by_voucher_consolidated = filters.get("group_by") == "Group by Voucher (Consolidated)"
group_by = group_by_field(filters.get("categorize_by"))
group_by_voucher_consolidated = filters.get("categorize_by") == "Categorize by Voucher (Consolidated)"
if filters.get("show_net_values_in_party_account"):
account_type_map = get_account_type_map(filters.get("company"))
@@ -531,17 +538,20 @@ def get_account_type_map(company):
def get_result_as_list(data, filters):
balance, _balance_in_account_currency = 0, 0
balance = 0
for d in data:
if not d.get("posting_date"):
balance, _balance_in_account_currency = 0, 0
balance = 0
balance = get_balance(d, balance, "debit", "credit")
d["balance"] = balance
d["account_currency"] = filters.account_currency
d["presentation_currency"] = filters.presentation_currency
return data
@@ -567,11 +577,21 @@ def get_columns(filters):
if filters.get("presentation_currency"):
currency = filters["presentation_currency"]
else:
if filters.get("company"):
currency = get_company_currency(filters["company"])
else:
company = get_default_company()
currency = get_company_currency(company)
company = filters.get("company") or get_default_company()
filters["presentation_currency"] = currency = get_company_currency(company)
company_currency = get_company_currency(filters.get("company") or get_default_company())
if (
filters.get("show_amount_in_company_currency")
and filters["presentation_currency"] != company_currency
):
frappe.throw(
_("Presentation Currency cannot be {0} , When {1} is enabled.").format(
frappe.bold(filters["presentation_currency"]),
frappe.bold("Show Credit / Debit in Company Currency"),
)
)
columns = [
{
@@ -592,19 +612,22 @@ def get_columns(filters):
{
"label": _("Debit ({0})").format(currency),
"fieldname": "debit",
"fieldtype": "Float",
"fieldtype": "Currency",
"options": "presentation_currency",
"width": 130,
},
{
"label": _("Credit ({0})").format(currency),
"fieldname": "credit",
"fieldtype": "Float",
"fieldtype": "Currency",
"options": "presentation_currency",
"width": 130,
},
{
"label": _("Balance ({0})").format(currency),
"fieldname": "balance",
"fieldtype": "Float",
"fieldtype": "Currency",
"options": "presentation_currency",
"width": 130,
},
{"label": _("Voucher Type"), "fieldname": "voucher_type", "width": 120},

View File

@@ -155,7 +155,7 @@ class TestGeneralLedger(FrappeTestCase):
"from_date": today(),
"to_date": today(),
"account": [account.name],
"group_by": "Group by Voucher (Consolidated)",
"categorize_by": "Categorize by Voucher (Consolidated)",
}
)
)
@@ -246,7 +246,7 @@ class TestGeneralLedger(FrappeTestCase):
"from_date": today(),
"to_date": today(),
"account": [account.name],
"group_by": "Group by Voucher (Consolidated)",
"categorize_by": "Categorize by Voucher (Consolidated)",
"ignore_err": True,
}
)
@@ -261,7 +261,7 @@ class TestGeneralLedger(FrappeTestCase):
"from_date": today(),
"to_date": today(),
"account": [account.name],
"group_by": "Group by Voucher (Consolidated)",
"categorize_by": "Categorize by Voucher (Consolidated)",
"ignore_err": False,
}
)
@@ -308,7 +308,7 @@ class TestGeneralLedger(FrappeTestCase):
"from_date": si.posting_date,
"to_date": si.posting_date,
"account": [si.debit_to],
"group_by": "Group by Voucher (Consolidated)",
"categorize_by": "Categorize by Voucher (Consolidated)",
"ignore_cr_dr_notes": False,
}
)
@@ -325,7 +325,7 @@ class TestGeneralLedger(FrappeTestCase):
"from_date": si.posting_date,
"to_date": si.posting_date,
"account": [si.debit_to],
"group_by": "Group by Voucher (Consolidated)",
"categorize_by": "Categorize by Voucher (Consolidated)",
"ignore_cr_dr_notes": True,
}
)

View File

@@ -11,7 +11,7 @@ import erpnext
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (
add_sub_total_row,
add_total_row,
apply_group_by_conditions,
apply_order_by_conditions,
get_grand_total,
get_group_by_and_display_fields,
get_tax_accounts,
@@ -305,12 +305,6 @@ def apply_conditions(query, pi, pii, filters):
if filters.get("item_group"):
query = query.where(pii.item_group == filters.get("item_group"))
if not filters.get("group_by"):
query = query.orderby(pi.posting_date, order=Order.desc)
query = query.orderby(pii.item_group, order=Order.desc)
else:
query = apply_group_by_conditions(query, pi, pii, filters)
return query
@@ -372,7 +366,17 @@ def get_items(filters, additional_table_columns):
query = apply_conditions(query, pi, pii, filters)
return query.run(as_dict=True)
from frappe.desk.reportview import build_match_conditions
query, params = query.walk()
match_conditions = build_match_conditions(doctype)
if match_conditions:
query += " and " + match_conditions
query = apply_order_by_conditions(query, pi, pii, filters)
return frappe.db.sql(query, params, as_dict=True)
def get_aii_accounts():

View File

@@ -384,27 +384,24 @@ def apply_conditions(query, si, sii, filters, additional_conditions=None):
| (si.unrealized_profit_loss_account == filters.get("income_account"))
)
if not filters.get("group_by"):
query = query.orderby(si.posting_date, order=Order.desc)
query = query.orderby(sii.item_group, order=Order.desc)
else:
query = apply_group_by_conditions(query, si, sii, filters)
for key, value in (additional_conditions or {}).items():
query = query.where(si[key] == value)
return query
def apply_group_by_conditions(query, si, ii, filters):
if filters.get("group_by") == "Invoice":
query = query.orderby(ii.parent, order=Order.desc)
def apply_order_by_conditions(query, si, ii, filters):
if not filters.get("group_by"):
query += f" order by {si.posting_date} desc, {ii.item_group} desc"
elif filters.get("group_by") == "Invoice":
query += f" order by {ii.parent} desc"
elif filters.get("group_by") == "Item":
query = query.orderby(ii.item_code)
query += f" order by {ii.item_code}"
elif filters.get("group_by") == "Item Group":
query = query.orderby(ii.item_group)
query += f" order by {ii.item_group}"
elif filters.get("group_by") in ("Customer", "Customer Group", "Territory", "Supplier"):
query = query.orderby(si[frappe.scrub(filters.get("group_by"))])
filter_field = frappe.scrub(filters.get("group_by"))
query += f" order by {filter_field} desc"
return query
@@ -479,7 +476,17 @@ def get_items(filters, additional_query_columns, additional_conditions=None):
query = apply_conditions(query, si, sii, filters, additional_conditions)
return query.run(as_dict=True)
from frappe.desk.reportview import build_match_conditions
query, params = query.walk()
match_conditions = build_match_conditions("Sales Invoice")
if match_conditions:
query += " and " + match_conditions
query = apply_order_by_conditions(query, si, sii, filters)
return frappe.db.sql(query, params, as_dict=True)
def get_delivery_notes_against_sales_order(item_list):

View File

@@ -46,6 +46,7 @@ class PaymentLedger:
against_voucher_no=ple.against_voucher_no,
amount=ple.amount,
currency=ple.account_currency,
company=ple.company,
)
if self.filters.include_account_currency:
@@ -77,6 +78,7 @@ class PaymentLedger:
against_voucher_no="Outstanding:",
amount=total,
currency=voucher_data[0].currency,
company=voucher_data[0].company,
)
if self.filters.include_account_currency:
@@ -85,7 +87,12 @@ class PaymentLedger:
voucher_data.append(entry)
# empty row
voucher_data.append(frappe._dict())
voucher_data.append(
frappe._dict(
currency=voucher_data[0].currency,
company=voucher_data[0].company,
)
)
self.data.extend(voucher_data)
def build_conditions(self):

View File

@@ -397,7 +397,6 @@ def get_invoices(filters, additional_query_columns):
pi.mode_of_payment,
)
.where(pi.docstatus == 1)
.orderby(pi.posting_date, pi.name, order=Order.desc)
)
if additional_query_columns:
@@ -413,8 +412,17 @@ def get_invoices(filters, additional_query_columns):
filters, query, doctype="Purchase Invoice", child_doctype="Purchase Invoice Item"
)
invoices = query.run(as_dict=True)
return invoices
from frappe.desk.reportview import build_match_conditions
query, params = query.walk()
match_conditions = build_match_conditions("Purchase Invoice")
if match_conditions:
query += " and " + match_conditions
query += " order by posting_date desc, name desc"
return frappe.db.sql(query, params, as_dict=True)
def get_conditions(filters, query, doctype):

View File

@@ -438,7 +438,6 @@ def get_invoices(filters, additional_query_columns):
si.company,
)
.where(si.docstatus == 1)
.orderby(si.posting_date, si.name, order=Order.desc)
)
if additional_query_columns:
@@ -453,8 +452,17 @@ def get_invoices(filters, additional_query_columns):
filters, query, doctype="Sales Invoice", child_doctype="Sales Invoice Item"
)
invoices = query.run(as_dict=True)
return invoices
from frappe.desk.reportview import build_match_conditions
query, params = query.walk()
match_conditions = build_match_conditions("Sales Invoice")
if match_conditions:
query += " and " + match_conditions
query += " order by posting_date desc, name desc"
return frappe.db.sql(query, params, as_dict=True)
def get_conditions(filters, query, doctype):

View File

@@ -4,6 +4,7 @@
import frappe
from frappe import _
from frappe.utils import getdate
def execute(filters=None):
@@ -33,6 +34,7 @@ def execute(filters=None):
def validate_filters(filters):
"""Validate if dates are properly set"""
filters = frappe._dict(filters or {})
if filters.from_date > filters.to_date:
frappe.throw(_("From Date must be before To Date"))
@@ -43,6 +45,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
gle_map = get_gle_map(tds_docs)
out = []
entries = {}
for name, details in gle_map.items():
for entry in details:
tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
@@ -68,7 +71,7 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
if not tax_withholding_category:
tax_withholding_category = party_map.get(party, {}).get("tax_withholding_category")
rate = tax_rate_map.get(tax_withholding_category)
rate = get_tax_withholding_rates(tax_rate_map.get(tax_withholding_category, []), posting_date)
if net_total_map.get((voucher_type, name)):
if voucher_type == "Journal Entry" and tax_amount and rate:
# back calcalute total amount from rate and tax_amount
@@ -117,9 +120,14 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_
"supplier_invoice_date": bill_date,
}
)
out.append(row)
out.sort(key=lambda x: x["section_code"])
key = entry.voucher_no
if key in entries:
entries[key]["tax_amount"] += tax_amount
else:
entries[key] = row
out = list(entries.values())
out.sort(key=lambda x: (x["section_code"], x["transaction_date"]))
return out
@@ -435,12 +443,22 @@ def get_doc_info(vouchers, doctype, tax_category_map, net_total_map=None):
def get_tax_rate_map(filters):
rate_map = frappe.get_all(
"Tax Withholding Rate",
filters={
"from_date": ("<=", filters.get("from_date")),
"to_date": (">=", filters.get("to_date")),
},
fields=["parent", "tax_withholding_rate"],
as_list=1,
filters={"from_date": ("<=", filters.to_date), "to_date": (">=", filters.from_date)},
fields=["parent", "tax_withholding_rate", "from_date", "to_date"],
)
return frappe._dict(rate_map)
rate_list = frappe._dict()
for rate in rate_map:
rate_list.setdefault(rate.parent, []).append(frappe._dict(rate))
return rate_list
def get_tax_withholding_rates(tax_withholding, posting_date):
# returns the row that matches with the fiscal year from posting date
for rate in tax_withholding:
if getdate(rate.from_date) <= getdate(posting_date) <= getdate(rate.to_date):
return rate.tax_withholding_rate
return 0

View File

@@ -3,7 +3,7 @@
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import today
from frappe.utils import add_to_date, today
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
@@ -60,6 +60,58 @@ class TestTdsPayableMonthly(AccountsTestMixin, FrappeTestCase):
]
self.check_expected_values(result, expected_values)
def test_date_filters_in_multiple_tax_withholding_rules(self):
create_tax_category("TDS - 3", rate=10, account="TDS - _TC", cumulative_threshold=1)
# insert new rate in same fiscal year
fiscal_year = get_fiscal_year(today(), company="_Test Company")
mid_year = add_to_date(fiscal_year[1], months=6)
tds_doc = frappe.get_doc("Tax Withholding Category", "TDS - 3")
tds_doc.rates[0].to_date = mid_year
from_date = add_to_date(mid_year, days=1)
tds_doc.append(
"rates",
{
"tax_withholding_rate": 20,
"from_date": from_date,
"to_date": fiscal_year[2],
"single_threshold": 1,
"cumulative_threshold": 1,
},
)
tds_doc.save()
inv_1 = make_purchase_invoice(
rate=1000, posting_date=add_to_date(fiscal_year[1], days=1), do_not_save=True, do_not_submit=True
)
inv_1.set_posting_time = 1
inv_1.apply_tds = 1
inv_1.tax_withholding_category = tds_doc.name
inv_1.save()
inv_1.submit()
inv_2 = make_purchase_invoice(rate=1000, posting_date=from_date, do_not_save=True, do_not_submit=True)
inv_2.set_posting_time = 1
inv_2.apply_tds = 1
inv_2.tax_withholding_category = tds_doc.name
inv_2.save()
inv_2.submit()
result = execute(
frappe._dict(
company="_Test Company",
party_type="Supplier",
from_date=fiscal_year[1],
to_date=fiscal_year[2],
)
)[1]
expected_values = [
[inv_1.name, "TDS - 3", 10.0, 5000, 500, 4500],
[inv_2.name, "TDS - 3", 20.0, 5000, 1000, 4000],
]
self.check_expected_values(result, expected_values)
def check_expected_values(self, result, expected_values):
for i in range(len(result)):
voucher = frappe._dict(result[i])

View File

@@ -79,8 +79,14 @@ frappe.require("assets/erpnext/js/financial_statements.js", function () {
options: erpnext.get_presentation_currency_list(),
},
{
fieldname: "with_period_closing_entry",
label: __("Period Closing Entry"),
fieldname: "with_period_closing_entry_for_opening",
label: __("With Period Closing Entry For Opening Balances"),
fieldtype: "Check",
default: 1,
},
{
fieldname: "with_period_closing_entry_for_current_period",
label: __("Period Closing Entry For Current Period"),
fieldtype: "Check",
default: 1,
},

View File

@@ -120,7 +120,7 @@ def get_data(filters):
max_rgt,
filters,
gl_entries_by_account,
ignore_closing_entries=not flt(filters.with_period_closing_entry),
ignore_closing_entries=not flt(filters.with_period_closing_entry_for_current_period),
ignore_opening_entries=True,
)
@@ -274,7 +274,7 @@ def get_opening_balance(
):
opening_balance = opening_balance.where(closing_balance.posting_date >= filters.year_start_date)
if not flt(filters.with_period_closing_entry):
if not flt(filters.with_period_closing_entry_for_opening):
if doctype == "Account Closing Balance":
opening_balance = opening_balance.where(closing_balance.is_period_closing_voucher_entry == 0)
else:

View File

@@ -4,15 +4,25 @@
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [
{
"fieldname": "company",
"fieldtype": "Link",
"label": "Company",
"mandatory": 1,
"options": "Company",
"wildcard_filter": 0
}
],
"idx": 0,
"is_standard": "Yes",
"modified": "2019-01-17 17:20:42.374958",
"modified": "2025-08-28 19:06:54.273322",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Trial Balance (Simple)",
"owner": "Administrator",
"prepared_report": 0,
"query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tfinance_book as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account",
"query": "select fiscal_year as \"Fiscal Year:Data:80\",\n\tcompany as \"Company:Data:220\",\n\tposting_date as \"Posting Date:Date:100\",\n\taccount as \"Account:Data:380\",\n\tsum(debit) as \"Debit:Currency:140\",\n\tsum(credit) as \"Credit:Currency:140\",\n\tfinance_book as \"Finance Book:Link/Finance Book:140\"\nfrom `tabGL Entry`\nwhere is_cancelled = 0 and company = %(company)s\ngroup by fiscal_year, company, posting_date, account\norder by fiscal_year, company, posting_date, account",
"ref_doctype": "GL Entry",
"report_name": "Trial Balance (Simple)",
"report_type": "Query Report",

View File

@@ -86,7 +86,7 @@ def get_rate_as_at(date, from_currency, to_currency):
return rate
def convert_to_presentation_currency(gl_entries, currency_info):
def convert_to_presentation_currency(gl_entries, currency_info, filters=None):
"""
Take a list of GL Entries and change the 'debit' and 'credit' values to currencies
in `currency_info`.
@@ -99,6 +99,13 @@ def convert_to_presentation_currency(gl_entries, currency_info):
company_currency = currency_info["company_currency"]
account_currencies = list(set(entry["account_currency"] for entry in gl_entries))
exchange_gain_or_loss = False
if filters and isinstance(filters.get("account"), list):
account_filter = filters.get("account")
gain_loss_account = frappe.db.get_value("Company", filters.company, "exchange_gain_loss_account")
exchange_gain_or_loss = len(account_filter) == 1 and account_filter[0] == gain_loss_account
for entry in gl_entries:
debit = flt(entry["debit"])
@@ -107,7 +114,11 @@ def convert_to_presentation_currency(gl_entries, currency_info):
credit_in_account_currency = flt(entry["credit_in_account_currency"])
account_currency = entry["account_currency"]
if len(account_currencies) == 1 and account_currency == presentation_currency:
if (
len(account_currencies) == 1
and account_currency == presentation_currency
and not exchange_gain_or_loss
) and not (filters and filters.get("show_amount_in_company_currency")):
entry["debit"] = debit_in_account_currency
entry["credit"] = credit_in_account_currency
else:

View File

@@ -12,8 +12,8 @@ DEFAULT_FILTERS = {
REPORT_FILTER_TEST_CASES: list[tuple[ReportName, ReportFilters]] = [
("General Ledger", {"group_by": "Group by Voucher (Consolidated)"}),
("General Ledger", {"group_by": "Group by Voucher (Consolidated)", "include_dimensions": 1}),
("General Ledger", {"categorize_by": "Categorize by Voucher (Consolidated)"}),
("General Ledger", {"categorize_by": "Categorize by Voucher (Consolidated)", "include_dimensions": 1}),
("Accounts Payable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}),
("Accounts Receivable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}),
("Consolidated Financial Statement", {"report": "Balance Sheet"}),

View File

@@ -2,12 +2,14 @@
# License: GNU General Public License v3. See license.txt
from collections import defaultdict
from json import loads
from typing import TYPE_CHECKING, Optional
import frappe
import frappe.defaults
from frappe import _, qb, throw
from frappe.desk.reportview import build_match_conditions
from frappe.model.meta import get_field_precision
from frappe.query_builder import AliasedQuery, Criterion, Table
from frappe.query_builder.functions import Round, Sum
@@ -26,6 +28,7 @@ from frappe.utils import (
nowdate,
)
from pypika import Order
from pypika.functions import Coalesce
from pypika.terms import ExistsCriterion
import erpnext
@@ -1788,14 +1791,17 @@ def update_voucher_outstanding(voucher_type, voucher_no, account, party_type, pa
):
outstanding = voucher_outstanding[0]
ref_doc = frappe.get_doc(voucher_type, voucher_no)
outstanding_amount = flt(
outstanding["outstanding_in_account_currency"], ref_doc.precision("outstanding_amount")
)
# Didn't use db_set for optimisation purpose
ref_doc.outstanding_amount = outstanding["outstanding_in_account_currency"] or 0.0
ref_doc.outstanding_amount = outstanding_amount
frappe.db.set_value(
voucher_type,
voucher_no,
"outstanding_amount",
outstanding["outstanding_in_account_currency"] or 0.0,
outstanding_amount,
)
ref_doc.set_status(update=True)
@@ -2188,3 +2194,44 @@ def run_ledger_health_checks():
doc.general_and_payment_ledger_mismatch = True
doc.checked_on = run_date
doc.save()
def get_link_fields_grouped_by_option(doctype):
meta = frappe.get_meta(doctype)
link_fields_map = defaultdict(list)
for df in meta.fields:
if df.fieldtype == "Link" and df.options and not df.ignore_user_permissions:
link_fields_map[df.options].append(df.fieldname)
return link_fields_map
def build_qb_match_conditions(doctype, user=None) -> list:
match_filters = build_match_conditions(doctype, user, False)
link_fields_map = get_link_fields_grouped_by_option(doctype)
criterion = []
apply_strict_user_permissions = frappe.get_system_settings("apply_strict_user_permissions")
if match_filters:
_dt = qb.DocType(doctype)
for filter in match_filters:
for link_option, allowed_values in filter.items():
fieldnames = link_fields_map.get(link_option, [])
cond = None
if link_option == doctype:
cond = _dt["name"].isin(allowed_values)
for fieldname in fieldnames:
field = _dt[fieldname]
cond = field.isin(allowed_values)
if not apply_strict_user_permissions:
cond = (Coalesce(field, "") == "") | cond
if cond:
criterion.append(cond)
return criterion

View File

@@ -152,6 +152,7 @@
{
"allow_on_submit": 1,
"fetch_from": "item_code.image",
"fetch_if_empty": 1,
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
@@ -582,7 +583,7 @@
"link_fieldname": "target_asset"
}
],
"modified": "2024-01-15 17:35:49.226603",
"modified": "2025-05-20 00:44:06.229177",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",

View File

@@ -635,38 +635,44 @@ class Asset(AccountsController):
return add_days(self.available_for_use_date, -1)
# if it returns True, depreciation_amount will not be equal for the first and last rows
def check_is_pro_rata(self, row, wdv_or_dd_non_yearly=False):
def check_is_pro_rata(asset_doc, row, wdv_or_dd_non_yearly=False):
has_pro_rata = False
# if not existing asset, from_date = available_for_use_date
# otherwise, if number_of_depreciations_booked = 2, available_for_use_date = 01/01/2020 and frequency_of_depreciation = 12
# from_date = 01/01/2022
from_date = self.get_modified_available_for_use_date(row, wdv_or_dd_non_yearly)
days = date_diff(row.depreciation_start_date, from_date) + 1
if wdv_or_dd_non_yearly:
total_days = get_total_days(row.depreciation_start_date, 12)
if row.depreciation_method in ("Straight Line", "Manual"):
prev_depreciation_start_date = get_last_day(
add_months(
row.depreciation_start_date,
(row.frequency_of_depreciation * -1) * asset_doc.number_of_depreciations_booked,
)
)
from_date = asset_doc.available_for_use_date
days = date_diff(prev_depreciation_start_date, from_date) + 1
total_days = get_total_days(prev_depreciation_start_date, row.frequency_of_depreciation)
else:
# if frequency_of_depreciation is 12 months, total_days = 365
from_date = _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False)
days = date_diff(row.depreciation_start_date, from_date) + 1
total_days = get_total_days(row.depreciation_start_date, row.frequency_of_depreciation)
if days <= 0:
frappe.throw(
_(
"""Error: This asset already has {0} depreciation periods booked.
The `depreciation start` date must be at least {1} periods after the `available for use` date.
Please correct the dates accordingly."""
).format(
asset_doc.number_of_depreciations_booked,
asset_doc.number_of_depreciations_booked,
)
)
if days < total_days:
has_pro_rata = True
return has_pro_rata
def get_modified_available_for_use_date(self, row, wdv_or_dd_non_yearly=False):
if wdv_or_dd_non_yearly:
return add_months(
self.available_for_use_date,
(self.number_of_depreciations_booked * 12),
)
else:
return add_months(
self.available_for_use_date,
(self.number_of_depreciations_booked * row.frequency_of_depreciation),
)
def validate_asset_finance_books(self, row):
if flt(row.expected_value_after_useful_life) >= flt(self.gross_purchase_amount):
frappe.throw(
@@ -1290,6 +1296,28 @@ def get_item_details(item_code, asset_category, gross_purchase_amount):
return books
def _get_modified_available_for_use_date(asset_doc, row, wdv_or_dd_non_yearly=False):
"""
if Asset has opening booked depreciations = 9,
available for use date = 17-07-2023,
depreciation start date = 30-04-2024
then from date should be 01-04-2024
"""
if asset_doc.number_of_depreciations_booked > 0:
from_date = add_months(
asset_doc.available_for_use_date,
(asset_doc.number_of_depreciations_booked * row.frequency_of_depreciation) - 1,
)
if is_last_day_of_the_month(row.depreciation_start_date):
return add_days(get_last_day(from_date), 1)
# get from date when depreciation start date is not last day of the month
months_difference = month_diff(row.depreciation_start_date, from_date) - 1
return add_days(add_months(row.depreciation_start_date, -1 * months_difference), 1)
else:
return asset_doc.available_for_use_date
def get_asset_account(account_name, asset=None, asset_category=None, company=None):
account = None
if asset:

View File

@@ -1451,7 +1451,7 @@ class TestDepreciationBasics(AssetSetup):
affects `value_after_depreciation`
"""
asset = create_asset(calculate_depreciation=1)
asset = create_asset(calculate_depreciation=1, depreciation_start_date="2021-12-31")
asset.opening_accumulated_depreciation = 2000
asset.number_of_depreciations_booked = 1

View File

@@ -380,7 +380,7 @@ erpnext.assets.AssetCapitalization = class AssetCapitalization extends erpnext.s
args: {
item_code: item.item_code,
warehouse: cstr(item.warehouse),
qty: flt(item.stock_qty),
qty: -1 * flt(item.stock_qty),
serial_no: item.serial_no,
posting_date: me.frm.doc.posting_date,
posting_time: me.frm.doc.posting_time,

View File

@@ -76,6 +76,7 @@
"fieldname": "completion_date",
"fieldtype": "Datetime",
"label": "Completion Date",
"mandatory_depends_on": "eval:doc.repair_status==\"Completed\"",
"no_copy": 1
},
{
@@ -264,7 +265,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2022-08-16 15:55:25.023471",
"modified": "2025-07-29 15:14:34.044564",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset Repair",
@@ -302,10 +303,11 @@
"write": 1
}
],
"row_format": "Dynamic",
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "asset_name",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _
from frappe.utils import add_months, cint, flt, getdate, time_diff_in_hours
from frappe.utils import add_months, cint, flt, get_link_to_form, getdate, time_diff_in_hours
import erpnext
from erpnext.accounts.general_ledger import make_gl_entries
@@ -20,6 +20,20 @@ class AssetRepair(AccountsController):
self.set_stock_items_cost()
self.calculate_total_repair_cost()
def validate_asset(self):
if self.asset_doc.status in ("Sold", "Fully Depreciated", "Scrapped"):
frappe.throw(
_("Asset {0} is in {1} status and cannot be repaired.").format(
get_link_to_form("Asset", self.asset), self.asset_doc.status
)
)
def validate_dates(self):
if self.completion_date and (getdate(self.failure_date) > getdate(self.completion_date)):
frappe.throw(
_("Completion Date can not be before Failure Date. Please adjust the dates accordingly.")
)
def update_status(self):
if self.repair_status == "Pending":
frappe.db.set_value("Asset", self.asset, "status", "Out of Order")
@@ -195,7 +209,7 @@ class AssetRepair(AccountsController):
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"posting_date": self.completion_date,
"against_voucher_type": "Purchase Invoice",
"against_voucher": self.purchase_invoice,
"company": self.company,
@@ -214,7 +228,7 @@ class AssetRepair(AccountsController):
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"posting_date": self.completion_date,
"company": self.company,
},
item=self,
@@ -248,7 +262,7 @@ class AssetRepair(AccountsController):
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"posting_date": self.completion_date,
"company": self.company,
},
item=self,
@@ -265,7 +279,7 @@ class AssetRepair(AccountsController):
"voucher_type": self.doctype,
"voucher_no": self.name,
"cost_center": self.cost_center,
"posting_date": getdate(),
"posting_date": self.completion_date,
"against_voucher_type": "Stock Entry",
"against_voucher": self.stock_entry,
"company": self.company,

View File

@@ -4,7 +4,7 @@
import unittest
import frappe
from frappe.utils import flt, nowdate
from frappe.utils import add_days, flt, nowdate
from erpnext.assets.doctype.asset.asset import (
get_asset_account,
@@ -288,6 +288,7 @@ def create_asset_repair(**args):
if args.submit:
asset_repair.repair_status = "Completed"
asset_repair.completion_date = add_days(args.failure_date, 1)
asset_repair.cost_center = frappe.db.get_value("Company", asset.company, "cost_center")
if args.stock_consumption:

View File

@@ -526,12 +526,8 @@ class TestPurchaseOrder(FrappeTestCase):
self.assertRaises(frappe.ValidationError, pr.submit)
self.assertRaises(frappe.ValidationError, pi.submit)
@change_settings("Accounts Settings", {"automatically_fetch_payment_terms": 1})
def test_make_purchase_invoice_with_terms(self):
from erpnext.selling.doctype.sales_order.test_sales_order import (
automatically_fetch_payment_terms,
)
automatically_fetch_payment_terms()
po = create_purchase_order(do_not_save=True)
self.assertRaises(frappe.ValidationError, make_pi_from_po, po.name)
@@ -555,7 +551,6 @@ class TestPurchaseOrder(FrappeTestCase):
self.assertEqual(getdate(pi.payment_schedule[0].due_date), getdate(po.transaction_date))
self.assertEqual(pi.payment_schedule[1].payment_amount, 2500.0)
self.assertEqual(getdate(pi.payment_schedule[1].due_date), add_days(getdate(po.transaction_date), 30))
automatically_fetch_payment_terms(enable=0)
def test_warehouse_company_validation(self):
from erpnext.stock.utils import InvalidWarehouseCompany
@@ -703,6 +698,7 @@ class TestPurchaseOrder(FrappeTestCase):
)
self.assertEqual(due_date, "2023-03-31")
@change_settings("Accounts Settings", {"automatically_fetch_payment_terms": 0})
def test_terms_are_not_copied_if_automatically_fetch_payment_terms_is_unchecked(self):
po = create_purchase_order(do_not_save=1)
po.payment_terms_template = "_Test Payment Term Template"
@@ -834,18 +830,16 @@ class TestPurchaseOrder(FrappeTestCase):
bo.load_from_db()
self.assertEqual(bo.items[0].ordered_qty, 5)
@change_settings("Accounts Settings", {"automatically_fetch_payment_terms": 1})
def test_payment_terms_are_fetched_when_creating_purchase_invoice(self):
from erpnext.accounts.doctype.payment_entry.test_payment_entry import (
create_payment_terms_template,
)
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.selling.doctype.sales_order.test_sales_order import (
automatically_fetch_payment_terms,
compare_payment_schedules,
)
automatically_fetch_payment_terms()
po = create_purchase_order(qty=10, rate=100, do_not_save=1)
create_payment_terms_template()
po.payment_terms_template = "Test Receivable Template"
@@ -859,8 +853,6 @@ class TestPurchaseOrder(FrappeTestCase):
# self.assertEqual(po.payment_terms_template, pi.payment_terms_template)
compare_payment_schedules(self, po, pi)
automatically_fetch_payment_terms(enable=0)
def test_internal_transfer_flow(self):
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
make_inter_company_purchase_invoice,

View File

@@ -9,6 +9,7 @@ from frappe import _
from frappe.core.doctype.communication.email import make
from frappe.desk.form.load import get_attachments
from frappe.model.mapper import get_mapped_doc
from frappe.query_builder import Order
from frappe.utils import get_url
from frappe.utils.print_format import download_pdf
from frappe.utils.user import get_user_fullname
@@ -502,35 +503,32 @@ def get_supplier_tag():
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_rfq_containing_supplier(doctype, txt, searchfield, start, page_len, filters):
conditions = ""
if txt:
conditions += "and rfq.name like '%%" + txt + "%%' "
rfq = frappe.qb.DocType("Request for Quotation")
rfq_supplier = frappe.qb.DocType("Request for Quotation Supplier")
if filters.get("transaction_date"):
conditions += "and rfq.transaction_date = '{}'".format(filters.get("transaction_date"))
rfq_data = frappe.db.sql(
f"""
select
distinct rfq.name, rfq.transaction_date,
rfq.company
from
`tabRequest for Quotation` rfq, `tabRequest for Quotation Supplier` rfq_supplier
where
rfq.name = rfq_supplier.parent
and rfq_supplier.supplier = %(supplier)s
and rfq.docstatus = 1
and rfq.company = %(company)s
{conditions}
order by rfq.transaction_date ASC
limit %(page_len)s offset %(start)s """,
{
"page_len": page_len,
"start": start,
"company": filters.get("company"),
"supplier": filters.get("supplier"),
},
as_dict=1,
query = (
frappe.qb.from_(rfq)
.from_(rfq_supplier)
.select(rfq.name)
.distinct()
.select(rfq.transaction_date, rfq.company)
.where(
(rfq.name == rfq_supplier.parent)
& (rfq_supplier.supplier == filters.get("supplier"))
& (rfq.docstatus == 1)
& (rfq.company == filters.get("company"))
)
.orderby(rfq.transaction_date, order=Order.asc)
.limit(page_len)
.offset(start)
)
if txt:
query = query.where(rfq.name.like(f"%%{txt}%%"))
if filters.get("transaction_date"):
query = query.where(rfq.transaction_date == filters.get("transaction_date"))
rfq_data = query.run(as_dict=1)
return rfq_data

View File

@@ -42,6 +42,11 @@ frappe.ui.form.on("Supplier", {
},
};
});
frm.make_methods = {
"Bank Account": () => erpnext.utils.make_bank_account(frm.doc.doctype, frm.doc.name),
"Pricing Rule": () => erpnext.utils.make_pricing_rule(frm.doc.doctype, frm.doc.name),
};
},
refresh: function (frm) {
@@ -84,21 +89,9 @@ frappe.ui.form.on("Supplier", {
__("View")
);
frm.add_custom_button(
__("Bank Account"),
function () {
erpnext.utils.make_bank_account(frm.doc.doctype, frm.doc.name);
},
__("Create")
);
frm.add_custom_button(__("Bank Account"), () => frm.make_methods["Bank Account"](), __("Create"));
frm.add_custom_button(
__("Pricing Rule"),
function () {
erpnext.utils.make_pricing_rule(frm.doc.doctype, frm.doc.name);
},
__("Create")
);
frm.add_custom_button(__("Pricing Rule"), () => frm.make_methods["Pricing Rule"](), __("Create"));
frm.add_custom_button(
__("Get Supplier Group Details"),
@@ -108,7 +101,10 @@ frappe.ui.form.on("Supplier", {
__("Actions")
);
if (cint(frappe.defaults.get_default("enable_common_party_accounting"))) {
if (
cint(frappe.defaults.get_default("enable_common_party_accounting")) &&
frappe.model.can_create("Party Link")
) {
frm.add_custom_button(
__("Link with Customer"),
function () {

View File

@@ -94,9 +94,6 @@
</script>
</head>
<div style="margin-bottom: 7px;" class="text-center">
{%= frappe.boot.letter_heads[frappe.defaults.get_default("letter_head")] %}
</div>
<h2 class="text-center">{%= __(report.report_name) %}</h2>
<h4 class="text-center">{%= filters.item %} </h4>
@@ -124,9 +121,7 @@
</tbody>
</table>
<h4 class="text-center"> Analysis Chart </h4>
<h4 class="text-center">{%= __("Analysis Chart") %}</h4>
<div id="chart_div"></div>
<p class="text-right text-muted">Printed On {%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
<p class="text-right text-muted">{%= __("Printed on {0}", [frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string())]) %}</p>

View File

@@ -76,14 +76,14 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
},
},
{
fieldname: "group_by",
label: __("Group by"),
fieldname: "categorize_by",
label: __("Categorize by"),
fieldtype: "Select",
options: [
{ label: __("Group by Supplier"), value: "Group by Supplier" },
{ label: __("Group by Item"), value: "Group by Item" },
{ label: __("Categorize by Supplier"), value: "Categorize by Supplier" },
{ label: __("Categorize by Item"), value: "Categorize by Item" },
],
default: __("Group by Supplier"),
default: __("Categorize by Supplier"),
},
{
fieldtype: "Check",

View File

@@ -15,6 +15,8 @@ def execute(filters=None):
if not filters:
return [], []
validate_filters(filters)
columns = get_columns(filters)
supplier_quotation_data = get_data(filters)
@@ -24,6 +26,12 @@ def execute(filters=None):
return columns, data, message, chart_data
def validate_filters(filters):
if not filters.get("categorize_by") and filters.get("group_by"):
filters["categorize_by"] = filters["group_by"]
filters["categorize_by"] = filters["categorize_by"].replace("Group by", "Categorize by")
def get_data(filters):
sq = frappe.qb.DocType("Supplier Quotation")
sq_item = frappe.qb.DocType("Supplier Quotation Item")
@@ -82,7 +90,9 @@ def prepare_data(supplier_quotation_data, filters):
group_wise_map = defaultdict(list)
supplier_qty_price_map = {}
group_by_field = "supplier_name" if filters.get("group_by") == "Group by Supplier" else "item_code"
group_by_field = (
"supplier_name" if filters.get("categorize_by") == "Categorize by Supplier" else "item_code"
)
company_currency = frappe.db.get_default("currency")
float_precision = cint(frappe.db.get_default("float_precision")) or 2
@@ -274,7 +284,7 @@ def get_columns(filters):
},
]
if filters.get("group_by") == "Group by Item":
if filters.get("categorize_by") == "Categorize by Item":
group_by_columns.reverse()
columns[0:0] = group_by_columns # add positioned group by columns to the report

View File

@@ -20,6 +20,9 @@ def update_last_purchase_rate(doc, is_submit) -> None:
this_purchase_date = getdate(doc.get("posting_date") or doc.get("transaction_date"))
for d in doc.get("items"):
if d.get("is_free_item"):
continue
# get last purchase details
last_purchase_details = get_last_purchase_details(d.item_code, doc.name)

View File

@@ -153,6 +153,48 @@ class AccountsController(TransactionBase):
raise_exception=1,
)
def validate_against_voucher_outstanding(self):
from frappe.model.meta import get_meta
if not get_meta(self.doctype).has_field("outstanding_amount"):
return
if self.get("is_return") and self.return_against and not self.get("is_pos"):
against_voucher_outstanding = frappe.get_value(
self.doctype, self.return_against, "outstanding_amount"
)
document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note"
msg = ""
if self.get("update_outstanding_for_self"):
msg = (
"We can see {0} is made against {1}. If you want {1}'s outstanding to be updated, "
"uncheck '{2}' checkbox. <br><br>Or"
).format(
frappe.bold(document_type),
get_link_to_form(self.doctype, self.get("return_against")),
frappe.bold(_("Update Outstanding for Self")),
)
elif not self.update_outstanding_for_self and (
abs(flt(self.rounded_total) or flt(self.grand_total)) > flt(against_voucher_outstanding)
):
self.update_outstanding_for_self = 1
msg = (
"The outstanding amount {} in {} is lesser than {}. Updating the outstanding to this invoice. <br><br>And"
).format(
against_voucher_outstanding,
get_link_to_form(self.doctype, self.get("return_against")),
flt(abs(self.outstanding_amount)),
)
if msg:
msg += " you can use {} tool to reconcile against {} later.".format(
get_link_to_form("Payment Reconciliation", "Payment Reconciliation"),
get_link_to_form(self.doctype, self.get("return_against")),
)
frappe.msgprint(_(msg))
def validate(self):
if not self.get("is_return") and not self.get("is_debit_note"):
self.validate_qty_is_not_zero()
@@ -171,6 +213,11 @@ class AccountsController(TransactionBase):
self.validate_date_with_fiscal_year()
self.validate_party_accounts()
if self.doctype in ["Sales Invoice", "Purchase Invoice"]:
if self.is_return:
self.validate_qty()
else:
self.validate_deferred_start_and_end_date()
self.validate_inter_company_reference()
@@ -178,6 +225,7 @@ class AccountsController(TransactionBase):
self.disable_tax_included_prices_for_internal_transfer()
self.set_incoming_rate()
self.init_internal_values()
self.validate_against_voucher_outstanding()
if self.meta.get_field("currency"):
self.calculate_taxes_and_totals()
@@ -209,31 +257,12 @@ class AccountsController(TransactionBase):
)
)
if self.get("is_return") and self.get("return_against") and not self.get("is_pos"):
if self.get("update_outstanding_for_self"):
document_type = "Credit Note" if self.doctype == "Sales Invoice" else "Debit Note"
frappe.msgprint(
_(
"We can see {0} is made against {1}. If you want {1}'s outstanding to be updated, uncheck '{2}' checkbox. <br><br> Or you can use {3} tool to reconcile against {1} later."
).format(
frappe.bold(document_type),
get_link_to_form(self.doctype, self.get("return_against")),
frappe.bold("Update Outstanding for Self"),
get_link_to_form("Payment Reconciliation", "Payment Reconciliation"),
)
)
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
if cint(self.allocate_advances_automatically) and not cint(self.get(pos_check_field)):
self.set_advances()
self.set_advance_gain_or_loss()
if self.is_return:
self.validate_qty()
else:
self.validate_deferred_start_and_end_date()
self.validate_deferred_income_expense_account()
self.set_inter_company_account()
@@ -655,7 +684,9 @@ class AccountsController(TransactionBase):
"Customer",
self.customer,
self.company,
None,
self.payment_terms_template,
self.doctype,
)
elif self.doctype == "Purchase Invoice":
validate_due_date(
@@ -666,6 +697,7 @@ class AccountsController(TransactionBase):
self.company,
self.bill_date,
self.payment_terms_template,
self.doctype,
)
def set_price_list_currency(self, buying_or_selling):
@@ -1710,69 +1742,50 @@ class AccountsController(TransactionBase):
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on):
from erpnext.controllers.status_updater import get_allowance_for
item_allowance = {}
global_qty_allowance, global_amount_allowance = None, None
ref_wise_billed_amount = self.get_reference_wise_billed_amt(ref_dt, item_ref_dn, based_on)
role_allowed_to_over_bill = frappe.get_cached_value(
"Accounts Settings", None, "role_allowed_to_over_bill"
)
user_roles = frappe.get_roles()
if not ref_wise_billed_amount:
return
total_overbilled_amt = 0.0
overbilled_items = []
precision = self.precision(based_on, "items")
precision_allowance = 1 / (10**precision)
reference_names = [d.get(item_ref_dn) for d in self.get("items") if d.get(item_ref_dn)]
reference_details = self.get_billing_reference_details(reference_names, ref_dt + " Item", based_on)
role_allowed_to_overbill = frappe.get_cached_value(
"Accounts Settings", None, "role_allowed_to_over_bill"
)
is_overbilling_allowed = role_allowed_to_overbill in frappe.get_roles()
for item in self.get("items"):
if not item.get(item_ref_dn):
continue
for row in ref_wise_billed_amount.values():
total_billed_amt = row.billed_amt
allowance = get_allowance_for(row.item_code, {}, None, None, "amount")[0]
ref_amt = flt(reference_details.get(item.get(item_ref_dn)), self.precision(based_on, item))
based_on_amt = flt(item.get(based_on))
if not ref_amt:
if based_on_amt: # Skip warning for free items
frappe.msgprint(
_(
"System will not check over billing since amount for Item {0} in {1} is zero"
).format(item.item_code, ref_dt),
title=_("Warning"),
indicator="orange",
)
continue
already_billed = self.get_billed_amount_for_item(item, item_ref_dn, based_on)
total_billed_amt = flt(flt(already_billed) + based_on_amt, self.precision(based_on, item))
allowance, item_allowance, global_qty_allowance, global_amount_allowance = get_allowance_for(
item.item_code, item_allowance, global_qty_allowance, global_amount_allowance, "amount"
)
max_allowed_amt = flt(ref_amt * (100 + allowance) / 100)
max_allowed_amt = flt(row.ref_amt * (100 + allowance) / 100)
if total_billed_amt < 0 and max_allowed_amt < 0:
# while making debit note against purchase return entry(purchase receipt) getting overbill error
total_billed_amt = abs(total_billed_amt)
max_allowed_amt = abs(max_allowed_amt)
total_billed_amt, max_allowed_amt = abs(total_billed_amt), abs(max_allowed_amt)
overbill_amt = total_billed_amt - max_allowed_amt
row["max_allowed_amt"] = max_allowed_amt
total_overbilled_amt += overbill_amt
if overbill_amt > 0.01 and role_allowed_to_over_bill not in user_roles:
if self.doctype != "Purchase Invoice":
self.throw_overbill_exception(item, max_allowed_amt)
elif not cint(
if overbill_amt > precision_allowance and not is_overbilling_allowed:
if self.doctype != "Purchase Invoice" or not cint(
frappe.db.get_single_value(
"Buying Settings", "bill_for_rejected_quantity_in_purchase_invoice"
)
):
self.throw_overbill_exception(item, max_allowed_amt)
overbilled_items.append(row)
if role_allowed_to_over_bill in user_roles and total_overbilled_amt > 0.1:
if overbilled_items:
self.throw_overbill_exception(overbilled_items, precision)
if is_overbilling_allowed and total_overbilled_amt > 0.1:
frappe.msgprint(
_("Overbilling of {} ignored because you have {} role.").format(
total_overbilled_amt, role_allowed_to_over_bill
total_overbilled_amt, role_allowed_to_overbill
),
indicator="orange",
alert=True,
@@ -1788,55 +1801,88 @@ class AccountsController(TransactionBase):
)
)
def get_billed_amount_for_item(self, item, item_ref_dn, based_on):
def get_reference_wise_billed_amt(self, ref_dt, item_ref_dn, based_on):
"""
Returns Sum of Amount of
Sales/Purchase Invoice Items
that are linked to `item_ref_dn` (`dn_detail` / `pr_detail`)
that are submitted OR not submitted but are under current invoice
"""
reference_names = [d.get(item_ref_dn) for d in self.items if d.get(item_ref_dn)]
from frappe.query_builder import Criterion
from frappe.query_builder.functions import Sum
if not reference_names:
return
item_doctype = frappe.qb.DocType(item.doctype)
ref_wise_billed_amount = {}
precision = self.precision(based_on, "items")
reference_details = self.get_billing_reference_details(reference_names, ref_dt + " Item", based_on)
already_billed = self.get_already_billed_amount(reference_names, item_ref_dn, based_on)
for item in self.items:
key = item.get(item_ref_dn)
if not key:
continue
ref_amt = flt(reference_details.get(key), precision)
current_amount = flt(item.get(based_on), precision)
if not ref_amt:
if current_amount: # Skip warning for free items
frappe.msgprint(
_(
"System will not check over billing since amount for Item {0} in {1} is zero"
).format(item.item_code, ref_dt),
title=_("Warning"),
indicator="orange",
)
continue
ref_wise_billed_amount.setdefault(
key,
frappe._dict(item_code=item.item_code, billed_amt=0.0, ref_amt=ref_amt, rows=[]),
)
ref_wise_billed_amount[key]["rows"].append(item.idx)
ref_wise_billed_amount[key]["ref_amt"] = ref_amt
ref_wise_billed_amount[key]["billed_amt"] += current_amount
if key in already_billed:
ref_wise_billed_amount[key]["billed_amt"] += flt(already_billed.pop(key, 0), precision)
return ref_wise_billed_amount
def get_already_billed_amount(self, reference_names, item_ref_dn, based_on):
item_doctype = frappe.qb.DocType(self.items[0].doctype)
based_on_field = frappe.qb.Field(based_on)
join_field = frappe.qb.Field(item_ref_dn)
result = (
frappe.qb.from_(item_doctype)
.select(Sum(based_on_field))
.where(join_field == item.get(item_ref_dn))
.where(
Criterion.any(
[ # select all items from other invoices OR current invoices
Criterion.all(
[ # for selecting items from other invoices
item_doctype.docstatus == 1,
item_doctype.parent != self.name,
]
),
Criterion.all(
[ # for selecting items from current invoice, that are linked to same reference
item_doctype.docstatus == 0,
item_doctype.parent == self.name,
item_doctype.name != item.name,
]
),
]
)
)
).run()
return result[0][0] if result else 0
def throw_overbill_exception(self, item, max_allowed_amt):
frappe.throw(
_(
"Cannot overbill for Item {0} in row {1} more than {2}. To allow over-billing, please set allowance in Accounts Settings"
).format(item.item_code, item.idx, max_allowed_amt)
return frappe._dict(
(
frappe.qb.from_(item_doctype)
.select(join_field, Sum(based_on_field))
.where(join_field.isin(reference_names))
.where((item_doctype.docstatus == 1) & (item_doctype.parent != self.name))
.groupby(join_field)
).run()
)
def throw_overbill_exception(self, overbilled_items, precision):
message = (
_("<p>Cannot overbill for the following Items:</p>")
+ "<ul>"
+ "".join(
_("<li>Item {0} in row(s) {1} billed more than {2}</li>").format(
frappe.bold(item.item_code),
", ".join(str(x) for x in item.rows),
frappe.bold(fmt_money(item.max_allowed_amt, precision=precision, currency=self.currency)),
)
for item in overbilled_items
)
+ "</ul>"
)
message += _("<p>To allow over-billing, please set allowance in Accounts Settings.</p>")
frappe.throw(_(message))
def get_company_default(self, fieldname, ignore_validation=False):
from erpnext.accounts.utils import get_company_default
@@ -2100,7 +2146,9 @@ class AccountsController(TransactionBase):
and automatically_fetch_payment_terms
and self.linked_order_has_payment_terms(po_or_so, fieldname, doctype)
):
self.fetch_payment_terms_from_order(po_or_so, doctype)
self.fetch_payment_terms_from_order(
po_or_so, doctype, grand_total, base_grand_total, automatically_fetch_payment_terms
)
if self.get("payment_terms_template"):
self.ignore_default_payment_terms_template = 1
elif self.get("payment_terms_template"):
@@ -2141,7 +2189,9 @@ class AccountsController(TransactionBase):
d.payment_amount * self.get("conversion_rate"), d.precision("base_payment_amount")
)
else:
self.fetch_payment_terms_from_order(po_or_so, doctype)
self.fetch_payment_terms_from_order(
po_or_so, doctype, grand_total, base_grand_total, automatically_fetch_payment_terms
)
self.ignore_default_payment_terms_template = 1
def get_order_details(self):
@@ -2179,7 +2229,9 @@ class AccountsController(TransactionBase):
def linked_order_has_payment_schedule(self, po_or_so):
return frappe.get_all("Payment Schedule", filters={"parent": po_or_so})
def fetch_payment_terms_from_order(self, po_or_so, po_or_so_doctype):
def fetch_payment_terms_from_order(
self, po_or_so, po_or_so_doctype, grand_total, base_grand_total, automatically_fetch_payment_terms
):
"""
Fetch Payment Terms from Purchase/Sales Order on creating a new Purchase/Sales Invoice.
"""
@@ -2187,6 +2239,7 @@ class AccountsController(TransactionBase):
self.payment_schedule = []
self.payment_terms_template = po_or_so.payment_terms_template
posting_date = self.get("bill_date") or self.get("posting_date") or self.get("transaction_date")
for schedule in po_or_so.payment_schedule:
payment_schedule = {
@@ -2195,12 +2248,36 @@ class AccountsController(TransactionBase):
"invoice_portion": schedule.invoice_portion,
"mode_of_payment": schedule.mode_of_payment,
"description": schedule.description,
"payment_amount": schedule.payment_amount,
"base_payment_amount": schedule.base_payment_amount,
"outstanding": schedule.outstanding,
"paid_amount": schedule.paid_amount,
}
if automatically_fetch_payment_terms:
if schedule.due_date_based_on:
payment_schedule["due_date"] = get_due_date(schedule, posting_date)
payment_schedule["due_date_based_on"] = schedule.due_date_based_on
payment_schedule["credit_days"] = cint(schedule.credit_days)
payment_schedule["credit_months"] = cint(schedule.credit_months)
if schedule.discount_validity_based_on:
payment_schedule["discount_date"] = get_discount_date(schedule, posting_date)
payment_schedule["discount_validity_based_on"] = schedule.discount_validity_based_on
payment_schedule["discount_validity"] = cint(schedule.discount_validity)
payment_schedule["payment_amount"] = flt(
grand_total * flt(payment_schedule["invoice_portion"]) / 100,
schedule.precision("payment_amount"),
)
payment_schedule["base_payment_amount"] = flt(
base_grand_total * flt(payment_schedule["invoice_portion"]) / 100,
schedule.precision("base_payment_amount"),
)
payment_schedule["outstanding"] = payment_schedule["payment_amount"]
else:
payment_schedule["base_payment_amount"] = flt(
schedule.base_payment_amount * self.get("conversion_rate"),
schedule.precision("base_payment_amount"),
)
if schedule.discount_type == "Percentage":
payment_schedule["discount_type"] = schedule.discount_type
payment_schedule["discount"] = schedule.discount
@@ -2459,12 +2536,17 @@ class AccountsController(TransactionBase):
default_currency = erpnext.get_company_currency(self.company)
if not default_currency:
throw(_("Please enter default currency in Company Master"))
if (
(self.currency == default_currency and flt(self.conversion_rate) != 1.00)
or not self.conversion_rate
or (self.currency != default_currency and flt(self.conversion_rate) == 1.00)
):
throw(_("Conversion rate cannot be 0 or 1"))
if not self.conversion_rate:
throw(_("Conversion rate cannot be 0"))
if self.currency == default_currency and flt(self.conversion_rate) != 1.00:
throw(_("Conversion rate must be 1.00 if document currency is same as company currency"))
if self.currency != default_currency and flt(self.conversion_rate) == 1.00:
frappe.msgprint(
_("Conversion rate is 1.00, but document currency is different from company currency")
)
def check_finance_books(self, item, asset):
if (
@@ -2917,14 +2999,26 @@ def get_payment_term_details(
term = frappe.get_doc("Payment Term", term)
else:
term_details.payment_term = term.payment_term
term_details.description = term.description
term_details.invoice_portion = term.invoice_portion
fields_to_copy = [
"description",
"invoice_portion",
"discount_type",
"discount",
"mode_of_payment",
"due_date_based_on",
"credit_days",
"credit_months",
"discount_validity_based_on",
"discount_validity",
]
for field in fields_to_copy:
term_details[field] = term.get(field)
term_details.payment_amount = flt(term.invoice_portion) * flt(grand_total) / 100
term_details.base_payment_amount = flt(term.invoice_portion) * flt(base_grand_total) / 100
term_details.discount_type = term.discount_type
term_details.discount = term.discount
term_details.outstanding = term_details.payment_amount
term_details.mode_of_payment = term.mode_of_payment
if bill_date:
term_details.due_date = get_due_date(term, bill_date)
@@ -2943,11 +3037,11 @@ def get_due_date(term, posting_date=None, bill_date=None):
due_date = None
date = bill_date or posting_date
if term.due_date_based_on == "Day(s) after invoice date":
due_date = add_days(date, term.credit_days)
due_date = add_days(date, cint(term.credit_days))
elif term.due_date_based_on == "Day(s) after the end of the invoice month":
due_date = add_days(get_last_day(date), term.credit_days)
due_date = add_days(get_last_day(date), cint(term.credit_days))
elif term.due_date_based_on == "Month(s) after the end of the invoice month":
due_date = get_last_day(add_months(date, term.credit_months))
due_date = get_last_day(add_months(date, cint(term.credit_months)))
return due_date
@@ -2955,11 +3049,11 @@ def get_discount_date(term, posting_date=None, bill_date=None):
discount_validity = None
date = bill_date or posting_date
if term.discount_validity_based_on == "Day(s) after invoice date":
discount_validity = add_days(date, term.discount_validity)
discount_validity = add_days(date, cint(term.discount_validity))
elif term.discount_validity_based_on == "Day(s) after the end of the invoice month":
discount_validity = add_days(get_last_day(date), term.discount_validity)
discount_validity = add_days(get_last_day(date), cint(term.discount_validity))
elif term.discount_validity_based_on == "Month(s) after the end of the invoice month":
discount_validity = get_last_day(add_months(date, term.discount_validity))
discount_validity = get_last_day(add_months(date, cint(term.discount_validity)))
return discount_validity

View File

@@ -6,7 +6,7 @@ import json
from collections import defaultdict
import frappe
from frappe import qb, scrub
from frappe import cint, qb, scrub
from frappe.desk.reportview import get_filters_cond, get_match_cond
from frappe.query_builder import Criterion, CustomFunction
from frappe.query_builder.functions import Locate
@@ -528,21 +528,27 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_blanket_orders(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(
"""select distinct bo.name, bo.blanket_order_type, bo.to_date
from `tabBlanket Order` bo, `tabBlanket Order Item` boi
where
boi.parent = bo.name
and boi.item_code = {item_code}
and bo.blanket_order_type = '{blanket_order_type}'
and bo.company = {company}
and bo.docstatus = 1""".format(
item_code=frappe.db.escape(filters.get("item")),
blanket_order_type=filters.get("blanket_order_type"),
company=frappe.db.escape(filters.get("company")),
bo = frappe.qb.DocType("Blanket Order")
bo_item = frappe.qb.DocType("Blanket Order Item")
blanket_orders = (
frappe.qb.from_(bo)
.from_(bo_item)
.select(bo.name)
.distinct()
.select(bo.blanket_order_type, bo.to_date)
.where(
(bo_item.parent == bo.name)
& (bo_item.item_code == filters.get("item"))
& (bo.blanket_order_type == filters.get("blanket_order_type"))
& (bo.company == filters.get("company"))
& (bo.docstatus == 1)
)
.run()
)
return blanket_orders
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
@@ -560,7 +566,7 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters):
if filters.get("company"):
condition += "and tabAccount.company = %(company)s"
condition += f"and tabAccount.disabled = {filters.get('disabled', 0)}"
condition += " and tabAccount.disabled = %(disabled)s"
return frappe.db.sql(
f"""select tabAccount.name from `tabAccount`
@@ -570,7 +576,11 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters):
and tabAccount.`{searchfield}` LIKE %(txt)s
{condition} {get_match_cond(doctype)}
order by idx desc, name""",
{"txt": "%" + txt + "%", "company": filters.get("company", "")},
{
"txt": "%" + txt + "%",
"company": filters.get("company", ""),
"disabled": cint(filters.get("disabled", 0)),
},
)
@@ -646,7 +656,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
where (tabAccount.report_type = "Profit and Loss"
or tabAccount.account_type in ("Expense Account", "Fixed Asset", "Temporary", "Asset Received But Not Billed", "Capital Work in Progress"))
and tabAccount.is_group=0
and tabAccount.docstatus!=2
and tabAccount.disabled = 0
and tabAccount.{searchfield} LIKE %(txt)s
{condition} {get_match_cond(doctype)}""",
{"company": filters.get("company", ""), "txt": "%" + txt + "%"},

View File

@@ -368,7 +368,7 @@ def make_return_doc(doctype: str, source_name: str, target_doc=None):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
company = frappe.db.get_value("Delivery Note", source_name, "company")
company = frappe.db.get_value(doctype, source_name, "company")
default_warehouse_for_sales_return = frappe.get_cached_value(
"Company", company, "default_warehouse_for_sales_return"
)

View File

@@ -520,8 +520,9 @@ class StockController(AccountsController):
make_sl_entries(sl_entries, allow_negative_stock, via_landed_cost_voucher)
def make_gl_entries_on_cancel(self):
cancel_exchange_gain_loss_journal(frappe._dict(doctype=self.doctype, name=self.name))
def make_gl_entries_on_cancel(self, from_repost=False):
if not from_repost:
cancel_exchange_gain_loss_journal(frappe._dict(doctype=self.doctype, name=self.name))
if frappe.db.sql(
"""select name from `tabGL Entry` where voucher_type=%s
and voucher_no=%s""",
@@ -1027,12 +1028,7 @@ def is_reposting_pending():
)
def future_sle_exists(args, sl_entries=None, allow_force_reposting=True):
if allow_force_reposting and frappe.db.get_single_value(
"Stock Reposting Settings", "do_reposting_for_each_stock_transaction"
):
return True
def future_sle_exists(args, sl_entries=None):
key = (args.voucher_type, args.voucher_no)
if not hasattr(frappe.local, "future_sle"):
frappe.local.future_sle = {}

View File

@@ -373,9 +373,7 @@ class calculate_taxes_and_totals:
self._calculate()
def calculate_taxes(self):
rounding_adjustment_computed = self.doc.get("is_consolidated") and self.doc.get("rounding_adjustment")
if not rounding_adjustment_computed:
self.doc.rounding_adjustment = 0
self.grand_total_diff = 0
# maintain actual tax rate based on idx
actual_tax_dict = dict(
@@ -440,9 +438,8 @@ class calculate_taxes_and_totals:
and self.discount_amount_applied
and self.doc.discount_amount
and self.doc.apply_discount_on == "Grand Total"
and not rounding_adjustment_computed
):
self.doc.rounding_adjustment = flt(
self.grand_total_diff = flt(
self.doc.grand_total - flt(self.doc.discount_amount) - tax.total,
self.doc.precision("rounding_adjustment"),
)
@@ -528,11 +525,11 @@ class calculate_taxes_and_totals:
return self.adjust_grand_total_for_inclusive_tax()
def adjust_grand_total_for_inclusive_tax(self):
# if fully inclusive taxes and diff
# if any inclusive taxes and diff
if self.doc.get("taxes") and any(cint(t.included_in_print_rate) for t in self.doc.get("taxes")):
last_tax = self.doc.get("taxes")[-1]
non_inclusive_tax_amount = sum(
flt(d.tax_amount_after_discount_amount)
self.get_tax_amount_if_for_valuation_or_deduction(d.tax_amount_after_discount_amount, d)
for d in self.doc.get("taxes")
if not d.included_in_print_rate
)
@@ -549,27 +546,23 @@ class calculate_taxes_and_totals:
diff = flt(diff, self.doc.precision("rounding_adjustment"))
if diff and abs(diff) <= (5.0 / 10 ** last_tax.precision("tax_amount")):
self.doc.grand_total_diff = diff
else:
self.doc.grand_total_diff = 0
self.grand_total_diff = diff
def calculate_totals(self):
if self.doc.get("taxes"):
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + flt(
self.doc.get("grand_total_diff")
)
self.doc.grand_total = flt(self.doc.get("taxes")[-1].total) + self.grand_total_diff
else:
self.doc.grand_total = flt(self.doc.net_total)
if self.doc.get("taxes"):
self.doc.total_taxes_and_charges = flt(
self.doc.grand_total - self.doc.net_total - flt(self.doc.get("grand_total_diff")),
self.doc.grand_total - self.doc.net_total - self.grand_total_diff,
self.doc.precision("total_taxes_and_charges"),
)
else:
self.doc.total_taxes_and_charges = 0.0
self._set_in_company_currency(self.doc, ["total_taxes_and_charges", "rounding_adjustment"])
self._set_in_company_currency(self.doc, ["total_taxes_and_charges"])
if self.doc.doctype in [
"Quotation",
@@ -619,7 +612,9 @@ class calculate_taxes_and_totals:
if self.doc.meta.get_field("rounded_total"):
if self.doc.is_rounded_total_disabled():
self.doc.rounded_total = self.doc.base_rounded_total = 0
self.doc.rounded_total = 0
self.doc.base_rounded_total = 0
self.doc.rounding_adjustment = 0
return
self.doc.rounded_total = round_based_on_smallest_currency_fraction(
@@ -663,33 +658,29 @@ class calculate_taxes_and_totals:
return
total_for_discount_amount = self.get_total_for_discount_amount()
taxes = self.doc.get("taxes")
net_total = 0
expected_net_total = 0
if total_for_discount_amount:
# calculate item amount after Discount Amount
for i, item in enumerate(self._items):
for item in self._items:
distributed_amount = (
flt(self.doc.discount_amount) * item.net_amount / total_for_discount_amount
)
item.net_amount = flt(item.net_amount - distributed_amount, item.precision("net_amount"))
adjusted_net_amount = item.net_amount - distributed_amount
expected_net_total += adjusted_net_amount
item.net_amount = flt(adjusted_net_amount, item.precision("net_amount"))
net_total += item.net_amount
# discount amount rounding loss adjustment if no taxes
if (
self.doc.apply_discount_on == "Net Total"
or not taxes
or total_for_discount_amount == self.doc.net_total
) and i == len(self._items) - 1:
discount_amount_loss = flt(
self.doc.net_total - net_total - self.doc.discount_amount,
self.doc.precision("net_total"),
)
# discount amount rounding adjustment
if rounding_difference := flt(
expected_net_total - net_total, self.doc.precision("net_total")
):
item.net_amount = flt(
item.net_amount + discount_amount_loss, item.precision("net_amount")
item.net_amount + rounding_difference, item.precision("net_amount")
)
net_total += rounding_difference
item.net_rate = (
flt(item.net_amount / item.qty, item.precision("net_rate")) if item.qty else 0
@@ -705,20 +696,44 @@ class calculate_taxes_and_totals:
def get_total_for_discount_amount(self):
if self.doc.apply_discount_on == "Net Total":
return self.doc.net_total
else:
actual_taxes_dict = {}
for tax in self.doc.get("taxes"):
if tax.charge_type in ["Actual", "On Item Quantity"]:
tax_amount = self.get_tax_amount_if_for_valuation_or_deduction(tax.tax_amount, tax)
actual_taxes_dict.setdefault(tax.idx, tax_amount)
elif tax.row_id in actual_taxes_dict:
actual_tax_amount = flt(actual_taxes_dict.get(tax.row_id, 0)) * flt(tax.rate) / 100
actual_taxes_dict.setdefault(tax.idx, actual_tax_amount)
total_actual_tax = 0
actual_taxes_dict = {}
return flt(
self.doc.grand_total - sum(actual_taxes_dict.values()), self.doc.precision("grand_total")
def update_actual_tax_dict(tax, tax_amount):
nonlocal total_actual_tax
if tax.get("add_deduct_tax") == "Deduct":
tax_amount *= -1
if tax.get("category") != "Valuation":
total_actual_tax += tax_amount
actual_taxes_dict[int(tax.idx)] = {
"tax_amount": tax_amount,
"cumulative_tax_amount": total_actual_tax,
}
for tax in self.doc.get("taxes"):
if tax.charge_type in ["Actual", "On Item Quantity"]:
update_actual_tax_dict(tax, tax.tax_amount)
continue
if not tax.row_id:
continue
base_row = actual_taxes_dict.get(int(tax.row_id))
if not base_row:
continue
base_tax_amount = (
base_row["tax_amount"]
if tax.charge_type == "On Previous Row Amount"
else base_row["cumulative_tax_amount"]
)
update_actual_tax_dict(tax, base_tax_amount * tax.rate / 100)
return self.doc.grand_total - total_actual_tax
def calculate_total_advance(self):
if not self.doc.docstatus.is_cancelled():
@@ -780,9 +795,12 @@ class calculate_taxes_and_totals:
if (
self.doc.is_return
and self.doc.return_against
and not self.doc.update_outstanding_for_self
and not self.doc.get("is_pos")
or self.is_internal_invoice()
):
# Do not calculate the outstanding amount for a return invoice if 'update_outstanding_for_self' is not enabled.
self.doc.outstanding_amount = 0
return
self.doc.round_floats_in(self.doc, ["grand_total", "total_advance", "write_off_amount"])

View File

@@ -29,4 +29,10 @@ frappe.ui.form.on("Contract", {
});
}
},
party_name: function (frm) {
let field = frm.doc.party_type.toLowerCase() + "_name";
frappe.db.get_value(frm.doc.party_type, frm.doc.party_name, field, (r) => {
frm.set_value("party_full_name", r[field]);
});
},
});

View File

@@ -14,6 +14,7 @@
"party_user",
"status",
"fulfilment_status",
"party_full_name",
"sb_terms",
"start_date",
"cb_date",
@@ -244,11 +245,18 @@
"fieldname": "authorised_by_section",
"fieldtype": "Section Break",
"label": "Authorised By"
},
{
"fieldname": "party_full_name",
"fieldtype": "Data",
"label": "Party Full Name",
"read_only": 1
}
],
"grid_page_length": 50,
"is_submittable": 1,
"links": [],
"modified": "2020-12-07 11:15:58.385521",
"modified": "2025-05-23 13:54:03.346537",
"modified_by": "Administrator",
"module": "CRM",
"name": "Contract",
@@ -315,9 +323,10 @@
"write": 1
}
],
"row_format": "Dynamic",
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -23,10 +23,17 @@ class Contract(Document):
self.name = _(name)
def validate(self):
self.set_missing_values()
self.validate_dates()
self.update_contract_status()
self.update_fulfilment_status()
def set_missing_values(self):
if not self.party_full_name:
field = self.party_type.lower() + "_name"
if res := frappe.db.get_value(self.party_type, self.party_name, field):
self.party_full_name = res
def before_submit(self):
self.signed_by_company = frappe.session.user

View File

@@ -60,7 +60,7 @@ def import_genericode():
"doctype": "File",
"attached_to_doctype": "Code List",
"attached_to_name": code_list.name,
"folder": "Home/Attachments",
"folder": frappe.db.get_value("File", {"is_attachments_folder": 1}),
"file_name": frappe.local.uploaded_filename,
"file_url": frappe.local.uploaded_file_url,
"is_private": 1,

View File

@@ -6,6 +6,7 @@
"engine": "InnoDB",
"field_order": [
"code_list",
"canonical_uri",
"title",
"common_code",
"description",
@@ -71,10 +72,17 @@
"in_list_view": 1,
"label": "Description",
"max_height": "60px"
},
{
"fetch_from": "code_list.canonical_uri",
"fieldname": "canonical_uri",
"fieldtype": "Data",
"label": "Canonical URI"
}
],
"grid_page_length": 50,
"links": [],
"modified": "2024-11-06 07:46:17.175687",
"modified": "2025-10-04 17:22:28.176155",
"modified_by": "Administrator",
"module": "EDI",
"name": "Common Code",
@@ -94,10 +102,11 @@
"write": 1
}
],
"row_format": "Dynamic",
"search_fields": "common_code,description",
"show_title_field_in_link": 1,
"sort_field": "creation",
"sort_order": "DESC",
"states": [],
"title_field": "title"
}
}

View File

@@ -22,6 +22,7 @@ class CommonCode(Document):
additional_data: DF.Code | None
applies_to: DF.Table[DynamicLink]
canonical_uri: DF.Data | None
code_list: DF.Link
common_code: DF.Data
description: DF.SmallText | None

View File

@@ -7,7 +7,7 @@ from collections import deque
from operator import itemgetter
import frappe
from frappe import _
from frappe import _, bold
from frappe.core.doctype.version.version import get_diff
from frappe.model.mapper import get_mapped_doc
from frappe.utils import cint, cstr, flt, today
@@ -554,9 +554,16 @@ class BOM(WebsiteGenerator):
def check_recursion(self, bom_list=None):
"""Check whether recursion occurs in any bom"""
def _throw_error(bom_name):
def _throw_error(bom_name, production_item=None):
msg = _("BOM recursion: {1} cannot be parent or child of {0}").format(self.name, bom_name)
if production_item and bom_name != self.name:
msg += "<br><br>"
msg += _(
"Note: If you want to use the finished good {0} as a raw material, then enable the 'Do Not Explode' checkbox in the Items table against the same raw material."
).format(bold(production_item))
frappe.throw(
_("BOM recursion: {1} cannot be parent or child of {0}").format(self.name, bom_name),
msg,
exc=BOMRecursionError,
)
@@ -573,7 +580,7 @@ class BOM(WebsiteGenerator):
if self.item == item.item_code and item.bom_no:
# Same item but with different BOM should not be allowed.
# Same item can appear recursively once as long as it doesn't have BOM.
_throw_error(item.bom_no)
_throw_error(item.bom_no, self.item)
if self.name in {d.bom_no for d in self.items}:
_throw_error(self.name)

View File

@@ -37,6 +37,14 @@ frappe.ui.form.on("Production Plan", {
};
});
frm.set_query("sub_assembly_warehouse", function (doc) {
return {
filters: {
company: doc.company,
},
};
});
frm.set_query("material_request", "material_requests", function () {
return {
filters: {

View File

@@ -1048,6 +1048,7 @@ def get_exploded_items(item_details, company, bom_no, include_non_stock_items, p
item.purchase_uom,
item_uom.conversion_factor,
item.safety_stock,
bom.item.as_("main_bom_item"),
)
.where(
(bei.docstatus < 2)
@@ -1115,6 +1116,7 @@ def get_subitems(
item_default.default_warehouse,
item.purchase_uom,
item_uom.conversion_factor,
bom.item.as_("main_bom_item"),
)
.where(
(bom.name == bom_no)
@@ -1228,6 +1230,7 @@ def get_material_request_items(
"sales_order": sales_order,
"description": row.get("description"),
"uom": row.get("purchase_uom") or row.get("stock_uom"),
"main_bom_item": row.get("main_bom_item"),
}
@@ -1757,6 +1760,7 @@ def get_raw_materials_of_sub_assembly_items(
item.purchase_uom,
item_uom.conversion_factor,
item.safety_stock,
bom.item.as_("main_bom_item"),
)
.where(
(bei.docstatus == 1)

View File

@@ -1322,20 +1322,20 @@ def stop_unstop(work_order, status):
@frappe.whitelist()
def query_sales_order(production_item):
out = frappe.db.sql_list(
"""
select distinct so.name from `tabSales Order` so, `tabSales Order Item` so_item
where so_item.parent=so.name and so_item.item_code=%s and so.docstatus=1
union
select distinct so.name from `tabSales Order` so, `tabPacked Item` pi_item
where pi_item.parent=so.name and pi_item.item_code=%s and so.docstatus=1
""",
(production_item, production_item),
def query_sales_order(production_item: str) -> list[str]:
return frappe.get_list(
"Sales Order",
filters=[
["Sales Order", "docstatus", "=", 1],
],
or_filters=[
["Sales Order Item", "item_code", "=", production_item],
["Packed Item", "item_code", "=", production_item],
],
pluck="name",
distinct=True,
)
return out
@frappe.whitelist()
def make_job_card(work_order, operations):

View File

@@ -23,6 +23,7 @@ def get_columns():
"""return columns"""
columns = [
_("Item") + ":Link/Item:150",
_("Item Name") + "::240",
_("Description") + "::300",
_("BOM Qty") + ":Float:160",
_("BOM UoM") + "::160",
@@ -73,11 +74,12 @@ def get_bom_stock(filters):
.on((BOM_ITEM.item_code == BIN.item_code) & (CONDITIONS))
.select(
BOM_ITEM.item_code,
BOM_ITEM.item_name,
BOM_ITEM.description,
BOM_ITEM.stock_qty,
BOM_ITEM.stock_uom,
BOM_ITEM.stock_qty * qty_to_produce / BOM.quantity,
Sum(BIN.actual_qty).as_("actual_qty"),
BIN.actual_qty.as_("actual_qty"),
Sum(Floor(BIN.actual_qty / (BOM_ITEM.stock_qty * qty_to_produce / BOM.quantity))),
)
.where((BOM_ITEM.parent == filters.get("bom")) & (BOM_ITEM.parenttype == "BOM"))

View File

@@ -94,6 +94,7 @@ def get_expected_data(bom, warehouse, qty_to_produce, show_exploded_view=False):
expected_data.append(
[
item.item_code,
item.item_name,
item.description,
item.stock_qty,
item.stock_uom,

View File

@@ -372,3 +372,8 @@ erpnext.patches.v14_0.disable_add_row_in_gross_profit
execute:frappe.db.set_single_value("Accounts Settings", "exchange_gain_loss_posting_date", "Payment")
erpnext.patches.v14_0.update_posting_datetime
erpnext.stock.doctype.stock_ledger_entry.patches.ensure_sle_indexes
erpnext.patches.v14_0.rename_group_by_to_categorize_by
execute:frappe.db.set_single_value("Accounts Settings", "receivable_payable_fetch_method", "Buffered Cursor")
erpnext.patches.v14_0.set_update_price_list_based_on
erpnext.patches.v14_0.rename_group_by_to_categorize_by_in_custom_reports
erpnext.patches.v14_0.update_full_name_in_contract

View File

@@ -0,0 +1,20 @@
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
rename_field("Process Statement Of Accounts", "group_by", "categorize_by")
frappe.db.sql(
"""
UPDATE
`tabProcess Statement Of Accounts`
SET
categorize_by = CASE
WHEN categorize_by = 'Group by Voucher (Consolidated)' THEN 'Categorize by Voucher (Consolidated)'
WHEN categorize_by = 'Group by Voucher' THEN 'Categorize by Voucher'
END
WHERE
categorize_by IN ('Group by Voucher (Consolidated)', 'Group by Voucher')
"""
)

View File

@@ -0,0 +1,24 @@
import json
import frappe
def execute():
custom_reports = frappe.get_all(
"Report",
filters={
"report_type": "Custom Report",
"reference_report": ["in", ["General Ledger", "Supplier Quotation Comparison"]],
},
fields=["name", "json"],
)
for report in custom_reports:
report_json = json.loads(report.json)
if "filters" in report_json and "group_by" in report_json["filters"]:
report_json["filters"]["categorize_by"] = (
report_json["filters"].pop("group_by").replace("Group", "Categorize")
)
frappe.db.set_value("Report", report.name, "json", json.dumps(report_json))

View File

@@ -0,0 +1,14 @@
import frappe
from frappe.utils import cint
def execute():
frappe.db.set_single_value(
"Stock Settings",
"update_price_list_based_on",
(
"Price List Rate"
if cint(frappe.db.get_single_value("Selling Settings", "editable_price_list_rate"))
else "Rate"
),
)

View File

@@ -0,0 +1,15 @@
import frappe
from frappe import qb
def execute():
con = qb.DocType("Contract")
for c in (
qb.from_(con)
.select(con.name, con.party_type, con.party_name)
.where(con.party_full_name.isnull())
.run(as_dict=True)
):
field = c.party_type.lower() + "_name"
if res := frappe.db.get_value(c.party_type, c.party_name, field):
frappe.db.set_value("Contract", c.name, "party_full_name", res)

View File

@@ -292,12 +292,16 @@ def get_projectwise_timesheet_data(project=None, parent=None, from_time=None, to
@frappe.whitelist()
def get_timesheet_detail_rate(timelog, currency):
timelog_detail = frappe.db.sql(
f"""SELECT tsd.billing_amount as billing_amount,
ts.currency as currency FROM `tabTimesheet Detail` tsd
INNER JOIN `tabTimesheet` ts ON ts.name=tsd.parent
WHERE tsd.name = '{timelog}'""",
as_dict=1,
ts = frappe.qb.DocType("Timesheet")
ts_detail = frappe.qb.DocType("Timesheet Detail")
timelog_detail = (
frappe.qb.from_(ts_detail)
.inner_join(ts)
.on(ts.name == ts_detail.parent)
.select(ts_detail.billing_amount.as_("billing_amount"), ts.currency.as_("currency"))
.where(ts_detail.name == timelog)
.run(as_dict=1)
)[0]
if timelog_detail.currency:

View File

@@ -87,7 +87,7 @@ erpnext.stock.StockController = class StockController extends frappe.ui.form.Con
from_date: me.frm.doc.posting_date,
to_date: moment(me.frm.doc.modified).format('YYYY-MM-DD'),
company: me.frm.doc.company,
group_by: "Group by Voucher (Consolidated)",
categorize_by: "Categorize by Voucher (Consolidated)",
show_cancelled_entries: me.frm.doc.docstatus === 2,
ignore_prepared_report: true
};

View File

@@ -26,7 +26,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
item.discount_amount = flt(item.rate_with_margin) * flt(item.discount_percentage) / 100;
}
if (item.discount_amount) {
if (item.discount_amount > 0) {
item_rate = flt((item.rate_with_margin) - (item.discount_amount), precision('rate', item));
item.discount_percentage = 100 * flt(item.discount_amount) / flt(item.rate_with_margin);
}
@@ -76,9 +76,10 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
// Update paid amount on return/debit note creation
if (
this.frm.doc.doctype === "Purchase Invoice"
&& this.frm.doc.is_return
&& (this.frm.doc.grand_total > this.frm.doc.paid_amount)
this.frm.doc.doctype === "Purchase Invoice" &&
this.frm.doc.is_return &&
this.frm.doc.grand_total < 0 &&
this.frm.doc.grand_total > this.frm.doc.paid_amount
) {
this.frm.doc.paid_amount = flt(this.frm.doc.grand_total, precision("grand_total"));
}
@@ -336,7 +337,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
calculate_taxes() {
var me = this;
this.frm.doc.rounding_adjustment = 0;
this.grand_total_diff = 0;
var actual_tax_dict = {};
// maintain actual tax rate based on idx
@@ -407,7 +408,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
// adjust Discount Amount loss in last tax iteration
if ((i == me.frm.doc["taxes"].length - 1) && me.discount_amount_applied
&& me.frm.doc.apply_discount_on == "Grand Total" && me.frm.doc.discount_amount) {
me.frm.doc.rounding_adjustment = flt(me.frm.doc.grand_total -
me.grand_total_diff = flt(me.frm.doc.grand_total -
flt(me.frm.doc.discount_amount) - tax.total, precision("rounding_adjustment"));
}
}
@@ -519,7 +520,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
adjust_grand_total_for_inclusive_tax() {
var me = this;
// if fully inclusive taxes and diff
// if any inclusive taxes and diff
if (this.frm.doc["taxes"] && this.frm.doc["taxes"].length) {
var any_inclusive_tax = false;
$.each(this.frm.doc.taxes || [], function(i, d) {
@@ -530,7 +531,9 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
var non_inclusive_tax_amount = frappe.utils.sum($.map(this.frm.doc.taxes || [],
function(d) {
if(!d.included_in_print_rate) {
return flt(d.tax_amount_after_discount_amount);
let tax_amount = d.category === "Valuation" ? 0 : d.tax_amount_after_discount_amount;
if (d.add_deduct_tax === "Deduct") tax_amount *= -1;
return tax_amount;
}
}
));
@@ -544,9 +547,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
diff = flt(diff, precision("rounding_adjustment"));
if ( diff && Math.abs(diff) <= (5.0 / Math.pow(10, precision("tax_amount", last_tax))) ) {
me.frm.doc.grand_total_diff = diff;
} else {
me.frm.doc.grand_total_diff = 0;
me.grand_total_diff = diff;
}
}
}
@@ -557,7 +558,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
var me = this;
var tax_count = this.frm.doc["taxes"] ? this.frm.doc["taxes"].length : 0;
this.frm.doc.grand_total = flt(tax_count
? this.frm.doc["taxes"][tax_count - 1].total + flt(this.frm.doc.grand_total_diff)
? this.frm.doc["taxes"][tax_count - 1].total + this.grand_total_diff
: this.frm.doc.net_total);
if(["Quotation", "Sales Order", "Delivery Note", "Sales Invoice", "POS Invoice"].includes(this.frm.doc.doctype)) {
@@ -589,9 +590,9 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
}
this.frm.doc.total_taxes_and_charges = flt(this.frm.doc.grand_total - this.frm.doc.net_total
- flt(this.frm.doc.rounding_adjustment), precision("total_taxes_and_charges"));
- this.grand_total_diff, precision("total_taxes_and_charges"));
this.set_in_company_currency(this.frm.doc, ["total_taxes_and_charges", "rounding_adjustment"]);
this.set_in_company_currency(this.frm.doc, ["total_taxes_and_charges"]);
// Round grand total as per precision
frappe.model.round_floats_in(this.frm.doc, ["grand_total", "base_grand_total"]);
@@ -611,6 +612,7 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
if (cint(disable_rounded_total)) {
this.frm.doc.rounded_total = 0;
this.frm.doc.base_rounded_total = 0;
this.frm.doc.rounding_adjustment = 0;
return;
}
@@ -679,22 +681,26 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
return;
}
var total_for_discount_amount = this.get_total_for_discount_amount();
var net_total = 0;
const total_for_discount_amount = this.get_total_for_discount_amount();
let net_total = 0;
let expected_net_total = 0;
// calculate item amount after Discount Amount
if (total_for_discount_amount) {
$.each(this.frm._items || [], function(i, item) {
distributed_amount = flt(me.frm.doc.discount_amount) * item.net_amount / total_for_discount_amount;
item.net_amount = flt(item.net_amount - distributed_amount, precision("net_amount", item));
const adjusted_net_amount = item.net_amount - distributed_amount;
expected_net_total += adjusted_net_amount
item.net_amount = flt(adjusted_net_amount, precision("net_amount", item));
net_total += item.net_amount;
// discount amount rounding loss adjustment if no taxes
if ((!(me.frm.doc.taxes || []).length || total_for_discount_amount==me.frm.doc.net_total || (me.frm.doc.apply_discount_on == "Net Total"))
&& i == (me.frm._items || []).length - 1) {
var discount_amount_loss = flt(me.frm.doc.net_total - net_total
- me.frm.doc.discount_amount, precision("net_total"));
item.net_amount = flt(item.net_amount + discount_amount_loss,
precision("net_amount", item));
// discount amount rounding adjustment
// assignment to rounding_difference is intentional
const rounding_difference = flt(expected_net_total - net_total, precision("net_total"));
if (rounding_difference) {
item.net_amount = flt(item.net_amount + rounding_difference, precision("net_amount", item));
net_total += rounding_difference;
}
item.net_rate = item.qty ? flt(item.net_amount / item.qty, precision("net_rate", item)) : 0;
me.set_in_company_currency(item, ["net_rate", "net_amount"]);
@@ -707,29 +713,38 @@ erpnext.taxes_and_totals = class TaxesAndTotals extends erpnext.payments {
}
get_total_for_discount_amount() {
if(this.frm.doc.apply_discount_on == "Net Total") {
if(this.frm.doc.apply_discount_on == "Net Total")
return this.frm.doc.net_total;
} else {
var total_actual_tax = 0.0;
var actual_taxes_dict = {};
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
if (["Actual", "On Item Quantity"].includes(tax.charge_type)) {
var tax_amount = (tax.category == "Valuation") ? 0.0 : tax.tax_amount;
tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
actual_taxes_dict[tax.idx] = tax_amount;
} else if (actual_taxes_dict[tax.row_id] !== null) {
var actual_tax_amount = flt(actual_taxes_dict[tax.row_id]) * flt(tax.rate) / 100;
actual_taxes_dict[tax.idx] = actual_tax_amount;
}
});
let total_actual_tax = 0.0;
let actual_taxes_dict = {};
$.each(actual_taxes_dict, function(key, value) {
if (value) total_actual_tax += value;
});
function update_actual_taxes_dict(tax, tax_amount) {
if (tax.add_deduct_tax == "Deduct") tax_amount *= -1;
if (tax.category != "Valuation") total_actual_tax += tax_amount;
return flt(this.frm.doc.grand_total - total_actual_tax, precision("grand_total"));
actual_taxes_dict[tax.idx] = {
tax_amount: tax_amount,
cumulative_total: total_actual_tax
};
}
$.each(this.frm.doc["taxes"] || [], function(i, tax) {
if (["Actual", "On Item Quantity"].includes(tax.charge_type)) {
update_actual_taxes_dict(tax, tax.tax_amount);
return;
}
const base_row = actual_taxes_dict[tax.row_id];
if (!base_row) return;
// if charge type is 'On Previous Row Amount', calculate tax on previous row amount
// else (On Previous Row Total) calculate tax on cumulative total
const base_tax_amount = tax.charge_type == "On Previous Row Amount" ? base_row["tax_amount"]: base_row["cumulative_total"];
update_actual_taxes_dict(tax, base_tax_amount * tax.rate / 100);
});
return this.frm.doc.grand_total - total_actual_tax;
}
calculate_total_advance(update_paid_amount) {

View File

@@ -297,7 +297,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
let d = locals[cdt][cdn];
return {
filters: {
docstatus: 1,
docstatus: ["<", 2],
inspection_type: inspection_type,
reference_name: doc.name,
item_code: d.item_code
@@ -878,6 +878,15 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
}
}
discount_date(doc, cdt, cdn) {
// Remove fields as discount_date is auto-managed by payment terms
const row = locals[cdt][cdn];
["discount_validity", "discount_validity_based_on"].forEach((field) => {
row[field] = "";
});
this.frm.refresh_field("payment_schedule");
}
due_date() {
// due_date is to be changed, payment terms template and/or payment schedule must
// be removed as due_date is automatically changed based on payment terms
@@ -2203,6 +2212,7 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
'item_code': item.item_code,
'valid_from': ["<=", doc.transaction_date || doc.bill_date || doc.posting_date],
'item_group': item.item_group,
'disabled': 0,
}
if (doc.tax_category)
@@ -2244,7 +2254,18 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
payment_term(doc, cdt, cdn) {
const me = this;
var row = locals[cdt][cdn];
if(row.payment_term) {
// empty date condition fields
[
"due_date_based_on",
"credit_days",
"credit_months",
"discount_validity",
"discount_validity_based_on",
].forEach(function (field) {
row[field] = "";
});
if (row.payment_term) {
frappe.call({
method: "erpnext.controllers.accounts_controller.get_payment_term_details",
args: {
@@ -2254,16 +2275,19 @@ erpnext.TransactionController = class TransactionController extends erpnext.taxe
grand_total: this.frm.doc.rounded_total || this.frm.doc.grand_total,
base_grand_total: this.frm.doc.base_rounded_total || this.frm.doc.base_grand_total
},
callback: function(r) {
if(r.message && !r.exc) {
for (var d in r.message) {
frappe.model.set_value(cdt, cdn, d, r.message[d]);
const company_currency = me.get_company_currency();
me.update_payment_schedule_grid_labels(company_currency);
callback: function (r) {
if (r.message && !r.exc) {
const company_currency = me.get_company_currency();
for (let d in r.message) {
row[d] = r.message[d];
}
me.update_payment_schedule_grid_labels(company_currency);
me.frm.refresh_field("payment_schedule");
}
}
})
},
});
} else {
me.frm.refresh_field("payment_schedule");
}
}

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