Compare commits

...

897 Commits

Author SHA1 Message Date
rohitwaghchaure
e19066afcf fix: BOM name issue (#44575)
fix: bom name issue
(cherry picked from commit b7a3c6b6ca)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/bom.py
2024-12-06 11:26:24 +00:00
mergify[bot]
ebc8bede7f fix(Bank Transaction): error in party matching should not block submitting (backport #44416) (#44573)
fix(Bank Transaction): error in party matching should not block submitting (#44416)

(cherry picked from commit 72256565bb)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-12-06 11:57:52 +01:00
ruthra kumar
19b64496b1 Merge pull request #44571 from frappe/mergify/bp/version-14-hotfix/pr-44538
fix: add labels for translation in purchase_order_analysis.py (backport #44538)
2024-12-06 12:21:04 +05:30
mahsem
f9974f9eb0 fix: add labels for translation in purchase_order_analysis.py
(cherry picked from commit 342a398bec)
2024-12-06 06:49:54 +00:00
ruthra kumar
0eccb01b7b Merge pull request #44565 from frappe/mergify/bp/version-14-hotfix/pr-44558
fix: add string for translation in delayed_tasks_summary.py (backport #44558)
2024-12-06 12:18:52 +05:30
mahsem
ce04f6d7c9 fix: add string for translation in delayed_tasks_summary.py
(cherry picked from commit 84b54f549a)
2024-12-06 12:17:50 +05:30
ruthra kumar
424d585962 Merge pull request #44569 from frappe/mergify/bp/version-14-hotfix/pr-44539
fix: add labels for translation in production_analytics.py (backport #44539)
2024-12-06 12:16:58 +05:30
mahsem
1a7f195d8f fix: add labels for translation in production_analytics.py
(cherry picked from commit 9b09116576)
2024-12-06 06:46:26 +00:00
ruthra kumar
5b0222615d Merge pull request #44567 from frappe/mergify/bp/version-14-hotfix/pr-44541
fix: add labels for translation in quality_inspection_summary.py (backport #44541)
2024-12-06 12:15:39 +05:30
mahsem
9986c26a0c fix: add labels for translation in quality_inspection_summary.py
(cherry picked from commit 6ff4704345)
2024-12-06 06:44:58 +00:00
ruthra kumar
e0c1e3474e Merge pull request #44563 from frappe/mergify/bp/version-14-hotfix/pr-44559
fix: add strings for translation payment_terms_status_for_sales_order.py (backport #44559)
2024-12-06 12:12:57 +05:30
mahsem
17dad01ab7 fix: add strings for translation payment_terms_status_for_sales_order.py
(cherry picked from commit 7d244051c8)
2024-12-06 06:38:29 +00:00
ruthra kumar
9515625135 Merge pull request #44561 from frappe/mergify/bp/version-14-hotfix/pr-44560
fix: add labels for translation in sales_order_analysis.py (backport #44560)
2024-12-06 12:07:05 +05:30
mahsem
bad1b2a164 fix: add labels for translation in sales_order_analysis.py
(cherry picked from commit 8a554a5538)
2024-12-06 06:09:28 +00:00
mergify[bot]
e2aedc85b4 fix: variant qty while making work order from BOM (backport #44548) (#44550)
fix: variant qty while making work order from BOM (#44548)

(cherry picked from commit 1571dff3ef)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-12-05 16:01:49 +05:30
Khushi Rawat
68fe3b4165 Merge pull request #44543 from frappe/mergify/bp/version-14-hotfix/pr-44537
fix: add title for translation in  asset.js (backport #44537)
2024-12-05 15:42:11 +05:30
mahsem
aed90f73d7 fix: add title for translation in asset.js
(cherry picked from commit 61439132a4)
2024-12-05 09:47:58 +00:00
mergify[bot]
ecc756bd52 fix: incorrect stock UOM for BOM raw materials (backport #44528) (#44530)
fix: incorrect stock UOM for BOM raw materials (#44528)

fix: incorrect stock uom for BOM raw materials
(cherry picked from commit 5413cf9f1f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-12-05 12:51:39 +05:30
ruthra kumar
0891399916 Merge pull request #44527 from frappe/mergify/bp/version-14-hotfix/pr-44503
fix: add strings for translation in pos_item_cart.js (backport #44503)
2024-12-05 10:24:51 +05:30
ruthra kumar
1436fda041 Merge pull request #44519 from frappe/mergify/bp/version-14-hotfix/pr-44500
fix: add labels for translation in sales_order.js (backport #44500)
2024-12-05 10:19:02 +05:30
ruthra kumar
639a71ffd0 chore: linter fix
(cherry picked from commit 31efaf6dbf)
2024-12-05 04:49:01 +00:00
mahsem
1f0f31a773 fix: add strings for translation in pos_item_cart.js
(cherry picked from commit 4b72b60f1a)
2024-12-05 04:49:00 +00:00
ruthra kumar
3bb4699754 Merge pull request #44525 from frappe/mergify/bp/version-14-hotfix/pr-44512
fix: add label strings for translation in pos_controller.js (backport #44512)
2024-12-05 10:17:40 +05:30
mahsem
3620ddab34 fix: add labels for translation in sales_order.js
(cherry picked from commit d544328ffe)
2024-12-05 10:16:48 +05:30
mahsem
8233e22d8b fix: add label strings for translation in pos_controller.js
(cherry picked from commit bd77a5557d)
2024-12-05 04:42:44 +00:00
ruthra kumar
1f293edc9e Merge pull request #44523 from frappe/mergify/bp/version-14-hotfix/pr-44501
fix: strings for translation in pos_past_order_summary.js (backport #44501)
2024-12-05 10:12:41 +05:30
ruthra kumar
13cd12e1e2 Merge pull request #44521 from frappe/mergify/bp/version-14-hotfix/pr-42081
Use better description in pos_payment.js (backport #42081)
2024-12-05 10:12:11 +05:30
mahsem
dfbb2279b6 fix: strings for translation in pos_past_order_summary.js
(cherry picked from commit 23c846d4b9)
2024-12-05 04:31:29 +00:00
mahsem
e1d288321f refactor: translatable label on pos payments (#42081)
* Use better description in pos_payment.js

Use Change Amount instead of Change and To Be Paid in pos_payment.js and be consistent with other strings

* change_amount_pos_payment.js

(cherry picked from commit 138ffc4e93)
2024-12-05 04:30:46 +00:00
mergify[bot]
c502b562db fix: inv dimensions fields not creating for standard doctype (backport #44504) (#44514)
fix: inv dimensions fields not creating for standard doctype (#44504)

(cherry picked from commit 353610ce61)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-12-05 09:45:29 +05:30
mergify[bot]
15e3663633 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>
2024-12-04 19:03:09 +05:30
ruthra kumar
2812eae589 Merge pull request #44484 from frappe/mergify/bp/version-14-hotfix/pr-44467
fix: Multiple Fixes in Gross Profit Report (backport #44467)
2024-12-03 19:15:34 +05:30
ruthra kumar
a94e3cd433 chore: fix typo
(cherry picked from commit fc0122ce76)
2024-12-03 12:00:36 +00:00
ljain112
91f6393104 fix: correct buying amount for product bundel
(cherry picked from commit 4e6a5893e7)
2024-12-03 12:00:36 +00:00
ljain112
7d724d7647 fix: remove queries
(cherry picked from commit a86b223aed)
2024-12-03 12:00:35 +00:00
ruthra kumar
e4b811be23 Merge pull request #44469 from frappe/mergify/bp/version-14-hotfix/pr-44461
fix: incorrect Gross Margin on project (backport #44461)
2024-12-03 15:32:04 +05:30
rohitwaghchaure
ccd7992e99 chore: fix conflicts 2024-12-03 15:08:38 +05:30
rohitwaghchaure
86ff3e0c10 chore: fix conflicts 2024-12-03 15:06:16 +05:30
ruthra kumar
96fe3f4a2c Merge pull request #44479 from frappe/mergify/bp/version-14-hotfix/pr-44415
fix: adjusted incoming rate for zero rated item in purchase receipt (backport #44415)
2024-12-03 14:48:24 +05:30
ljain112
d7583e3993 fix: adjusted incoming rate for zero rated item in purchase receipt
(cherry picked from commit 3182c6981c)
2024-12-03 08:56:06 +00:00
rohitwaghchaure
5533592b2b fix: incorrect Gross Margin on project (#44461)
(cherry picked from commit 7de9c14a2c)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.py
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2024-12-02 10:10:31 +00:00
ruthra kumar
ba19e06e64 Merge pull request #44464 from frappe/mergify/bp/version-14-hotfix/pr-44412
fix: handle multi currency in common party journal entry (backport #44412)
2024-12-02 14:03:21 +05:30
ruthra kumar
1988c23539 chore: resolve conflict 2024-12-02 13:42:27 +05:30
ruthra kumar
70cac3186b Merge pull request #44462 from frappe/mergify/bp/version-14-hotfix/pr-44437
fix: Added translation for `Account` column (backport #44437)
2024-12-02 13:39:59 +05:30
ljain112
bed6dabecb fix: handle multi currency in common party journal entry
(cherry picked from commit e371f68d66)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2024-12-02 07:10:05 +00:00
Abdeali Chharchhoda
c4103d26be fix: Translate Party Account column label
(cherry picked from commit a4f8315602)
2024-12-02 06:53:37 +00:00
Abdeali Chharchhoda
2061c7ca46 fix: Added translation for Account column
(cherry picked from commit de6cbd382f)
2024-12-02 06:53:37 +00:00
Sagar Vora
84bd0c8c50 Merge pull request #44446 from frappe/mergify/bp/version-14-hotfix/pr-44443
perf: reduce queries during transaction save (backport #44443)
2024-11-30 00:47:53 +05:30
Sagar Vora
f884cf8a5e perf: reduce queries during transaction save
(cherry picked from commit b6b8a06fda)
2024-11-29 19:17:26 +00:00
Sagar Vora
54782d41be Merge pull request #44444 from frappe/mergify/bp/version-14-hotfix/pr-44439
fix: added fieldname to avoid fieldname to translate (backport #44439)
2024-11-30 00:29:47 +05:30
Abdeali Chharchhoda
d7caa8d51b fix: added fieldname to avoid fieldname to translate
(cherry picked from commit b80022133c)
2024-11-29 18:56:31 +00:00
Sagar Vora
9e8150554f Merge pull request #44441 from frappe/mergify/bp/version-14-hotfix/pr-44440
perf: cache product bundle items at document level (backport #44440)
2024-11-29 23:04:01 +05:30
Sagar Vora
df0dac5610 perf: cache product bundle items at document level (#44440)
(cherry picked from commit 6de7320ef4)
2024-11-29 17:22:51 +00:00
mergify[bot]
cbce4e72d9 fix: source warehouse not set in required items of WO (backport #44426) (#44433)
* fix: source warehouse not set in required items of WO (#44426)

fix: source warehouse not set in required items of WO on data import
(cherry picked from commit 4050ea07eb)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-11-29 18:13:25 +05:30
ruthra kumar
2c2a204a06 Merge pull request #44390 from frappe/mergify/bp/version-14-hotfix/pr-44386
fix: Add translation for showing mandatory fields in error msg (backport #44386)
2024-11-29 15:38:52 +05:30
ruthra kumar
da5b57e4af Merge pull request #44424 from frappe/mergify/bp/version-14-hotfix/pr-44302
fix: Minor Updates in `Payment Request` and `Payment Entry`  (backport #44302)
2024-11-29 15:38:11 +05:30
Abdeali Chharchhoda
de5b253215 fix: Add translation for showing mandatory fields in error msg
(cherry picked from commit f42ec6a124)
2024-11-29 14:57:21 +05:30
ruthra kumar
a8ef90b40c chore: resolve conflict 2024-11-29 14:51:46 +05:30
Abdeali Chharchhoda
7e847f27dd fix: Add filter for outstanding_amount to fetch open PRs
(cherry picked from commit 214dfab269)
2024-11-29 09:11:07 +00:00
Abdeali Chharchhoda
eb809847f1 refactor: Move PR link filters to client side
(cherry picked from commit 2db2c8bce1)
2024-11-29 09:11:06 +00:00
Abdeali Chharchhoda
9baaaca924 revert: remove default Payment Request indicator color
(cherry picked from commit 37ceb09955)

# Conflicts:
#	erpnext/accounts/doctype/payment_request/payment_request_list.js
2024-11-29 09:11:06 +00:00
Abdeali Chharchhoda
c911a70a84 fix: Dashboard for Payment Request
(cherry picked from commit 91955e27c3)
2024-11-29 09:11:06 +00:00
Abdeali Chharchhoda
e2728db5c2 refactor: Used object to get payment request status indicator
(cherry picked from commit e1c4d6e1e6)

# Conflicts:
#	erpnext/accounts/doctype/payment_request/payment_request_list.js
2024-11-29 09:11:06 +00:00
Smit Vora
f6f1052a80 Merge pull request #44409 from frappe/mergify/bp/version-14-hotfix/pr-44195
fix: Data Should be Computed in Backend to Maintain Consistent Behaviour (backport #44195)
2024-11-28 16:27:16 +05:30
Ninad Parikh
8529eb4573 fix: Data Should be Computed in Backend to Maintain Consistent Behaviour (#44195)
(cherry picked from commit 69bd90b038)
2024-11-28 10:31:28 +00:00
ruthra kumar
a73fedbaca Merge pull request #44406 from frappe/mergify/bp/version-14-hotfix/pr-44405
fix: typeerror on transaction.js (backport #44405)
2024-11-28 15:13:27 +05:30
ruthra kumar
147eb047aa fix: typeerror on transaction.js
(cherry picked from commit 46ce8780f2)
2024-11-28 15:02:35 +05:30
mergify[bot]
9ae04dfed3 fix: show "Send SMS" only when enabled (backport #43941) (#43969)
fix: show "Send SMS" only when enabled (#43941)

(cherry picked from commit 65088cbb1b)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-11-27 23:52:12 +01:00
mergify[bot]
78ab44ce1a feat: add Company Contact Person in selling transactions (backport #44362) (#44397)
* feat: add Company Contact Person in selling transactions (#44362)

(cherry picked from commit f6776c7d6b)

* chore: resolve conflicts

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-11-27 17:09:09 +01:00
ruthra kumar
627a50e7bc Merge pull request #44384 from frappe/mergify/bp/version-14-hotfix/pr-44323
fix: update gross profit for returned invoices (backport #44323)
2024-11-27 17:21:13 +05:30
ljain112
7eafe7f853 fix: test case
(cherry picked from commit af5a3e5a48)
2024-11-27 11:20:16 +00:00
ljain112
6e563438bd fix: gp for return invoice
(cherry picked from commit 00403515a8)
2024-11-27 11:20:16 +00:00
ljain112
0eb5e001e1 fix: update gross profit for returned invoices
(cherry picked from commit 8a42601e99)
2024-11-27 11:20:15 +00:00
ruthra kumar
0dfb9ddb85 Merge pull request #44380 from frappe/mergify/bp/version-14-hotfix/pr-44377
fix:  correct placeholder index in message (backport #44377)
2024-11-27 15:38:39 +05:30
ljain112
d7e6b0e1b7 fix: correct placeholder index in message
(cherry picked from commit d61cb9a4bf)
2024-11-27 09:26:10 +00:00
Raffael Meyer
fef7cfb888 fix: unify company address query in sales transactions (backport #44361) (#44366)
* fix: unify company address query in sales transactions (backport #44361)

* style: add whitespace
2024-11-26 21:11:27 +01:00
Khushi Rawat
aa442da2f6 Merge pull request #44329 from khushi8112/incorrect-gl-entry-on-asset-sale
fix: incorrect GL entry on sale of fully depreciated asset
2024-11-27 01:09:33 +05:30
mergify[bot]
6aebe98020 fix: billed qty and received amount in PO analysis report (backport #44349) (#44353)
* fix: billed qty and received amount in PO analysis report (#44349)

(cherry picked from commit 2ab7ec5437)

# Conflicts:
#	erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-11-26 21:18:38 +05:30
Khushi Rawat
841df3b1ce fix: change asset status correctly 2024-11-26 14:06:07 +05:30
Khushi Rawat
cc5ada194e fix: incorrect GL entry on sale of fully depreciated asset 2024-11-26 01:39:42 +05:30
Smit Vora
edccb746f0 Merge pull request #44294 from Abdeali099/fix-fiscal-dates 2024-11-25 16:15:04 +05:30
ruthra kumar
506fd97a2c Merge pull request #44314 from frappe/mergify/bp/version-14-hotfix/pr-44297
refactor: added translate function for some columns of report (backport #44297)
2024-11-25 10:39:49 +05:30
Abdeali Chharchhoda
6c9485fb13 refactor: added translate function for some columns of report
(cherry picked from commit e545c913b5)
2024-11-25 04:39:26 +00:00
Abdeali Chharchhoda
4f806f9a72 fix: Used Fiscal Dates instead of year's Start and End dates 2024-11-22 18:09:23 +05:30
ruthra kumar
8a45258778 Merge pull request #44286 from frappe/mergify/bp/version-14-hotfix/pr-44246
fix: Get submitted documents in validate_for_closed_fiscal_year (backport #44246)
2024-11-22 16:25:37 +05:30
rohitwaghchaure
d10a9d3225 Merge pull request #44288 from frappe/mergify/bp/version-14-hotfix/pr-44191
fix: patch (backport #44191)
2024-11-22 16:25:03 +05:30
rohitwaghchaure
3643c60c67 fix: patch (#44191)
(cherry picked from commit 495528a758)
2024-11-22 10:51:44 +00:00
ruthra kumar
92e252e37a Merge pull request #44284 from frappe/mergify/bp/version-14-hotfix/pr-44266
fix: make free qty round on large transaction qty (backport #44266)
2024-11-22 16:15:19 +05:30
vimalraj27
b9efeeb71a fix: Get submitted documents in validate_for_closed_fiscal_year
(cherry picked from commit c607e5f940)
2024-11-22 15:56:34 +05:30
venkat102
d695fb5723 test: add unit test to validate free qty round on large transaction qty
(cherry picked from commit 013a6fc6ec)
2024-11-22 10:20:54 +00:00
venkat102
2eb70026ae fix: make free qty round on large transaction qty
(cherry picked from commit f9b8165385)
2024-11-22 10:20:53 +00:00
ruthra kumar
18cbc956bb Merge pull request #44271 from frappe/mergify/bp/version-14-hotfix/pr-44194
fix: include current invoice amount when tax_on_excess_amount is checked (backport #44194)
2024-11-22 11:29:21 +05:30
venkat102
47e4fd3c76 test: add unit test for tax on excess amount
(cherry picked from commit 4820273595)
2024-11-22 05:37:26 +00:00
venkat102
071adcf291 fix: include current invoice amount when tax_on_excess_amount is checked
(cherry picked from commit b74f2896cd)
2024-11-22 05:37:26 +00:00
mergify[bot]
ee647f2381 fix: added Stock UOM field for RM in work order (backport #44185) (#44236)
* fix: added Stock UOM field for RM in work order (#44185)

fix: added UOM field for RM in work order
(cherry picked from commit cc571aca8f)

# Conflicts:
#	erpnext/manufacturing/doctype/work_order_item/work_order_item.json
#	erpnext/manufacturing/doctype/work_order_item/work_order_item.py
#	erpnext/patches.txt

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-11-21 14:52:18 +05:30
ruthra kumar
24126b03dd Merge pull request #44244 from frappe/mergify/bp/version-14-hotfix/pr-44197
fix: payment reco for jv with negative dr or cr amount (backport #44197)
2024-11-20 13:12:55 +05:30
ljain112
5fa4fd8825 fix: added test cases
(cherry picked from commit 6f9ea6422d)
2024-11-20 07:18:19 +00:00
ljain112
23fb4f348f fix: payment reco for jv with negative dr or cr amount
(cherry picked from commit fee79b9445)
2024-11-20 07:18:19 +00:00
ruthra kumar
227c912ece Merge pull request #44241 from frappe/mergify/bp/version-14-hotfix/pr-44240
fix: non group pos warehouse (backport #44240)
2024-11-20 12:17:33 +05:30
ruthra kumar
5bfbdb805c Merge pull request #44238 from frappe/mergify/bp/version-14-hotfix/pr-44220
refactor: Update `Payment Request` search query in PE's reference (backport #44220)
2024-11-20 12:16:21 +05:30
Nihantra C. Patel
ec40131d4d fix: non group pos warehouse
(cherry picked from commit d526be0394)
2024-11-20 06:41:34 +00:00
ruthra kumar
859672c419 Merge pull request #44232 from frappe/mergify/bp/version-14-hotfix/pr-44207
fix: validate sales team to ensure all sales person are enabled (backport #44207)
2024-11-20 11:51:56 +05:30
Abdeali Chharchhoda
e8c3617628 refactor: Update Payment Request search query in PE's reference
(cherry picked from commit 4ab3499a17)
2024-11-20 06:21:41 +00:00
ruthra kumar
09b21b8cb4 Merge pull request #44234 from frappe/mergify/bp/version-14-hotfix/pr-44203
fix: disable conversion to user tz for sales order calender (backport #44203)
2024-11-20 11:51:21 +05:30
ljain112
356da69179 fix: disable conversion to user tz for sales order calender
(cherry picked from commit cdf098c193)
2024-11-20 05:17:52 +00:00
ljain112
bd0f11ef4f fix: validate sales team to ensure all sales person are enabled
(cherry picked from commit 548dbb33eb)
2024-11-20 05:11:35 +00:00
ruthra kumar
9f3dfb3d18 Merge pull request #44216 from frappe/mergify/bp/version-14-hotfix/pr-44104
fix: check if pricing rule matches with coupon code (backport #44104)
2024-11-19 17:37:33 +05:30
Nikolas Beckel
24b5b3c8e0 fix: check if pricing rule matches with coupon code (#44104)
* fix: check if pricing rule matches with coupon code

* fix: correct linting error

(cherry picked from commit 9d31bf7647)
2024-11-19 11:41:48 +00:00
mergify[bot]
a7de8c1143 feat: new DocTypes "Code List" and "Common Code" (backport #43425) (#44172)
Co-authored-by: David <dgx.arnold@gmail.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-11-18 20:59:41 +01:00
ruthra kumar
2fcab327aa Merge pull request #44181 from frappe/mergify/bp/version-14-hotfix/pr-44127
fix: set default Party Type based on Payment Type in Payment Entry (backport #44127)
2024-11-18 10:49:10 +05:30
vishakhdesai
f3cbbef346 fix: set default party type in Payment Entry
(cherry picked from commit 19222690d3)
2024-11-18 10:16:59 +05:30
ruthra kumar
339beff023 Merge pull request #44179 from frappe/mergify/bp/version-14-hotfix/pr-44147
fix: set conversion factor before applying price list (backport #44147)
2024-11-18 10:14:34 +05:30
ruthra kumar
85d398efcc Merge pull request #44177 from frappe/mergify/bp/version-14-hotfix/pr-44157
fix: apply "cannot_add_rows" directly to table field for more efficient solution (backport #44157)
2024-11-18 10:14:12 +05:30
vishakhdesai
e09f101336 fix: set conversion factor before applying price list
(cherry picked from commit 9749fe23cc)
2024-11-18 04:38:32 +00:00
UmakanthKaspa
f9b52b292e refactor: set 'cannot_add_rows' directly in the allocations table field (optimized approach)
(cherry picked from commit 5dd8eafdfc)
2024-11-18 04:36:12 +00:00
Türker Tunalı
8a94d7bea8 fix:Unable to pause job card (#42839)
fix: unable to pause job card

Pause operation creates "Value missing for: Completed Qty" error. That field was mandatory but it's non mandatory in v15.
2024-11-15 17:29:58 +05:30
mergify[bot]
f871f08f47 fix: stock ledger variance report filter options (backport #44137) (#44149)
fix: stock ledger variance report filter options (#44137)

(cherry picked from commit e8bbf6492f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-11-15 15:05:03 +05:30
ruthra kumar
313ea3983f Merge pull request #44161 from frappe/mergify/bp/version-14-hotfix/pr-43414
fix: Get Entries not showing accounts with no gain or loss in Exchange Rate Revaluation issue fixed (backport #43414)
2024-11-15 13:09:35 +05:30
Vishakh Desai
c3e2ff2fa5 fix: linters
(cherry picked from commit 9cc22b4cac)
2024-11-15 07:18:49 +00:00
Vishakh Desai
33e835c4d3 fix: Get Entries not showing accounts with no gain or loss in Exchange Rate Revaluation issue
(cherry picked from commit 6de6f55b39)
2024-11-15 07:18:49 +00:00
ruthra kumar
c9fa4af4fe Merge pull request #44159 from frappe/mergify/bp/version-14-hotfix/pr-44158
fix: broken UI on currency exchange (backport #44158)
2024-11-15 12:28:18 +05:30
ruthra kumar
36898f6797 fix: broken UI on currency exchange
(cherry picked from commit e91b65e7bd)
2024-11-15 06:52:40 +00:00
ruthra kumar
b9a0f4fed8 Merge pull request #44154 from frappe/mergify/bp/version-14-hotfix/pr-44089
fix: apply posting date sorting to invoices in Payment Reconciliation similar to payments (backport #44089)
2024-11-15 10:54:40 +05:30
UmakanthKaspa
1019d98c5a fix: remove trailing whitespace
(cherry picked from commit d6703eb88b)
2024-11-15 05:00:03 +00:00
UmakanthKaspa
cc9b22ce9f fix: apply posting date sorting to invoices in Payment Reconciliation similar to payments
(cherry picked from commit 0bd83d920d)
2024-11-15 05:00:02 +00:00
ruthra kumar
f5135cd4a4 Merge pull request #44152 from frappe/mergify/bp/version-14-hotfix/pr-44148
Fix: Disable "Add Row" button in allocations table during UnReconcile process (backport #44148)
2024-11-15 10:22:43 +05:30
UmakanthKaspa
137ef78d96 fix: correctly set 'cannot_add_rows' property on allocations table field
(cherry picked from commit 13ca2700f8)
2024-11-15 04:47:46 +00:00
ruthra kumar
5452f8ac4a Merge pull request #44139 from frappe/mergify/bp/version-14-hotfix/pr-43189
fix: broken apply on other item (backport #43189)
2024-11-14 13:45:41 +05:30
ruthra kumar
f03e301250 fix: broken apply on other item pricing rule
(cherry picked from commit e5119a749c)
2024-11-14 07:54:10 +00:00
Raffael Meyer
c23868a14d fix: backport german translations from develop (#44046) 2024-11-13 18:17:50 +01:00
ruthra kumar
ddac2c59ab Merge pull request #44114 from frappe/mergify/bp/version-14-hotfix/pr-43977
fix: update per_billed value in Purchase Receipt while creating Debit Note (backport #43977)
2024-11-13 19:01:04 +05:30
rohitwaghchaure
030df0d7e8 chore: fix conflicts 2024-11-13 18:27:41 +05:30
NaviN
da6c6dcfcb fix: update per_billed value in Purchase Receipt while creating Debit Note (#43977)
* fix: update per_billed value in Purchase Receipt while creating Debit Note

* test: add unit test for validating per_billed value for partial Debit Note

(cherry picked from commit 494fd7ceea)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-11-13 18:27:41 +05:30
ruthra kumar
cbe92fef0c Merge pull request #44128 from frappe/mergify/bp/version-14-hotfix/pr-39543
feat: Partly billed status in Purchase Receipt (backport #39543)
2024-11-13 18:04:39 +05:30
Deepesh Garg
3e2fa16d84 feat: Partly billed status in Purchase Receipt (#39543)
(cherry picked from commit a673220feb)
2024-11-13 12:13:37 +00:00
ruthra kumar
44988c8bfa Merge pull request #44126 from frappe/mergify/copy/version-14-hotfix/pr-44124
refactor: 'Partly Billed' status for Purchase Receipt (copy #44124)
2024-11-13 17:22:41 +05:30
ruthra kumar
2acee05a0a refactor: 'Partly Billed' status for Purchase Receipt
(cherry picked from commit c58bbd25f2)
2024-11-13 17:00:20 +05:30
Nihantra C. Patel
d258684b8d Merge pull request #44119 from frappe/mergify/bp/version-14-hotfix/pr-44116
fix: Drop Shipping address based on customer shopping address (backport #44116)
2024-11-13 15:51:55 +05:30
Nihantra Patel
ea38a1f36a fix: Drop Shipping address based on customer shopping address
(cherry picked from commit c7499f3528)
2024-11-13 10:01:42 +00:00
ruthra kumar
7fb5f17100 Merge pull request #44087 from frappe/mergify/bp/version-14-hotfix/pr-43695
fix: exception on register reports when filtered on cost center (backport #43695)
2024-11-11 17:05:32 +05:30
ruthra kumar
fd9fd8f46f chore: filter report output 2024-11-11 16:42:42 +05:30
ruthra kumar
558fac6843 chore: use FrappeTestCase 2024-11-11 15:07:46 +05:30
ruthra kumar
71a1e50314 refactor(test): assertion refactoring and exact decimals
(cherry picked from commit 1d11131afe)
2024-11-11 09:18:08 +00:00
ruthra kumar
4f7d534cab refactor(test): pass all mandatory fields
(cherry picked from commit c53e9637dd)
2024-11-11 09:18:08 +00:00
ruthra kumar
a8a89f971d refactor(test): fix incorrect assertion
(cherry picked from commit d6030e7112)
2024-11-11 09:18:07 +00:00
ruthra kumar
964ac05e74 test: journals with cost center
(cherry picked from commit c255f34eea)
2024-11-11 09:18:07 +00:00
ruthra kumar
a98fe7a72b test: basic report output
(cherry picked from commit 657201b324)
2024-11-11 09:18:07 +00:00
Vishv-silveroak
599581e09d fix: exception on register reports when filtered on cost center
1

(cherry picked from commit f01e1a8e20)
2024-11-11 09:18:07 +00:00
mergify[bot]
6b149f5ddf fix: populate payment schedule from payment terms (backport #44082) (#44084)
fix: populate payment schedule from payment terms (#44082)

(cherry picked from commit c81eb6c824)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-11-11 13:12:39 +05:30
mergify[bot]
f2aa71cd6c chore: update CODEOWNERS (backport #44074) (#44080)
* chore: update `CODEOWNERS` (#44074)

(cherry picked from commit 9a758ea826)

# Conflicts:
#	CODEOWNERS

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-11-11 13:06:26 +05:30
mergify[bot]
c12d5f613a fix: task path (backport #44073) (#44077)
fix: task path (#44073)

(cherry picked from commit 8c99acb1b9)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-11-11 13:00:43 +05:30
rohitwaghchaure
3df783bfff Merge pull request #44069 from frappe/mergify/bp/version-14-hotfix/pr-44058
fix: type error while saving pick list (backport #44058)
2024-11-11 12:27:00 +05:30
vishnu
d73cc83b91 fix: tyeerror while saving pick list
(cherry picked from commit 22de0ecbdc)
2024-11-11 06:24:53 +00:00
ruthra kumar
093b4f9845 Merge pull request #44026 from frappe/mergify/bp/version-14-hotfix/pr-43873
fix: add missing fields to field_no_map array (backport #43873)
2024-11-08 11:52:24 +05:30
Ravindu Nethmina
440ada1bdc refactor: add "margin_type" and "margin_rate_or_amount" to no copy
(cherry picked from commit 70f090c1ec)
2024-11-08 06:00:28 +00:00
ruthra kumar
82cd42bbdf Merge pull request #44023 from frappe/mergify/bp/version-14-hotfix/pr-43762
fix: handle NoneType error when updating ordered_qty in SO for remove… (backport #43762)
2024-11-08 11:11:18 +05:30
bhaveshkumar.j
1446aa3636 fix: NoneType while updating ordered_qty in SO for removed items
(cherry picked from commit 442cdd7ce4)
2024-11-08 05:10:39 +00:00
Sagar Vora
0cdb4cb927 Merge pull request #44014 from Ninad1306/dashboard_links 2024-11-07 18:16:06 +05:30
Ninad1306
b1e205f4d1 fix: subcontracting receipt has no reference field for purchase order 2024-11-07 16:34:14 +05:30
rohitwaghchaure
9838eaa332 fix: serial no ledger report (#44006) 2024-11-07 13:12:46 +05:30
mergify[bot]
bc9f0f8368 fix: task showing limit in customer portal (backport #44003) (#44004)
fix: task showing limit in customer portal (#44003)

(cherry picked from commit 44832c3b5c)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-11-07 12:49:42 +05:30
Sagar Vora
478b49cc49 Merge pull request #43994 from frappe/mergify/bp/version-14-hotfix/pr-43993
fix: ensure list has items (backport #43993)
2024-11-06 14:08:21 +05:30
Sagar Vora
5c8af85086 fix: ensure list has items
(cherry picked from commit e13e688987)
2024-11-06 08:37:20 +00:00
Sagar Vora
876af6dca5 Merge pull request #43990 from frappe/mergify/bp/version-14-hotfix/pr-43989
fix: error when saving POS merge log (backport #43989)
2024-11-06 13:26:09 +05:30
Sagar Vora
657bd3712b fix: error when saving POS merge log (#43989)
(cherry picked from commit c62596b323)
2024-11-06 07:52:12 +00:00
Sagar Vora
0a166a813a Merge pull request #43988 from frappe/mergify/bp/version-14-hotfix/pr-43985
fix: removed single quotes from deferred revenue (backport #43985)
2024-11-06 12:08:14 +05:30
Nihantra C. Patel
aee8a23626 fix: removed single quotes from deferred revenue (#43985)
(cherry picked from commit 834d18840c)
2024-11-06 06:37:02 +00:00
mergify[bot]
57d35ec20e perf: too many writes error during reposting (backport #43978) (#43982)
perf: too many writes error during reposting (#43978)

perf: too many writes error
(cherry picked from commit 134c24b9c5)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-11-06 10:05:36 +05:30
ruthra kumar
1e2bea82f9 Merge pull request #43964 from frappe/mergify/bp/version-14-hotfix/pr-43388
fix: SO link on PO and add in missing dashboard references on both (backport #43388)
2024-11-04 15:34:04 +05:30
ruthra kumar
0f4c5dd26c chore: resolve conflicts
Stock Reservation Entry is unavailable in v14
2024-11-04 14:17:04 +05:30
CaseSolved
7906c21bdf chore: linting
(cherry picked from commit be6970c850)
2024-11-04 08:32:22 +00:00
CaseSolved
4f8a8a5e99 fix: SO link on PO and add in missing dashboard references on both
(cherry picked from commit 2017fd80d1)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order_dashboard.py
#	erpnext/selling/doctype/sales_order/sales_order_dashboard.py
2024-11-04 08:32:22 +00:00
mergify[bot]
42c2b84b28 feat: remove Payroll Entry from Bank Account dashboard (backport #43931) (#43932)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-10-30 15:49:21 +01:00
mergify[bot]
55c5f30d54 fix: calculate tds with net amount when invoice exceeds single threshold amount (backport #43869) (#43919)
* fix: calculate tds with net amount when invoice exceeds single threshold amount

(cherry picked from commit ef694a40a1)

* test: add unit test to validate purchase invoice exceeding single threshold value

(cherry picked from commit 94badb464d)

---------

Co-authored-by: venkat102 <venkatesharunachalam659@gmail.com>
2024-10-30 11:26:08 +05:30
ruthra kumar
cc85f5de26 Merge pull request #43916 from frappe/mergify/bp/version-14-hotfix/pr-43886
fix: remarks field in payment reconciliation (backport #43886)
2024-10-30 10:51:39 +05:30
ruthra kumar
15881ea718 chore: resolve conflicts 2024-10-30 10:30:48 +05:30
Ahmed Shareef
93243b1d95 fix: remarks field in payment reconciliation
(cherry picked from commit 2d5b079949)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.json
#	erpnext/accounts/doctype/payment_reconciliation_payment/payment_reconciliation_payment.py
2024-10-30 04:50:23 +00:00
mergify[bot]
76530de786 fix: work order finish button not showing (backport #43875) (#43877)
* fix: work order finish button not showing (#43875)

(cherry picked from commit 0a70be5b99)

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

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-10-29 22:00:36 +05:30
ruthra kumar
d04396b697 Merge pull request #43896 from frappe/mergify/bp/version-14-hotfix/pr-43856
fix: add parenttype clause to invoice tax query in sales_register report (backport #43856)
2024-10-29 16:12:46 +05:30
ruthra kumar
e552df31d6 Merge pull request #43894 from frappe/mergify/bp/version-14-hotfix/pr-43698
fix: Project name instead of ID in chart (backport #43698)
2024-10-29 16:12:32 +05:30
Imesha Sudasingha
cbe704c73c fix: add parenttype clause to invoice tax query in sales_register report
(cherry picked from commit e30ab141f4)
2024-10-29 10:10:37 +00:00
rohitwaghchaure
0742e6e193 fix: not able to submit stock entry (#43890) 2024-10-29 15:35:19 +05:30
lukas.brandhoff
3fa392ebdf refactor: include 'Project Name' in Project summary report
Keep name field for backwards compatibility

(cherry picked from commit 736d1a1105)
2024-10-29 09:54:26 +00:00
ruthra kumar
a3c2121870 Merge pull request #43863 from frappe/mergify/bp/version-14-hotfix/pr-43685
fix: do not check for payment terms details for return invoices. (backport #43685)
2024-10-28 15:53:06 +05:30
mergify[bot]
aaae81f7e8 fix: added validation for UOM must be whole number (backport #43710) (#43711)
* fix: added validation for UOM must be whole number (#43710)

(cherry picked from commit 4fd4a37dc9)

# Conflicts:
#	erpnext/controllers/accounts_controller.py

* chore: fix conflicts

* chore: fix linters issue

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-10-28 15:12:16 +05:30
rohitwaghchaure
a7cc7b28c0 fix: purchase return validation issue (#43871) 2024-10-28 15:11:07 +05:30
mergify[bot]
51c1d032ba fix: basic rate not editable in Stock Entry Detail (backport #43837) (#43839)
* fix: basic rate not editable in Stock Entry Detail (#43837)

(cherry picked from commit 5a967bc868)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-10-28 14:02:23 +05:30
ruthra kumar
c695959902 chore: resolve conflicts 2024-10-28 13:32:30 +05:30
ruthra kumar
83f5a24520 Merge pull request #43868 from frappe/mergify/bp/version-14-hotfix/pr-43862
refactor: fix garbage title, desc and name in razorpay (backport #43862)
2024-10-28 12:47:42 +05:30
ruthra kumar
627832fe5b refactor: fix garbage title, desc and name in razorpay
(cherry picked from commit 7332ec8fbd)
2024-10-28 06:55:08 +00:00
ljain112
78db8c0029 fix: hide payment terms for return and paid purchase invoices
(cherry picked from commit 912e1e3f3d)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2024-10-28 05:53:55 +00:00
ljain112
bd34a67871 fix: do not set payment terms for return invoices
(cherry picked from commit 8b700eadc7)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2024-10-28 05:53:54 +00:00
ljain112
fd63ace6c7 fix: do not check for payment terms details for return invoices.
(cherry picked from commit 6703b7d1ae)
2024-10-28 05:53:54 +00:00
ruthra kumar
36fdd540c0 Merge pull request #43858 from frappe/mergify/bp/version-14-hotfix/pr-43833
refactor: query for expense_account moved to setup hook in purchase invoice (backport #43833)
2024-10-28 09:59:55 +05:30
ruthra kumar
b81dc2bf5e chore: resolve conflict 2024-10-28 09:55:04 +05:30
ljain112
7e7cc807a5 refactor: query for expense_account moved to setup hook in purchase invoice
(cherry picked from commit a9ac0cc223)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
2024-10-28 04:14:14 +00:00
mergify[bot]
895f1bff01 fix(RFQ): make strings translatable (backport #43843) (#43847)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(RFQ): make strings translatable (#43843)
2024-10-26 19:51:31 +02:00
ruthra kumar
53c4b5f752 Merge pull request #43832 from frappe/mergify/bp/version-14-hotfix/pr-43830
fix: set bill_no before `against_voucher` gets concatenated (backport #43830)
2024-10-25 14:28:44 +05:30
ruthra kumar
2f3c3d5519 fix: set bill_no before against_voucher gets concatenated
(cherry picked from commit 7bade7f1fe)
2024-10-25 14:05:15 +05:30
ruthra kumar
6ddff1b168 Merge pull request #43806 from frappe/mergify/bp/version-14-hotfix/pr-43755
fix: Add Company Filter (backport #43755)
2024-10-23 17:57:42 +05:30
IamSaiyyamChhetri
d3e29fe828 fix: add company filter for project
- In Project dt Sales Order field
- In Sales Order dt Project field

(cherry picked from commit 9909d760a5)
2024-10-23 17:31:44 +05:30
Smit Vora
3ace876c1f Merge pull request #43784 from frappe/mergify/bp/version-14-hotfix/pr-43462
fix: get stock accounts from the doc in `validate_stock_accounts` in Journal Entry (backport #43462)
2024-10-23 10:36:30 +05:30
mergify[bot]
5b0a8fd2ce fix: use correct variable in error message (backport #43790) (#43791)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: use correct variable in error message (#43790)
2024-10-22 19:43:13 +02:00
Sagar Vora
f5f6c7609a test: fix test case 2024-10-22 20:27:06 +05:30
Vishakh Desai
ad04610c94 fix: get stock accounts from the doc instead of db in validate_stock_accounts
(cherry picked from commit 30954586d8)
2024-10-22 14:07:06 +00:00
ruthra kumar
1a4a329c1d Merge pull request #43779 from frappe/mergify/bp/version-14-hotfix/pr-43778
refactor: validate_return_against_account (backport #43778)
2024-10-22 17:36:37 +05:30
Raffael Meyer
411f7c3a2c refactor: validate_return_against_account (#43778)
(cherry picked from commit c4faa0e101)
2024-10-22 11:45:49 +00:00
ruthra kumar
c55d473c92 Merge pull request #43776 from frappe/mergify/bp/version-14-hotfix/pr-43775
fix(deferred_revenue): Escape account in query (backport #43775)
2024-10-22 16:40:02 +05:30
Corentin Forler
3d082c93bc fix(deferred_revenue): Escape account in query
(cherry picked from commit c7b3ae41d4)
2024-10-22 10:42:08 +00:00
ruthra kumar
a3e8cc6abe Merge pull request #43767 from frappe/mergify/bp/version-14-hotfix/pr-43766
refactor: allow unreconcile on bank and cash entry type journals (backport #43766)
2024-10-22 12:12:52 +05:30
ruthra kumar
0dcb5a4fbb refactor: allow unreconcile on bank and cash entry type journals
(cherry picked from commit 2c4f37f488)
2024-10-22 06:35:37 +00:00
ruthra kumar
14a589eb2f Merge pull request #43764 from frappe/mergify/bp/version-14-hotfix/pr-43761
fix: coupon code validation logic (backport #43761)
2024-10-22 10:39:10 +05:30
ruthra kumar
2af36383cc chore: resolve conflict 2024-10-22 10:16:57 +05:30
bhaveshkumar.j
719565c897 fix: remove extra space
(cherry picked from commit 1561a9e1bf)
2024-10-22 04:37:48 +00:00
bhaveshkumar.j
c18beaea6b fix: coupon code validation logic
(cherry picked from commit d04257a32d)

# Conflicts:
#	erpnext/accounts/doctype/pricing_rule/utils.py
2024-10-22 04:37:48 +00:00
ruthra kumar
3d5c15df0a Merge pull request #43741 from frappe/mergify/bp/version-14-hotfix/pr-43726
fix: "show_remarks" checkbox in Process statement of accounts (backport #43726)
2024-10-21 13:09:04 +05:30
ruthra kumar
0cf172c0da Merge pull request #43743 from frappe/mergify/bp/version-14-hotfix/pr-43727
fix: get period estimate till service end date (backport #43727)
2024-10-21 13:08:44 +05:30
ruthra kumar
5289022351 Merge pull request #43745 from frappe/mergify/bp/version-14-hotfix/pr-43720
fix: party_balance based on company in payment entry (backport #43720)
2024-10-21 13:08:22 +05:30
ruthra kumar
bbce58524e Merge pull request #43747 from frappe/mergify/bp/version-14-hotfix/pr-42461
fix: Freeze Screen on load invoices on POS Closing Entry (backport #42461)
2024-10-21 13:08:02 +05:30
HarryPaulo
725b6beff3 fix: Freeze Screen on load invoices on POS Closing Entry
(cherry picked from commit 486d396174)
2024-10-21 06:57:51 +00:00
ljain112
5333f33c21 fix: party_balance based on company in payment entry
(cherry picked from commit 97c9adf06b)
2024-10-21 06:53:31 +00:00
ruthra kumar
beb5318446 chore: resolve conflict 2024-10-21 12:21:51 +05:30
venkat102
35c257a7ae fix: get period estimate till service end date
(cherry picked from commit a7ba7e9c28)
2024-10-21 06:50:26 +00:00
ljain112
083382399f fix: "show_remarks" checkbox in Process statement of accounts
(cherry picked from commit f4600df1f7)

# Conflicts:
#	erpnext/accounts/doctype/process_statement_of_accounts/process_statement_of_accounts.py
2024-10-21 06:44:35 +00:00
ruthra kumar
a05d6de2be Merge pull request #43716 from frappe/mergify/bp/version-14-hotfix/pr-42898
fix: incorrect amount in bank clearance (backport #42898)
2024-10-18 11:01:11 +05:30
NIYAZ RAZAK
98362d9183 fix: incorrect amount in bank clearance
(cherry picked from commit 9a11df59fc)
2024-10-18 10:37:17 +05:30
ruthra kumar
2e6ead30e0 Merge pull request #43683 from frappe/mergify/bp/version-14-hotfix/pr-43661
fix: missing child company accounts in consolidated balance sheet (backport #43661)
2024-10-15 17:38:11 +05:30
ruthra kumar
70050081ff Merge pull request #43681 from frappe/mergify/bp/version-14-hotfix/pr-43663
fix: run gl_entries and closing voucher processes in same function (backport #43663)
2024-10-15 17:28:04 +05:30
ljain112
bb774cec58 fix: missing child company accounts in consolidated balance sheet
(cherry picked from commit 7fae9d57d2)
2024-10-15 11:37:52 +00:00
ruthra kumar
7c549e60d6 Merge pull request #43679 from frappe/mergify/bp/version-14-hotfix/pr-43602
fix: added parentheses for correct query formation for logical OR condition (backport #43602)
2024-10-15 17:07:17 +05:30
ljain112
59c314c98a fix: run gl_entries and closing voucher processes in same function
(cherry picked from commit af4daa5b0f)
2024-10-15 11:35:55 +00:00
ljain112
0f738de5e5 fix: added parentheses for correct query formation for logical OR condition
(cherry picked from commit c0da8f11f7)
2024-10-15 11:15:40 +00:00
ruthra kumar
8701cb73ef Merge pull request #43677 from frappe/mergify/bp/version-14-hotfix/pr-43600
fix: added string for translation in bank reconciliation statement (backport #43600)
2024-10-15 16:40:53 +05:30
ljain112
32f6eb7ee7 fix: added string for translation in bank reconciliation statement
(cherry picked from commit c99d9f7037)
2024-10-15 11:02:29 +00:00
mergify[bot]
1262c322d1 fix: conversion factor issue (backport #43645) (#43675)
fix: conversion factor issue (#43645)

(cherry picked from commit a52756f1d4)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-10-15 16:08:37 +05:30
ruthra kumar
aa85c3abee Merge pull request #43669 from frappe/mergify/bp/version-14-hotfix/pr-43557
fix: delete invalid pricing rule on change of applicable_for values (backport #43557)
2024-10-15 15:56:29 +05:30
ljain112
5d9474c98c test: added test for change in applicable_for_value in promotional scheme
(cherry picked from commit 2613bdd868)
2024-10-15 09:55:31 +00:00
ljain112
c7c2bdd159 fix: delete invalid pricing rule on change of applicable_for
(cherry picked from commit 42746fc630)
2024-10-15 09:55:31 +00:00
ruthra kumar
1913caf2b0 Merge pull request #43665 from frappe/mergify/bp/version-14-hotfix/pr-43662
fix: removed unused query (backport #43662)
2024-10-15 13:55:52 +05:30
ruthra kumar
5aff4242e3 Merge pull request #43657 from frappe/mergify/bp/version-14-hotfix/pr-43570
fix: update item details with actual quantity (backport #43570)
2024-10-15 13:52:23 +05:30
ruthra kumar
e7f630fc74 chore: resolve conflict 2024-10-15 13:34:37 +05:30
ruthra kumar
9697cb066c Merge pull request #43659 from frappe/mergify/bp/version-14-hotfix/pr-43642
fix: zero incoming rate for delivery note return (backport #43642)
2024-10-15 13:26:03 +05:30
ruthra kumar
be78e17e8c chore: resolve conflict 2024-10-15 13:25:14 +05:30
ljain112
dcbfd4ae1d fix: removed unused query
(cherry picked from commit 5f590ddfa2)

# Conflicts:
#	erpnext/accounts/doctype/tax_withholding_category/tax_withholding_category.py
2024-10-15 07:53:40 +00:00
rohitwaghchaure
a585a7029f chore: fix conflicts 2024-10-15 12:08:24 +05:30
rohitwaghchaure
7eac9cc1db fix: zero incoming rate for delivery note return (#43642)
(cherry picked from commit 6087a57b0c)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/test_delivery_note.py
2024-10-15 06:28:36 +00:00
Bhavan23
a8ad608fd8 fix: update formatings
(cherry picked from commit 5044297321)
2024-10-15 06:27:42 +00:00
Bhavan23
699b09846a fix: update formatings
(cherry picked from commit 5f4a523340)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.py
2024-10-15 06:27:41 +00:00
Bhavan23
dc2483bb92 test: Validate the actual quantity when creating a material request from the sales order
(cherry picked from commit 17fdd42645)
2024-10-15 06:27:41 +00:00
Bhavan23
c520a7c6c1 fix: update item details with actual quantity.
(cherry picked from commit 9dbdfec9b7)
2024-10-15 06:27:40 +00:00
ruthra kumar
475c9b8450 Merge pull request #43653 from frappe/mergify/bp/version-14-hotfix/pr-43601
refactor: remove 'format:' based naming (backport #43601)
2024-10-15 07:34:49 +05:30
ruthra kumar
2cce2cfdbe Merge pull request #43649 from frappe/mergify/bp/version-14-hotfix/pr-43614
fix: ignore free item when qty is zero (backport #43614)
2024-10-15 06:01:44 +05:30
ruthra kumar
065465626e chore: resolve conflict 2024-10-15 06:00:47 +05:30
venkat102
fc7207bcd3 refactor: remove 'format:' based naming
(cherry picked from commit e8e1ec0e85)

# Conflicts:
#	erpnext/accounts/doctype/unreconcile_payment/unreconcile_payment.json
2024-10-14 15:45:57 +00:00
Ninad1306
3b1f0c191e test: test case to validate free item is ignored when qty is zero
(cherry picked from commit a2b41a0c16)
2024-10-14 10:51:00 +00:00
Ninad1306
ae47fb9617 fix: ignore free item when qty is zero
(cherry picked from commit 7ae98f77ee)
2024-10-14 10:51:00 +00:00
Smit Vora
16d9ca72e8 Merge pull request #43640 from frappe/mergify/bp/version-14-hotfix/pr-43638
fix: Use `ref_doc.get()` for `party_account_currency` (backport #43638)
2024-10-14 13:59:05 +05:30
Abdeali Chharchhoda
01d6c1081b fix: Use ref_doc.get() for party_account_currency
(cherry picked from commit b79549422a)
2024-10-14 06:09:08 +00:00
mergify[bot]
1f099752d2 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>
2024-10-12 18:32:30 +05:30
Sagar Vora
8714ec608b Merge pull request #43571 from frappe/mergify/bp/version-14-hotfix/pr-43271
fix: deduct advances adjusted for threshold check for tcs (backport #43271)
2024-10-09 18:38:07 +05:30
Sagar Vora
e7518414cb Merge pull request #43595 from ljain112/fix-pr-43271 2024-10-09 17:44:37 +05:30
ljain112
d5c82ccbab test: fixed account settings in test case 2024-10-09 17:34:59 +05:30
ljain112
f5a7c8b0b0 test: added test cases for the tcs deduction for advances adjusted.
(cherry picked from commit efe238cefd)
2024-10-08 12:05:48 +00:00
ljain112
de15728741 fix: deduct advances adjusted for threshold check for tcs
(cherry picked from commit 767c8f92be)
2024-10-08 12:05:48 +00:00
Smit Vora
d6f9909ba5 Merge pull request #43552 from frappe/mergify/bp/version-14-hotfix/pr-43397
fix: do not include advances for tds vouchers (backport #43397)
2024-10-08 11:29:48 +05:30
ljain112
9d950a9b77 fix: do not include advances for tds vouchers
(cherry picked from commit 7ef918421e)
2024-10-08 05:09:01 +00:00
Smit Vora
0336e7ac45 Merge pull request #43529 from frappe/mergify/bp/version-14-hotfix/pr-43407
fix: multiple issues in Payment Request (backport #43407)
2024-10-08 10:38:50 +05:30
Smit Vora
078eb46eb8 fix: get company from ref doc as it's not available in payment request 2024-10-07 22:55:58 +05:30
Smit Vora
1d21f428c1 Merge pull request #43526 from frappe/mergify/bp/version-14-hotfix/pr-43391
fix: create Account Closing Balance even though there are no transaction in period (backport #43391)
2024-10-07 22:34:37 +05:30
Smit Vora
71ee88dc79 Merge pull request #43524 from frappe/mergify/bp/version-14-hotfix/pr-43384
fix: add parenttype condition for item table in Purchase Register Report (backport #43384)
2024-10-07 22:34:23 +05:30
Smit Vora
f6b91969b2 chore: resolve conflicts, remove additional new fields 2024-10-07 22:31:49 +05:30
Smit Vora
3f5f37fa73 chore: resolve conflicts visible prima-facie 2024-10-07 22:15:26 +05:30
Smit Vora
d4258fff9d chore: remove unused filed
(cherry picked from commit 0c599c2b6d)
2024-10-07 16:17:06 +00:00
Abdeali Chharchhoda
54608bdff9 test: Change Accounts Settings for multi currency (https://github.com/frappe/erpnext/pull/42427#discussion_r1789859737)
(cherry picked from commit 62cc86114b)
2024-10-07 16:17:05 +00:00
Abdeali Chharchhoda
4d00d2b87b test: Remove Payment Gateway settings from test
(cherry picked from commit 3d9d56ab50)
2024-10-07 16:17:05 +00:00
Abdeali Chharchhoda
d828ea6a1a fix: Separate on_submit and before_submit of PR
(cherry picked from commit dbd7b83204)
2024-10-07 16:17:05 +00:00
Abdeali Chharchhoda
677aadde7c fix: Remove unused function get_paid_amount_against_order
(cherry picked from commit 75916629c8)
2024-10-07 16:17:04 +00:00
Abdeali Chharchhoda
3a51cf4e1a fix: Remove unused field
(cherry picked from commit e785928c0f)

# Conflicts:
#	erpnext/accounts/doctype/payment_request/payment_request.json
2024-10-07 16:17:04 +00:00
Abdeali Chharchhoda
7d0a094515 test: Removed initial PR status assertion
(cherry picked from commit 67bd540135)
2024-10-07 16:17:03 +00:00
Abdeali Chharchhoda
8f5c191136 fix: Add removed test code b41f10c1b9
(cherry picked from commit 30fd11f138)
2024-10-07 16:17:02 +00:00
Abdeali Chharchhoda
d4421dade1 fix: Remove unreference method
(cherry picked from commit 770bc1c293)
2024-10-07 16:17:02 +00:00
Abdeali Chharchhoda
36b4f68566 fix: Remove advance_payment_status uses
(cherry picked from commit 907e3af1b0)
2024-10-07 16:17:02 +00:00
Abdeali Chharchhodawala
ef52be2f17 fix: multiple issues in Payment Request (#42427)
* fix: multiple issues in Payment Request

* chore: minor changes

* fix: remove  bug

* fix: replace `round` with `flt`

* fix: update `set_advance_payment_status()` logic

* fix: removed bug of `set_advance_payment_status`

* fix: changes as per review

* refactor: replace sql query of `matched_payment_requests` to query builder

* fix: replace `locals` with `get_doc` in set_query

* fix: changes during review

* fix: minor review changes

* fix: remove unnecessary code for setting payment entry received amount

* fix: logic for ser payment_request if PE made from transaction

* fix: Use rounded total to make Payment Request from `Sales Invoice` or `Purchase Invoice`

* refactor: enhance logic of `set_open_payment_requests_to_references`

* fix: added one optional arg `created_from_payment_request`

* fix: handle multiple allocation of PR at PE's reference

* fix: logic for PR if outstanding docs fetch

* fix: formatted Link field for `Payment Request` for PE's references

* fix: replace `get_all()` with `get_list()` for getting Payment Request for Link field

* fix: replace `get_all()` with `get_list()` for getting Payment Request for Link field

* chore: format `payment_entry.js` file

* style: Show preview popup of `Payment Request`

* fix: remove minor bug

* fix: add virtual field for Payment Term and Request `outstanding_amount` in PE's reference

* fix: get outstanding amount in PE's reference on realtime

* fix: move allocation of allocated_amount to server side (no change)

* fix: some minor changes to allocation

* fix: Split `Payment Request` if PE is created from PR and there are `Payment Terms`

* fix: minor logic changes

* fix: Allocation of allocated_amount if `paid_amount` is changes

* fix: improve logic of allocation

* fix: set matched payment request if unset

* fix: minor changes

* fix: Allocate single Payment Request if PE created from PR

* fix: improve code logic

* fix: Removed duplication code

* fix: proper message title

* refactor: Rename method of Allocation Amount to References

* refactor: Changing `grand_total` description based on `party_type`

* refactor: update Payment Request

* fix: Remove virtual property of payment_term_oustanding from references

* fix: fetch party account currency for creating payment request

* fix: use transaction currency as base in payment request

* fix: party amount for creating payment entry

* fix: allow for proportional amount paid by bank

* fix: Changed field order in Payment Request

* fix: Minor refactor in Payment Entry Reference table data

* test: Added test cases for allow Payment at `Partially Paid` status for PR

* test: Update partial paid status test case

* test: Update test case for same currency PR

* refactor: Wider the `msgprint` dialog for after save PE

* test: Update PR test cases

* chore: Remove dirty lines

* test: Checking `Advance Payment Status`

* fix: formatting update

* fix: Use `flt` where doing subtraction

* test: PR test case with Payment Term for same currency

* fix: remove redundant `flt`

* test: Add test cases for PR

---------

Co-authored-by: Sagar Vora <sagar@resilient.tech>
(cherry picked from commit ea69ba7cd8)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
#	erpnext/accounts/doctype/payment_entry/payment_entry.py
#	erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.json
#	erpnext/accounts/doctype/payment_entry_reference/payment_entry_reference.py
#	erpnext/accounts/doctype/payment_request/payment_request.json
#	erpnext/accounts/doctype/payment_request/payment_request.py
2024-10-07 16:17:01 +00:00
ljain112
2fc776d0f5 fix: create Account Closing Balance even though there are no transaction in period
(cherry picked from commit 43deaea96b)
2024-10-07 16:12:19 +00:00
ljain112
4586f03bdc fix: add parenttype condition for item table in Purchase Register Report
(cherry picked from commit 28abf191fc)
2024-10-07 15:55:42 +00:00
mergify[bot]
31ecdb2104 fix(Dunning): logic for fetching text (backport #43160) (#43489)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Dunning): logic for fetching text (#43160)
2024-10-03 20:28:59 +01:00
Sagar Vora
3b550ca419 Merge pull request #43484 from frappe/mergify/bp/version-14-hotfix/pr-43475
fix: set margin fields for purchase documents when updating items (backport #43475)
2024-10-02 15:24:03 +05:30
Sagar Vora
97edadfc4b fix: set margin fields for purchase documents when updating items
(cherry picked from commit 7be4d56be2)
2024-10-02 09:51:45 +00:00
Sagar Vora
824ccfb10c Merge pull request #43482 from frappe/mergify/bp/version-14-hotfix/pr-43481
fix: patch to update Currency Exchange Settings for `frankfurter.app` (backport #43481)
2024-10-02 15:14:46 +05:30
Sagar Vora
02ce528501 fix: conflicts 2024-10-02 15:14:16 +05:30
Sagar Vora
b4706db816 fix: patch to update Currency Exchange Settings for frankfurter.app
(cherry picked from commit c5889c5d2e)

# Conflicts:
#	erpnext/patches.txt
2024-10-02 09:43:14 +00:00
Sagar Vora
f608ba55ab Merge pull request #43477 from frappe/mergify/bp/version-14-hotfix/pr-43476
fix: Fix API endpoint for Frankfurter (backport #43476)
2024-10-02 14:43:07 +05:30
Sagar Vora
b18b4c1e35 test: update test for API change
(cherry picked from commit c444de017a)
2024-10-02 09:11:47 +00:00
Corentin Forler
1c0843caee fix: Fix API endpoint for Frankfurter
(cherry picked from commit 33e72111c7)
2024-10-02 09:11:47 +00:00
Nihantra C. Patel
7b158accec Merge pull request #43458 from frappe/mergify/bp/version-14-hotfix/pr-43455
fix: add company filter in Warehouse wise Item Balance Age and Value (backport #43455)
2024-10-01 11:46:54 +05:30
Nihantra Patel
3cb85028d0 fix: add company filter in Warehouse wise Item Balance Age and Value
(cherry picked from commit 75950f86cf)
2024-10-01 05:47:33 +00:00
rohitwaghchaure
619550942f Merge pull request #43439 from frappe/mergify/bp/version-14-hotfix/pr-43437
fix: adjustment entry for stock reco (backport #43437)
2024-09-30 15:38:09 +05:30
Rohit Waghchaure
57925a1315 fix: adjustmen entry for stock reco
(cherry picked from commit 4e463b7d6d)
2024-09-30 08:57:50 +00:00
rohitwaghchaure
a201c56b38 Merge pull request #43432 from frappe/mergify/bp/version-14-hotfix/pr-43420
fix: Stock Ledger Invariant Check report (backport #43420)
2024-09-30 13:39:47 +05:30
Rohit Waghchaure
44263842f5 fix: Stock Ledger Invariant Check report
(cherry picked from commit d7daedc5b2)
2024-09-29 17:07:35 +00:00
mergify[bot]
4146bdf324 fix(Bank Account): dashboard connections (backport #43365) (#43366)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
fix(Bank Account): dashboard connections (#43365)
2024-09-24 16:20:05 +02:00
ruthra kumar
c36b40ad8c Merge pull request #43363 from frappe/mergify/bp/version-14-hotfix/pr-43356
fix: AR / AP report to ignore 0.0 outstanding (backport #43356)
2024-09-24 16:58:26 +05:30
ruthra kumar
79f95ba507 fix: AR / AP report to ignore 0.0 outstanding
(cherry picked from commit 6e2cf79e2c)
2024-09-24 10:14:49 +00:00
Nihantra C. Patel
5ba9fb73bb Merge pull request #43342 from frappe/mergify/bp/version-14-hotfix/pr-43253
fix: partial return on POS invoice (backport #43253)
2024-09-23 23:36:25 +05:30
ruthra kumar
43ba79f0e5 Merge pull request #43299 from barredterra/de-payment-reco
fix(Payment Reconciliation): German translations
2024-09-23 20:03:02 +05:30
ruthra kumar
5ce4dae204 chore: resolve conflict 2024-09-23 20:02:10 +05:30
Nihantra C. Patel
50e0f56d18 fix: partial return on POS invoice
(cherry picked from commit 18bdd06652)

# Conflicts:
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.py
2024-09-23 14:26:05 +00:00
Nihantra C. Patel
ef7d4fe84a fix: partial return on POS invoice
(cherry picked from commit 76289fa8dc)

# Conflicts:
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.py
2024-09-23 14:26:05 +00:00
ruthra kumar
8f81fdba4f Merge pull request #43335 from frappe/mergify/bp/version-14-hotfix/pr-43316
fix: incorrect outstanding on non-pos invoice with write_off_account (backport #43316)
2024-09-23 18:22:39 +05:30
ruthra kumar
5434d4bb1c Merge pull request #43337 from frappe/mergify/bp/version-14-hotfix/pr-43308
fix: show chart tool tip in report currency (backport #43308)
2024-09-23 18:22:17 +05:30
ruthra kumar
54d0162fef Merge pull request #43339 from frappe/mergify/bp/version-14-hotfix/pr-43307
fix: change dynamic link doctype fieldtype to data (backport #43307)
2024-09-23 18:21:57 +05:30
venkat102
c0dfda6ccc fix: change dynamic link doctype fieldtype to data
(cherry picked from commit 1e46f7344a)
2024-09-23 12:23:01 +00:00
venkat102
6becaba672 fix: add currency in financial statement
(cherry picked from commit 91a27bda84)
2024-09-23 12:11:47 +00:00
venkat102
92438f8dba fix: show chart tool tip in report currency
(cherry picked from commit 827b3f4542)
2024-09-23 12:11:46 +00:00
ruthra kumar
79235cd688 fix: incorrect outstanding on non-pos invoice with write_off_account
(cherry picked from commit d5e2906e59)
2024-09-23 12:09:50 +00:00
barredterra
32d4f96e02 fix(Payment Reconciliation): German translations 2024-09-19 13:57:55 +02:00
mergify[bot]
1bdbcc6703 fix: incorrect stock balance for inventory dimension (backport #43284) (#43289)
* fix: incorrect stock balance for inventory dimension (#43284)

(cherry picked from commit 3e7a7a54bf)

# Conflicts:
#	erpnext/stock/report/stock_balance/stock_balance.js

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-09-19 10:20:58 +05:30
rohitwaghchaure
8abc1f4da9 fix: Serial No reserved against historical sales order - unable to sell again (#43294) 2024-09-19 09:37:08 +05:30
ruthra kumar
2e2a4d9c70 Merge pull request #43292 from frappe/mergify/bp/version-14-hotfix/pr-43274
fix: translate in js (backport #43274)
2024-09-19 09:01:04 +05:30
Doğancan
e43c357c08 fix: translate in js
(cherry picked from commit 25faec5662)
2024-09-19 03:27:14 +00:00
ruthra kumar
66349d0877 Merge pull request #43288 from frappe/mergify/bp/version-14-hotfix/pr-43213
fix: Payment Ledger Report currency fieldtype fix (backport #43213)
2024-09-19 08:50:19 +05:30
sameer Chauhan
7ac39dc233 fix: Payment Ledger Report currency fieldtype fix
(cherry picked from commit ad2d6a1625)
2024-09-19 01:36:31 +00:00
Nihantra C. Patel
02f414e0aa Merge pull request #43277 from frappe/mergify/bp/version-14-hotfix/pr-43276
fix: Translation for button SO to PO (backport #43276)
2024-09-18 21:49:31 +05:30
Nihantra C. Patel
b6ce9222aa fix: Translation for button SO to PO --conflicts 2024-09-18 21:47:30 +05:30
Nihantra C. Patel
a8b5bcfe02 fix: Translation for button SO to PO
(cherry picked from commit a5275e9f28)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.js
2024-09-18 16:14:06 +00:00
ruthra kumar
c442dc6b8e Merge pull request #43267 from frappe/mergify/bp/version-14-hotfix/pr-43239
fix: add currency in options for rate field in pricing rule (backport #43239)
2024-09-18 12:39:25 +05:30
ruthra kumar
fff8f8b83f chore: resolve conflict 2024-09-18 12:12:06 +05:30
krishna
c9467f4c1f fix: add currency in options for rate field in pricing rule
(cherry picked from commit 636c0131fa)

# Conflicts:
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.json
2024-09-18 06:29:34 +00:00
ruthra kumar
eed7eba695 Merge pull request #43265 from frappe/mergify/bp/version-14-hotfix/pr-43216
fix: get cost center allocation percentage only from the applicable allocation (backport #43216)
2024-09-18 11:40:10 +05:30
venkat102
4646f11829 fix: cancel cost center allocation and journal entry after test
(cherry picked from commit 3c65b98b49)
2024-09-18 05:49:31 +00:00
venkat102
872c150ea7 test: add unit test for validating multiple cost center allocation with different child cost center
(cherry picked from commit 4d5d6150e1)
2024-09-18 05:49:30 +00:00
venkat102
a26f0e9973 fix: fetch cost center allocation percentage only from the applicable allocation
(cherry picked from commit 36e5945c66)
2024-09-18 05:49:30 +00:00
ruthra kumar
dc6d3cca70 Merge pull request #43248 from frappe/mergify/bp/version-14-hotfix/pr-43188
fix: invalid gp calculation (backport #43188)
2024-09-17 14:35:06 +05:30
Dany Robert
9af2df3810 fix: invalid gp calculation
(cherry picked from commit c79851239c)
2024-09-17 06:33:14 +00:00
Smit Vora
84447caac7 Merge pull request #43240 from frappe/mergify/bp/version-14-hotfix/pr-43176
fix: hide and reset discount control on new POS order (backport #43176)
2024-09-16 20:01:15 +05:30
ljain112
5434432cfc fix: hide and reset discount control on new POS order
(cherry picked from commit 5b0053f8dd)
2024-09-16 14:25:19 +00:00
ruthra kumar
2193395072 Merge pull request #43201 from frappe/mergify/bp/version-14-hotfix/pr-43191
fix: delete exchange gain loss journal entry while deleting payment entry (backport #43191)
2024-09-13 11:22:56 +05:30
ruthra kumar
73821ac647 Merge pull request #43203 from frappe/mergify/bp/version-14-hotfix/pr-43192
refactor(test): use test fixture on pricing rule test suite (backport #43192)
2024-09-13 11:22:29 +05:30
ruthra kumar
2e323cc126 refactor(test): use test fixture on pricing rule test suite
(cherry picked from commit 0ea1d6d960)
2024-09-13 05:20:23 +00:00
Navin-S-R
95a66b8d8f test: add unit test for deletion of gain loss jv while deleting payment entry
(cherry picked from commit 7855d3034b)
2024-09-13 05:19:04 +00:00
Navin-S-R
62f12861f1 fix: delete exchange gain loss journal entry while deleting payment entry
(cherry picked from commit 9886cf0d46)
2024-09-13 05:19:03 +00:00
ruthra kumar
77bdf18c23 Merge pull request #43170 from frappe/mergify/copy/version-14-hotfix/pr-43169
refactor: enable no-copy on Purchase Invoice status (copy #43169)
2024-09-11 14:20:38 +05:30
ruthra kumar
097eae478d refactor: enable no-copy on Purchase Invoice status
(cherry picked from commit 0d9741fdd7)
2024-09-11 07:56:59 +00:00
mergify[bot]
91105344bb fix: bom cost update is not working (backport #43155) (#43156)
fix: bom cost update is not working (#43155)

(cherry picked from commit 05f9015c0b)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-09-10 23:07:52 +05:30
ruthra kumar
6895efe577 Merge pull request #43147 from frappe/mergify/bp/version-14-hotfix/pr-43144
feat: utility report for identifying invalid ledger entries (backport #43144)
2024-09-10 16:00:10 +05:30
ruthra kumar
2a890f9061 refactor: allow all accounts
(cherry picked from commit 43198c946b)
2024-09-10 09:06:14 +00:00
ruthra kumar
b2d361b495 refactor: fetch as dictionary
(cherry picked from commit 2126b10a92)
2024-09-10 09:06:14 +00:00
ruthra kumar
d51cf281c3 refactor: barebones methods with basic logic
(cherry picked from commit b05b378ef0)
2024-09-10 09:06:14 +00:00
ruthra kumar
3574d11946 refactor: standard filters
(cherry picked from commit dccbc1f432)
2024-09-10 09:06:14 +00:00
ruthra kumar
37b8715096 feat: utility report to identify invalid ledger entries
(cherry picked from commit 832c4aaf82)
2024-09-10 09:06:13 +00:00
mergify[bot]
e8aae5018a fix: return type of get_party_details (backport #43131) (#43135)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: return type of `get_party_details` (#43131)
2024-09-09 19:26:21 +02:00
mergify[bot]
a4b9dda4b2 fix: incorrect actual cost in Procurement Tracker report (backport #43109) (#43137)
fix: incorrect actual cost in Procurement Tracker report (#43109)

(cherry picked from commit 80f101f92e)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-09-09 20:35:14 +05:30
ruthra kumar
a5a0c0cb07 Merge pull request #43128 from frappe/mergify/bp/version-14-hotfix/pr-42801
fix(Delivery Note): translatability of validation errors (backport #42801)
2024-09-09 15:15:36 +05:30
barredterra
14ae3edc1d refactor: extract common validation method
(cherry picked from commit 08646b7ab7)
2024-09-09 09:14:01 +00:00
barredterra
5e33961448 fix(Delivery Note): translatability of validation errors
(cherry picked from commit 34df6e39dc)
2024-09-09 09:14:00 +00:00
ruthra kumar
2db15d7375 Merge pull request #43126 from frappe/mergify/bp/version-14-hotfix/pr-43051
fix: unreconcile allocation child table redirect url voucher no issue (backport #43051)
2024-09-09 14:34:11 +05:30
Prashant Kamble
53496ed79f fix: unreconcile allocation child table redirect url voucher no issue
(cherry picked from commit 5d6f6a2fb9)
2024-09-09 09:00:19 +00:00
ruthra kumar
4536e8bc47 Merge pull request #43124 from frappe/mergify/bp/version-14-hotfix/pr-43121
fix: set today in 'On This Date' in Available Batch Report (backport #43121)
2024-09-09 14:14:26 +05:30
Nihantra C. Patel
36f65fc592 fix: set today in 'On This Date' in Available Batch Report
(cherry picked from commit 9fd55e4c83)
2024-09-09 08:27:14 +00:00
ruthra kumar
c237f3c4c4 Merge pull request #43119 from frappe/mergify/bp/version-14-hotfix/pr-43095
fix: check multi-currency on jv for common party accounting with foreign currency (backport #43095)
2024-09-09 11:24:00 +05:30
ruthra kumar
cf78f9702c chore: resolve conflict 2024-09-09 11:01:54 +05:30
ruthra kumar
de0b8c07f6 refactor(test): use change_settings decorator
(cherry picked from commit ee94fb37c8)
2024-09-09 05:06:22 +00:00
venkat102
4dd06b69a1 fix: uncomment internal parties
(cherry picked from commit 454e18ad5f)
2024-09-09 05:06:21 +00:00
venkat102
b6f352a024 test: add unit test for common party with foreign currency
(cherry picked from commit 740a04a704)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2024-09-09 05:06:21 +00:00
venkat102
a3a40febf3 fix: check multi-currency on jv for common party accounting with foreign currency
(cherry picked from commit 00938bfd4d)
2024-09-09 05:06:21 +00:00
Smit Vora
6bfc8a0152 Merge pull request #43091 from frappe/mergify/bp/version-14-hotfix/pr-43013
fix: `default_advance_account` field in Process Payment Reconciliation (backport #43013)
2024-09-09 08:00:21 +05:30
Smit Vora
5113b0063e chore: resolve conflicts with backport 2024-09-09 06:58:34 +05:30
Smit Vora
9e77a0245a chore: resolve conflicts with backport 2024-09-09 06:51:30 +05:30
mergify[bot]
77892f4e24 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>
2024-09-07 17:34:22 +05:30
ruthra kumar
4bd7ce3e0b Merge pull request #43096 from frappe/mergify/bp/version-14-hotfix/pr-43077
fix: cancel common party advance jv while canceling the invoice (backport #43077)
2024-09-06 20:48:51 +05:30
venkat102
e7b17e05b0 test: add unit test for canceling the common party advance jv created from sales invoice
(cherry picked from commit 8c6e3f3c12)
2024-09-06 14:50:05 +00:00
venkat102
f5069524f3 fix: cancel common party advance jv while canceling the invoice
(cherry picked from commit 6a928b92df)
2024-09-06 14:50:04 +00:00
ruthra kumar
202ebbe140 refactor: fetch advance account on party seleection
(cherry picked from commit c4ed04cb31)
2024-09-06 09:48:47 +00:00
ljain112
3691a500eb fix: default_advance_account field in Process Payment Reconciliation
(cherry picked from commit 143209f91a)

# Conflicts:
#	erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.json
#	erpnext/accounts/doctype/process_payment_reconciliation/process_payment_reconciliation.py
2024-09-06 09:48:47 +00:00
ruthra kumar
f4032b64c9 Merge pull request #43073 from frappe/mergify/bp/version-14-hotfix/pr-43070
fix: AP filter to simulate employee advance as a ledger impacting voucher (backport #43070)
2024-09-06 10:09:21 +05:30
ruthra kumar
2913785bac refactor: filter to toggle employee advance scenario in AP
(cherry picked from commit 257e13c299)
2024-09-05 11:44:02 +00:00
ruthra kumar
3a57ef4c5f refactor: Handle Emp Advance as separate row in AP report
(cherry picked from commit eedf22b07a)
2024-09-05 11:44:02 +00:00
Smit Vora
ed185a6171 Merge pull request #43045 from frappe/mergify/bp/version-14-hotfix/pr-42988
fix: adjust price insertion logic for internal suppliers/customers (backport #42988)
2024-09-04 13:19:09 +05:30
Lakshit Jain
3912c688ac fix: adjust price insertion logic for internal suppliers/customers (#42988)
* fix: adjust price insertion logic for internal suppliers/customers

* refactor: correct indentation, specify conditions within function

* fix: typo

---------

Co-authored-by: Smit Vora <smitvora203@gmail.com>
(cherry picked from commit 38f925b376)
2024-09-04 07:26:53 +00:00
ruthra kumar
c7fb6e5f61 Merge pull request #43032 from frappe/mergify/bp/version-14-hotfix/pr-43030
fix: typerror on default_currency (backport #43030)
2024-09-03 16:51:31 +05:30
ruthra kumar
22b283d4a8 fix: typerror on default_currency
(cherry picked from commit 4a7cc4da87)
2024-09-03 11:11:30 +00:00
ruthra kumar
56b4e79305 Merge pull request #43027 from frappe/mergify/bp/version-14-hotfix/pr-42974
fix: retain date filter when redirecting in Profit and Loss report (backport #42974)
2024-09-03 15:51:57 +05:30
vishnu
e8cfb4d602 fix: indentation
(cherry picked from commit 598e9c1390)
2024-09-03 10:14:32 +00:00
vishnu
c87f2d2f7c fix: retain date filter when redirecting in Profit and Loss report
(cherry picked from commit bb29fc4c3d)
2024-09-03 10:14:32 +00:00
Khushi Rawat
ec00b2cf48 Merge pull request #42965 from frappe/mergify/bp/version-14-hotfix/pr-41845
fix: resolve gl entries duplication in asset purchase workflow (backport #41845)
2024-09-02 16:35:19 +05:30
mergify[bot]
c55f8e3388 fix: Discount and taxes in return document should follow the reference document (backport #41911) (#42573)
* fix: Discount and taxes in return document should follow the reference document (#41911)

* fix: Discount and taxes in return document should follow the reference document

* fix: Ignore Pricing rule on debit/credit note if created against PI/SI with test cases

* fix: linter issue

(cherry picked from commit 281198456d)

# Conflicts:
#	erpnext/controllers/sales_and_purchase_return.py

* fix: resolved conflict

---------

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-09-02 11:12:22 +05:30
Khushi Rawat
4951d01102 Merge pull request #42766 from frappe/mergify/bp/version-14-hotfix/pr-42765
fix: set up filters for dimensions (backport #42765)
2024-08-30 13:43:51 +05:30
ruthra kumar
a2d5024d3f Merge pull request #42984 from frappe/mergify/bp/version-14-hotfix/pr-42983
refactor: link utility report with bank reconciliation statement (backport #42983)
2024-08-29 16:16:37 +05:30
ruthra kumar
ef7a83c354 refactor: link utility report with bank reconciliation statement
(cherry picked from commit 00eac65712)
2024-08-29 10:42:52 +00:00
ruthra kumar
810bc65e30 Merge pull request #42980 from frappe/mergify/bp/version-14-hotfix/pr-42979
refactor: better UX on Bank Clearance tool (backport #42979)
2024-08-29 14:15:47 +05:30
ruthra kumar
cfb5a6592c chore: resolve conflict 2024-08-29 14:11:28 +05:30
ruthra kumar
9afbd43f05 refactor: better UX on Bank Clearance tool
(cherry picked from commit 6a06e26d04)

# Conflicts:
#	erpnext/accounts/doctype/bank_clearance/bank_clearance.js
2024-08-29 08:25:09 +00:00
Khushi Rawat
6fda0e8e1b chore: linters check 2024-08-28 15:22:07 +05:30
Nicolas Pereira
9db7f7b033 fix: default fiscal year in report v14 (#42960)
* loads the fiscal year from the calendar year

* loads the fiscal year from the calendar year

* loads the fiscal year from the calendar year

* loads the fiscal year from the calendar year

* fix: default fiscal year in report v14

* fix: default fiscal year in report v14 --prettier

---------

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-08-28 14:18:55 +05:30
ruthra kumar
82b2046805 Merge pull request #42967 from frappe/mergify/bp/version-14-hotfix/pr-42966
fix: typeerror on Payment Entry (backport #42966)
2024-08-28 13:27:24 +05:30
ruthra kumar
6cb9ae2035 chore: resolve conflict 2024-08-28 13:23:49 +05:30
ruthra kumar
dda4002da4 fix: typeerror on Payment Entry
(cherry picked from commit e9cf8937cd)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
2024-08-28 06:57:56 +00:00
Khushi Rawat
91bff147e0 chore: resolved conflicts 2024-08-28 12:05:25 +05:30
Khushi Rawat
b3c9697b7c fix: resolve gl entries duplication in asset purchase workflow (#41845)
* fix: resolve gl entries duplication in asset purchase workflow

* fix: prevent duplicate entry when creating purchase receipt from purchase invoice

* chore: test case added

* fix: fixed missing asset category issue

(cherry picked from commit 55a4bd469b)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/test_purchase_invoice.py
2024-08-28 06:29:56 +00:00
ruthra kumar
23c5edaf08 Merge pull request #42788 from kurogeek/fix-share_transfer-amount-currency-symbol
fix: share_transfer amount currency symbol field
2024-08-28 10:05:19 +05:30
Raffael Meyer
35c10fa97f Merge pull request #42671 from frappe/mergify/bp/version-14-hotfix/pr-42669
fix: german translations for incoterms (backport #42669)
2024-08-27 16:54:22 +02:00
ruthra kumar
10025a2c8d Merge pull request #42946 from frappe/mergify/bp/version-14-hotfix/pr-42923
fix: get amount with taxes and charges from payment entry (backport #42923)
2024-08-27 17:39:22 +05:30
ruthra kumar
813b699d5e Merge pull request #42948 from frappe/mergify/bp/version-14-hotfix/pr-42936
fix: remove unnecessary condition on 'voucher_no' (backport #42936)
2024-08-27 17:09:06 +05:30
ruthra kumar
94b09bb836 Merge pull request #42945 from frappe/mergify/bp/version-14-hotfix/pr-42453
fix: Update get_amount to return currency precision grand total (backport #42453)
2024-08-27 17:07:24 +05:30
ruthra kumar
ff14d72a46 fix: use of incorrect attribute
(cherry picked from commit fb32d2cafb)
2024-08-27 11:05:50 +00:00
Syed Mujeer Hashmi
0c2d7f2d9a fix: Update get_amount to return currency precision grand total
In case of multi-currency purchase invoice, we are getting the error "Total Payment Request amount cannot be greater than Purchase Invoice amount" because of rounding difference.

(cherry picked from commit 976abf7b3c)
2024-08-27 16:31:56 +05:30
venkat102
094411f5f0 fix: get amount with taxes and charges from payment entry
(cherry picked from commit b3a901b631)
2024-08-27 11:01:27 +00:00
mergify[bot]
c0b5f7c8eb fix: same posting date and time, creation causing incorrect balance qty (backport #42904) (#42919)
* fix: same posting date and time, creation causing incorrect balance qty (#42904)

fix: same posting date and time, creation causing incorrect balance quantity
(cherry picked from commit 27364b7e6b)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
#	erpnext/stock/stock_ledger.py

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-27 14:33:56 +05:30
mergify[bot]
73eab91631 fix: timeout while submitting stock entry (backport #42929) (#42930)
* fix: timeout while submitting stock entry (#42929)

(cherry picked from commit ca2fde891e)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-27 14:29:41 +05:30
mergify[bot]
2f4f2a8eec fix: unsupported operand type(s) for *: 'float' and 'NoneType' (backport #42916) (#42917)
fix: unsupported operand type(s) for *: 'float' and 'NoneType' (#42916)

(cherry picked from commit 10434742e9)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-27 09:30:01 +05:30
ruthra kumar
6a2210e46a Merge pull request #42914 from frappe/mergify/bp/version-14-hotfix/pr-42887
fix: update dimesions in exchange_gain_loss jv based on base document (backport #42887)
2024-08-26 17:56:18 +05:30
ljain112
820dcd79bb fix: update dimesions in exchange_gain_loss jv based on base document
(cherry picked from commit 96df19149d)
2024-08-26 12:01:01 +00:00
ruthra kumar
97205ce355 Merge pull request #42906 from frappe/mergify/bp/version-14-hotfix/pr-42905
refactor: better err msg on clearance tool (backport #42905)
2024-08-26 16:34:06 +05:30
ruthra kumar
8207b12f11 Merge pull request #42911 from frappe/mergify/bp/version-14-hotfix/pr-42910
feat: utility report to better diagnose incorrectly cleared Cheques and Deposits (backport #42910)
2024-08-26 16:32:41 +05:30
ruthra kumar
09946c7ea7 refactor: build dictionary for Journal
remove redundant filter

(cherry picked from commit 2144e0337d)
2024-08-26 10:11:09 +00:00
ruthra kumar
15aeec8a2d chore: remove redundant column
(cherry picked from commit 74b36db24e)
2024-08-26 10:11:09 +00:00
ruthra kumar
29fe7bea6d refactor: build dict for payment entry
(cherry picked from commit 784dec24c8)
2024-08-26 10:11:09 +00:00
ruthra kumar
c58987ba38 refactor: working state with minimum functions
(cherry picked from commit 4cd023444a)
2024-08-26 10:11:09 +00:00
ruthra kumar
ef93c96f43 refactor: barebones functions
(cherry picked from commit ceaa1be729)
2024-08-26 10:11:08 +00:00
ruthra kumar
c29b95e306 feat: report to identify incorrectly cleared cheques
(cherry picked from commit 28890fa833)
2024-08-26 10:11:08 +00:00
ruthra kumar
e6438b293d chore: resolve conflict 2024-08-26 15:30:53 +05:30
ruthra kumar
18a75fef9a refactor: better err msg on clearance tool
(cherry picked from commit 092411b54f)

# Conflicts:
#	erpnext/accounts/doctype/bank_clearance/bank_clearance.py
2024-08-26 08:55:01 +00:00
mergify[bot]
12d5e247c5 perf: data import for stock entries (backport #42711) (#42903)
* perf: data import for stock entries (#42711)

(cherry picked from commit 1511280464)

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

* chore: fix conflicts

* chore: fix linters issue

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-26 13:53:23 +05:30
Smit Vora
72cc42997b Merge pull request #42891 from frappe/mergify/bp/version-14-hotfix/pr-42848
fix: do not copy date fields in opportunity doctype (backport #42848)
2024-08-24 13:12:27 +05:30
Smit Vora
3a02800fbc chore: resolve conflicts 2024-08-24 12:38:11 +05:30
ruthra kumar
6cf248578f Merge pull request #42817 from frappe/mergify/bp/version-14-hotfix/pr-39481
fix: specify precision for net_amount (backport #39481)
2024-08-24 07:53:43 +05:30
ljain112
5186872b9b fix: do not copy date fields in opportunity doctype
(cherry picked from commit 74afa57a9f)

# Conflicts:
#	erpnext/crm/doctype/opportunity/opportunity.json
2024-08-23 08:48:29 +00:00
rohitwaghchaure
54842ea0b3 fix: stock reco with incorrect serial numbers (#42865) 2024-08-22 19:33:44 +05:30
ruthra kumar
a95a0524d9 Merge pull request #42870 from frappe/mergify/bp/version-14-hotfix/pr-42867
fix: call 'process' directly instead of creating 'process_subscription' (backport #42867)
2024-08-22 17:51:25 +05:30
ruthra kumar
dffd5f291d Merge pull request #42868 from frappe/mergify/bp/version-14-hotfix/pr-42851
refactor: Allow equity type Account in Payment Entry for shareholders (backport #42851)
2024-08-22 17:50:51 +05:30
ruthra kumar
164b417136 chore: resolve conflict 2024-08-22 17:34:31 +05:30
ruthra kumar
8412938442 fix: call 'process' directly instead of creating 'process_subscripti
reason: 'process' follows simple DB transaction model.
(cherry picked from commit b4d22c2936)
2024-08-22 11:53:32 +00:00
ruthra kumar
30ad25d86c refactor: filter shareholder on company
(cherry picked from commit 63ad9f4f86)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
2024-08-22 11:40:37 +00:00
ruthra kumar
651e853156 refactor: allow equity types on Payment Entry
(cherry picked from commit 6cbf98294a)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
2024-08-22 11:40:37 +00:00
ruthra kumar
c2fdef4d5b refactor(test): update grand total 2024-08-21 17:36:11 +05:30
ruthra kumar
678f08898a refactor(test): update tast case of rounding value 2024-08-21 15:26:47 +05:30
ruthra kumar
c5dedab304 chore: resolve conflicts 2024-08-19 13:53:29 +05:30
Dany Robert
cf34219c71 fix: specify precision for net_amount (#39481)
* fix: specify precision for net_amount

* fix: correct existing test to account for precision

* fix: rounding issue in test cases

* fix: optional grand total manipulation

* fix: use `grand_total_diff` for manipulation

* fix: patch to set default for grand total manipulation

* fix: wrong rounding assertion for USD

* fix: undefined this.frm error

* chore: linters

* fix: `net_amount` percision and method rename

* fix: missing frm reference

* chore: minor cleanups and depr message

* refactor: remove optional adjusting of grand total

(cherry picked from commit 50d56db0c2)

# Conflicts:
#	erpnext/public/js/controllers/accounts.js
#	erpnext/public/js/controllers/taxes_and_totals.js
2024-08-19 04:36:52 +00:00
ruthra kumar
752f93c630 Merge pull request #42793 from frappe/mergify/bp/version-14-hotfix/pr-42791
fix(patch): Use sql to update 'against_voucher' rather than reposting (backport #42791)
2024-08-16 15:55:22 +05:30
ruthra kumar
d14e386e18 chore: resolve conflict 2024-08-16 15:34:48 +05:30
ruthra kumar
9f687eee4e chore: update patches.txt
(cherry picked from commit 1721175a20)

# Conflicts:
#	erpnext/patches.txt
2024-08-16 10:02:34 +00:00
ruthra kumar
c98ab15a44 fix(patch): replace repost with direct sql to update 'against_voucher
(cherry picked from commit 13bb48434f)
2024-08-16 10:02:33 +00:00
kurogeek
333c7577eb fix: currency symbol on amount field suppose to show as Company's currency not as default company's currency 2024-08-16 13:52:54 +07:00
Khushi Rawat
ea7c82c6a3 chore: resolved conflicts 2024-08-15 13:12:38 +05:30
Nihantra C. Patel
54815b44e7 Merge pull request #42770 from frappe/mergify/bp/version-14-hotfix/pr-42769
fix: disable rename from warehouse (backport #42769)
2024-08-14 17:15:39 +05:30
Nihantra C. Patel
ed568fb01d fix: disable rename from warehouse 2024-08-14 16:35:34 +05:30
Nihantra C. Patel
a520d06c3f fix: disable rename from warehouse
(cherry picked from commit c1812f74e8)

# Conflicts:
#	erpnext/stock/doctype/warehouse/warehouse.json
2024-08-14 11:03:41 +00:00
Khushi Rawat
47a9325177 chore: linters check
(cherry picked from commit 0d42793397)

# Conflicts:
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
2024-08-14 09:07:34 +00:00
Khushi Rawat
db319f95f1 fix: removed extra filter condition
(cherry picked from commit 6fa29376a0)
2024-08-14 09:07:34 +00:00
Khushi Rawat
450b3f338e fix: set up filters for dimensions
(cherry picked from commit 2fd8de2f76)

# Conflicts:
#	erpnext/assets/doctype/asset_capitalization/asset_capitalization.js
2024-08-14 09:07:34 +00:00
ruthra kumar
695297b917 Merge pull request #42760 from frappe/mergify/bp/version-14-hotfix/pr-42720
fix: incorrect 'against_voucher' for Pos return with 'Update Outstanding for Self' disabled. (backport #42720)
2024-08-14 12:27:13 +05:30
ruthra kumar
8882b85888 chore: resolve conflict 2024-08-14 12:04:30 +05:30
ruthra kumar
1cddb4ff39 refactor: move patch to v14 and update patches.txt
(cherry picked from commit da2286802a)

# Conflicts:
#	erpnext/patches.txt
2024-08-14 06:26:35 +00:00
ruthra kumar
aaa6d66666 test: against_voucher for pos_returns without updating for self
(cherry picked from commit 3fb0858321)
2024-08-14 06:26:35 +00:00
ruthra kumar
fa44b0d745 refactor: update patches.txt
(cherry picked from commit 4dc0d3a003)

# Conflicts:
#	erpnext/patches.txt
2024-08-14 06:26:35 +00:00
ruthra kumar
54735469c1 fix: patch to fix incorrect against_voucher references in ledger
(cherry picked from commit 487d0a55f5)

# Conflicts:
#	erpnext/patches/v14_0/update_pos_return_ledger_entries.py
2024-08-14 06:26:34 +00:00
ruthra kumar
714a432c1c fix: ledger entries for pos return with update outstanding for self
(cherry picked from commit 2cd9b28e5b)
2024-08-14 06:26:34 +00:00
ruthra kumar
367b4177c6 Merge pull request #42748 from frappe/mergify/bp/version-14-hotfix/pr-42221
fix: Force Fetching updates on Subscriptions (backport #42221)
2024-08-13 17:24:50 +05:30
ruthra kumar
2d0dca943a chore: resolve conflict 2024-08-13 16:54:35 +05:30
ruthra kumar
456f5b644b Merge pull request #42740 from frappe/mergify/bp/version-14-hotfix/pr-42726
fix: text color in sales funnel report based on theme (backport #42726)
2024-08-13 16:49:01 +05:30
ruthra kumar
cca5aa8a96 chore: resolve conflict 2024-08-13 16:28:07 +05:30
ruthra kumar
366f383d1f refactor: test for force-fetch on future subscription
(cherry picked from commit fd680380bb)

# Conflicts:
#	erpnext/accounts/doctype/subscription/test_subscription.py
2024-08-13 10:53:15 +00:00
ruthra kumar
7752de3a1c chore: minor naming change
(cherry picked from commit d8b6767697)
2024-08-13 10:53:14 +00:00
ruthra kumar
f0f663e552 refactor: don't process future subscriptions
(cherry picked from commit 3a11577411)
2024-08-13 10:53:14 +00:00
ruthra kumar
f35bc43242 fix: force fetch updates for subcription
(cherry picked from commit 1ef890db73)

# Conflicts:
#	erpnext/accounts/doctype/subscription/subscription.js
2024-08-13 10:53:14 +00:00
ruthra kumar
b0b5b25a53 chore: resolve conflict 2024-08-13 14:38:44 +05:30
ljain112
25096185c9 fix: text color in sales funnel report based on theme
(cherry picked from commit 61bc0925d5)

# Conflicts:
#	erpnext/selling/page/sales_funnel/sales_funnel.js
2024-08-13 08:36:21 +00:00
ruthra kumar
a5b5b5e62c Merge pull request #42734 from frappe/mergify/bp/version-14-hotfix/pr-42733
refactor: add a new filter flag in Process Statement of Accounts (backport #42733)
2024-08-13 11:49:19 +05:30
ruthra kumar
e421e16fdc chore: resolve conflicts 2024-08-13 11:22:52 +05:30
ruthra kumar
cef3573d79 refactor: pass filter to General Ledger
(cherry picked from commit 90880c8c01)
2024-08-13 05:41:19 +00:00
ruthra kumar
1ebcc33cdd refactor: cr and dr note filter in Statement of Accounts
(cherry picked from commit 0cf478c4c2)

# 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
2024-08-13 05:41:19 +00:00
ruthra kumar
a9871e379a refactor: combine vouchers from both ignore
(cherry picked from commit 4cc5cd5a71)
2024-08-13 05:41:19 +00:00
ruthra kumar
34662e6e3c Merge pull request #42724 from frappe/mergify/bp/version-14-hotfix/pr-42672
fix: update 'Paid Amount' on forex payment request (backport #42672)
2024-08-12 16:36:28 +05:30
ruthra kumar
1844cb60a4 chore: resolve conflict 2024-08-12 16:14:29 +05:30
ruthra kumar
71416902f6 test: currency conversion on foreign currency account
(cherry picked from commit f913c0fde1)
2024-08-12 10:38:33 +00:00
ruthra kumar
e289793308 test: make use of test fixture
(cherry picked from commit d6d0a1b38d)

# Conflicts:
#	erpnext/accounts/doctype/payment_request/test_payment_request.py
2024-08-12 10:38:33 +00:00
ruthra kumar
365ef6b88a fix: update 'Paid Amount' on forex payment request
(cherry picked from commit 7b0dfb2a05)
2024-08-12 10:38:33 +00:00
mergify[bot]
e44daf73fb fix: warning message for negative stock (backport #42683) (#42709)
* fix: warning message for negative stock (#42683)

(cherry picked from commit deccb007c1)

# Conflicts:
#	erpnext/stock/stock_ledger.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-12 11:20:44 +05:30
ruthra kumar
a43136da5d Merge pull request #42694 from frappe/mergify/bp/version-14-hotfix/pr-42428
fix: Sort lists before calling itertools.groupby (backport #42428)
2024-08-09 12:44:24 +05:30
ruthra kumar
d0fbb4d532 Merge pull request #42692 from frappe/mergify/bp/version-14-hotfix/pr-42691
fix: typeerror on payment entry (backport #42691)
2024-08-09 11:55:49 +05:30
Corentin Forler
29cfb7cf25 fix: Sort lists before calling itertools.groupby
(cherry picked from commit 45a6ecbd38)
2024-08-09 06:23:57 +00:00
ruthra kumar
c4c001b6f9 fix: typeerror on payment entry
(cherry picked from commit 9cdca0d662)
2024-08-09 11:53:35 +05:30
Raffael Meyer
93d8e3f3b0 Merge pull request #42687 from frappe/mergify/bp/version-14-hotfix/pr-42684
fix: german translation of exit (backport #42684)
2024-08-08 23:25:58 +02:00
barredterra
db27dd8702 fix: german translation of exit
(cherry picked from commit a2df276880)
2024-08-08 21:15:03 +00:00
ruthra kumar
cc97d4e869 Merge pull request #42651 from frappe/mergify/bp/version-14-hotfix/pr-40865
fix: missing def expense if no exp in first month (backport #40865)
2024-08-08 14:37:39 +05:30
ruthra kumar
eb26610d54 Merge pull request #42677 from frappe/mergify/bp/version-14-hotfix/pr-42673
fix: Maintain same rate on qty change on Quotation to Sales Order (backport #42673)
2024-08-08 13:37:48 +05:30
ruthra kumar
29449cbaf9 fix: Maintain same rate on qty change on Quotation to Sales Order
(cherry picked from commit 91ce9fce9b)
2024-08-08 08:03:37 +00:00
Shariq Ansari
f29cad695a Merge pull request #42667 from frappe/mergify/bp/version-14-hotfix/pr-42596
fix: changes in opportunity.py to show contacts and addresses created from opportunity (backport #42596)
2024-08-08 11:39:47 +05:30
barredterra
003653c572 fix: german translations for incoterms
(cherry picked from commit 9789648175)
2024-08-07 18:54:36 +00:00
Dietmar Fischer
8f19832aa5 fix: pre-commit for better code formatting
(cherry picked from commit 511a0b9f37)
2024-08-07 14:29:48 +00:00
Dietmar Fischer
8d7e150afb feat: changes in opportunity.py to show contacts and addresses from referenced and opportunities
(cherry picked from commit 61576ca030)
2024-08-07 14:29:48 +00:00
ruthra kumar
4a77653e94 Merge pull request #42660 from frappe/mergify/bp/version-14-hotfix/pr-42578
fix: dimensions in common party journal entry (backport #42578)
2024-08-07 16:23:45 +05:30
ruthra kumar
fa74efc1fc test: dimension inheritance on Exc Gain/Loss JV on Common party
(cherry picked from commit 8040544216)
2024-08-07 10:33:23 +00:00
ljain112
b73df8f5f0 fix: dimensions in common party journal entry
(cherry picked from commit ac629ede79)
2024-08-07 10:33:22 +00:00
Khushi Rawat
f4811c3846 Merge pull request #42629 from khushi8112/depreciation-adjustment-issue-when-field-for-income-tax-enabled
fix: depreciation calculation as per income tax act
2024-08-06 19:15:03 +05:30
Dany Robert
a9fa9e86ea fix: expense causing p&l test case to fail
(cherry picked from commit 01888c98bc)
2024-08-06 11:01:41 +00:00
Dany Robert
c67be05280 chore: semgrep
(cherry picked from commit 581af4eced)
2024-08-06 11:01:41 +00:00
Dany Robert
186701b54f fix: test case for zero deferred expense
(cherry picked from commit 7ef4dbcaf6)
2024-08-06 11:01:41 +00:00
Dany Robert
7cd6debd0e fix: missing def expense if no exp in first month
(cherry picked from commit 5c9ce575f6)
2024-08-06 11:01:41 +00:00
Nihantra C. Patel
f8fd354d75 Merge pull request #42650 from Nihantra-Patel/fix_item_sales_purchase_register
fix: item_code filter in item-wise sales-purchase register v14
2024-08-06 16:19:16 +05:30
Nihantra Patel
bc9b46126b fix: filter condition in item-wise purchase register 2024-08-06 15:56:00 +05:30
Nihantra Patel
f0f8a2f01b fix: item_code filter in item-wise sales register 2024-08-06 15:54:05 +05:30
mergify[bot]
83928bbf78 feat: expiry date column in Available Batch Report (backport #42628) (#42641)
* feat: expiry date column in Available Batch Report (#42628)

(cherry picked from commit faff84c6e5)

# Conflicts:
#	erpnext/stock/report/available_batch_report/available_batch_report.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-06 15:24:37 +05:30
ruthra kumar
bc50512c97 Merge pull request #42645 from frappe/mergify/bp/version-14-hotfix/pr-42592
fix: company filter for filtring tax withheld vouchers (backport #42592)
2024-08-06 13:39:17 +05:30
ljain112
b7731c8fd7 fix: company filter for filtring tax withheld vouchers
(cherry picked from commit cfe2ae604b)
2024-08-06 07:47:21 +00:00
ruthra kumar
8667bcd86b Merge pull request #42643 from frappe/mergify/bp/version-14-hotfix/pr-42545
fix: min height for rows in sales funnel (backport #42545)
2024-08-06 13:09:39 +05:30
ljain112
7086a96462 fix: min height for rows in sales funnel
(cherry picked from commit fd71d8af52)
2024-08-06 07:33:07 +00:00
ruthra kumar
2a38e14cca Merge pull request #42637 from frappe/mergify/bp/version-14-hotfix/pr-42636
refactor: posting date should not be considered for ignore filters in GL (backport #42636)
2024-08-06 11:43:54 +05:30
ruthra kumar
f4ba879203 refactor: posting date is not considered for ignore filters in GL
(cherry picked from commit c930f8ba9d)
2024-08-06 05:26:26 +00:00
mergify[bot]
5c5349ed16 fix: do not update item price and last purchase rate for inter transf… (backport #42616) (#42632)
fix: do not update item price and last purchase rate for inter transf… (#42616)

fix: do not update item price and last purchase rate for inter transfer transaction
(cherry picked from commit c8af544ef3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-08-06 08:19:46 +05:30
Khushi Rawat
8df1079618 fix: fixed depreciation calculation as per income tax act 2024-08-05 18:04:06 +05:30
Khushi Rawat
38739bec45 Merge pull request #42630 from khushi8112/fix-semgrep
ci: fix semgrep version in linters
2024-08-05 18:01:50 +05:30
Khushi Rawat
6ceb3476a6 ci: fix semgrep version in linters 2024-08-05 17:37:29 +05:30
ruthra kumar
6cba69c7da Merge pull request #42625 from frappe/mergify/bp/version-14-hotfix/pr-42555
refactor: date filters should be mandatory in Sales Pipeline Analytics report (backport #42555)
2024-08-05 15:32:28 +05:30
ruthra kumar
ffd3aea07e refactor(test): use test fixture and supply from and to dates
(cherry picked from commit 4253caf910)
2024-08-05 09:39:27 +00:00
ruthra kumar
989ef52f59 refactor: consider empty-string as Not Assigned
(cherry picked from commit 213b2ba942)
2024-08-05 09:39:27 +00:00
ruthra kumar
baa36c6d5e refactor: report columns should be based on from and to dates
(cherry picked from commit 751a25c4b7)
2024-08-05 09:39:27 +00:00
ruthra kumar
f7f191fe50 refactor: make 'from_date' and 'to_date' mandatory
(cherry picked from commit 3617b41b95)
2024-08-05 09:39:27 +00:00
ruthra kumar
703f58ceac refactor: date filters should be explicit
(cherry picked from commit 40c166a0a0)
2024-08-05 09:39:27 +00:00
ruthra kumar
e1da019fe7 Merge pull request #42613 from frappe/mergify/bp/version-14-hotfix/pr-42597
refactor: filter to ignore system generated cr / dr reconciliation journals on general ledger (backport #42597)
2024-08-05 13:20:25 +05:30
ruthra kumar
f0bdc41a94 refactor(test): clear old records 2024-08-05 12:58:21 +05:30
ruthra kumar
392ba36dcf refactor(test): filter and reconcile concerned vouchers
(cherry picked from commit 9ade269b7a)
2024-08-05 05:43:50 +00:00
ruthra kumar
1b6539c3c5 test: clear old data
(cherry picked from commit 991069bfbc)
2024-08-05 05:43:50 +00:00
ruthra kumar
1da744dc4d refactor: make use of date filters on ignore filterss
(cherry picked from commit 03f3ab522f)
2024-08-05 05:43:50 +00:00
ruthra kumar
ac763f8c19 test: ignore filter for system generated cr / dr note journals
(cherry picked from commit 3ffac73598)
2024-08-05 05:43:50 +00:00
ruthra kumar
0a83c8b00c refactor: ignore system generated cr / dr notes on general ledger
(cherry picked from commit bb8c9b5a58)
2024-08-05 05:43:50 +00:00
ruthra kumar
b20b15af74 refactor: ignore filter in general ledger for cr / dr notes
(cherry picked from commit 59d5beee20)
2024-08-05 05:43:50 +00:00
mergify[bot]
3fb6f97f66 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>
2024-08-01 13:21:37 +05:30
ruthra kumar
35f6657bae Merge pull request #42565 from frappe/mergify/bp/version-14-hotfix/pr-42563
fix: set query filters for sales / purchase tax template on PE (backport #42563)
2024-07-31 17:28:45 +05:30
ruthra kumar
e82c441326 chore: resolve conflict 2024-07-31 17:14:26 +05:30
ruthra kumar
c8d85364b9 fix: set query filters for sales / purchase tax template on PE
(cherry picked from commit 9fe47ac101)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
2024-07-31 11:39:09 +00:00
ruthra kumar
64234a571e Merge pull request #42559 from frappe/mergify/bp/version-14-hotfix/pr-42558
fix: 'undefined' in PL and BS report summary on Consolidated report (backport #42558)
2024-07-31 16:19:17 +05:30
ruthra kumar
a5e14324da fix: 'undefined' in PL and BS report summary on Consolidated report
(cherry picked from commit dd5a5e4919)
2024-07-31 10:03:56 +00:00
mergify[bot]
53034c332b fix: dynamic condition in the pricing rule not working (backport #42467) (#42543)
fix: dynamic condition in the pricing rule not working (#42467)

(cherry picked from commit 0e817f42ef)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 17:01:24 +05:30
mergify[bot]
0441984405 fix: warehouse filter in Product Bundle Balance (backport #42532) (#42536)
fix: warehouse filter in Product Bundle Balance (#42532)

(cherry picked from commit 0ecfa709d8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 14:53:31 +05:30
mergify[bot]
3ba6f40063 fix: price_list_currency not found error (backport #42534) (#42538)
fix: price_list_currency not found error (#42534)

(cherry picked from commit 23fed831a0)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 14:52:45 +05:30
mergify[bot]
8e8d0c7bd0 fix: keep status as In Progress for RIV for Timeout Error (backport #42274) (#42504)
* fix: keep status as In Progress for RIV for Timeout Error (#42274)

(cherry picked from commit 10280d6140)

# Conflicts:
#	erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 14:25:51 +05:30
mergify[bot]
f42f1bb35f fix: performance issue for the report Purchase Order Analysis report (backport #42503) (#42506)
* fix: performance issue for the report Purchase Order Analysis report (#42503)

(cherry picked from commit cb522f8f22)

# Conflicts:
#	erpnext/buying/report/purchase_order_analysis/purchase_order_analysis.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 14:25:23 +05:30
mergify[bot]
0256c64634 fix: builtins.KeyError: ('ABC', 'Store - CP') (backport #42505) (#42508)
fix: builtins.KeyError: ('ABC', 'Store - CP') (#42505)

(cherry picked from commit 25dac1f18e)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-30 14:25:01 +05:30
ruthra kumar
e4f583d25a Merge pull request #42529 from frappe/mergify/bp/version-14-hotfix/pr-42528
chore: button name should reflect what it creates (backport #42528)
2024-07-30 12:12:32 +05:30
ruthra kumar
7259c0fe30 chore: button name should reflect what it creates
(cherry picked from commit 0b6e7f83cd)
2024-07-30 06:31:17 +00:00
ruthra kumar
02547115e5 Merge pull request #42335 from frappe/mergify/bp/version-14-hotfix/pr-42330
fix: incorrect valuation rate for items from different warehouses in Gross Profit (backport #42330)
2024-07-29 10:17:04 +05:30
ruthra kumar
0bc9825238 Merge pull request #42491 from frappe/mergify/bp/version-14-hotfix/pr-42477
fix: incorrect cost_center on AR/AP report (backport #42477)
2024-07-26 20:10:43 +05:30
ruthra kumar
bb66126dfa test: invoice cost center reported in AR/AP report
(cherry picked from commit 9a0894fd65)
2024-07-26 14:14:32 +00:00
ruthra kumar
0e2abbd08e fix: incorrect cost_center on AR/AP report
(cherry picked from commit 3e19041fa3)
2024-07-26 14:14:32 +00:00
Smit Vora
ff78fab176 Merge pull request #42483 from frappe/mergify/bp/version-14-hotfix/pr-42305
fix: consider payment entries for checking if tds is deducted (backport #42305)
2024-07-26 15:17:05 +05:30
Smit Vora
04840762dd Merge pull request #42481 from frappe/mergify/bp/version-14-hotfix/pr-42444
fix: parenttype in purchase and sales item query (backport #42444)
2024-07-26 15:16:44 +05:30
ljain112
e7432fc60d fix: consider payment entries for checking if tds is deducted
(cherry picked from commit 40b59de4cd)
2024-07-26 09:11:50 +00:00
ljain112
97f2e88f4c fix: parenttype in item wise purchase and sales register
(cherry picked from commit 35981b8730)
2024-07-26 08:56:42 +00:00
ruthra kumar
37f24ae763 Merge pull request #42473 from frappe/mergify/bp/version-14-hotfix/pr-42472
refactor: index on Purchase Invoice 'release_date' (backport #42472)
2024-07-25 21:51:16 +05:30
ruthra kumar
25b9127bae refactor: index on Purchase Invoice 'release_date'
(cherry picked from commit 764dd12b10)
2024-07-25 15:57:59 +00:00
ruthra kumar
6e74e6f314 Merge pull request #42464 from frappe/mergify/bp/version-14-hotfix/pr-42462
refactor: provision for re-evaluating Exchange Rates in monthly frequency (backport #42462)
2024-07-24 22:11:22 +05:30
ruthra kumar
240118ee8b chore: resolve conflict 2024-07-24 18:48:32 +05:30
ruthra kumar
c1fd95ac66 refactor: hooks for monthly re-evaluation jobs
(cherry picked from commit fc4e5f165c)

# Conflicts:
#	erpnext/hooks.py
2024-07-24 13:15:15 +00:00
ruthra kumar
8e340bb7fd refactor: provision for monthly re-evaluation
(cherry picked from commit ce2b9e0f1a)

# Conflicts:
#	erpnext/setup/doctype/company/company.json
#	erpnext/setup/doctype/company/company.py
2024-07-24 13:15:15 +00:00
ruthra kumar
96a6172999 Merge pull request #42455 from frappe/mergify/bp/version-14-hotfix/pr-42390
refactor: cleaning up stale code related to reposting (backport #42390)
2024-07-24 17:35:24 +05:30
Smit Vora
d0d587432d Merge pull request #42439 from frappe/mergify/bp/version-14-hotfix/pr-42377
fix: ignore duplicates while creating default templates (backport #42377)
2024-07-24 14:25:46 +05:30
ruthra kumar
07509b5e99 chore: resolve conflicts 2024-07-24 13:07:15 +05:30
ruthra kumar
99d5b6dc71 chore: resolve conflicts 2024-07-24 13:04:57 +05:30
ruthra kumar
56b1582027 refactor(test): remove assert on 'repost_required'
(cherry picked from commit e71cb4eab7)
2024-07-24 07:29:10 +00:00
ruthra kumar
149109649d refactor: remove attribute check on 'repost_required'
(cherry picked from commit 07fc952a43)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.py
2024-07-24 07:29:09 +00:00
ruthra kumar
0284328e2c refactor: repost without checking on flag
(cherry picked from commit 09f429ffba)
2024-07-24 07:29:09 +00:00
ruthra kumar
a243873ab0 chore: remove stale UI code related to repost
(cherry picked from commit fe46e1d089)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
2024-07-24 07:29:09 +00:00
ruthra kumar
197e043fc9 chore: remove 'repost_required' from Journal Entry
(cherry picked from commit e81373bb6a)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/journal_entry.json
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
2024-07-24 07:29:09 +00:00
ruthra kumar
925a164101 chore: remove 'repost_required' from purchase invoice
(cherry picked from commit a467888a67)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
2024-07-24 07:29:08 +00:00
ruthra kumar
8f1a4b9717 chore: remove stale 'repost_required' flag from sales invoice
(cherry picked from commit 06c5334f2a)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.py
2024-07-24 07:29:08 +00:00
ruthra kumar
67d4020241 chore: remove stale code from sales invoice
(cherry picked from commit f3fda9ce98)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2024-07-24 07:29:08 +00:00
Smit Vora
99bc8e849c fix: ignore duplicates while creating default templates
(cherry picked from commit cf55c2ab3d)
2024-07-23 04:56:31 +00:00
ruthra kumar
7a25d33547 Merge pull request #42408 from frappe/mergify/bp/version-14-hotfix/pr-42407
test: basic test case for item-wise purchase register (backport #42407)
2024-07-21 20:08:19 +05:30
ruthra kumar
2466e28bf5 test: basic test case for item-wise purchase register
(cherry picked from commit c3c5d3f615)
2024-07-19 11:21:08 +00:00
ruthra kumar
1096528bb9 Merge pull request #42401 from frappe/mergify/bp/version-14-hotfix/pr-42386
fix: set pos data if not return doc (backport #42386)
2024-07-19 10:57:20 +05:30
ljain112
6ecb064264 fix: set pos data if not return doc
(cherry picked from commit 65d672da65)
2024-07-19 04:56:26 +00:00
ruthra kumar
92300b27c9 Merge pull request #42384 from frappe/mergify/bp/version-14-hotfix/pr-42374
fix: Show the rows in AR/AP report where outstanding equals to 0.01 (backport #42374)
2024-07-18 15:08:55 +05:30
ruthra kumar
4fa9626de0 chore: resolve conflict 2024-07-18 14:41:09 +05:30
ruthra kumar
9b828b829a test: AR/AP report on miniscule outstanding
(cherry picked from commit bb9e42cce2)
2024-07-18 08:15:39 +00:00
Nabin Hait
2936988cc6 fix: Show the rows in AR/AP report where outstanding equals to 0.01
(cherry picked from commit e1dedc5402)

# Conflicts:
#	erpnext/patches.txt
2024-07-18 08:15:38 +00:00
ruthra kumar
9fca232578 Merge pull request #42382 from frappe/mergify/bp/version-14-hotfix/pr-42369
fix: missing cr/dr notes on payment reconciliation (backport #42369)
2024-07-18 13:43:36 +05:30
ruthra kumar
fac22e93d0 chore: resolve conflict 2024-07-18 12:44:34 +05:30
ruthra kumar
3109efaf09 test: payment filter should not affect dr/cr notes
(cherry picked from commit 2d686c06ea)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation/test_payment_reconciliation.py
2024-07-18 07:12:45 +00:00
ruthra kumar
90ee21f868 fix: missing cr/dr notes on payment reconciliation
(cherry picked from commit a30af68e9e)
2024-07-18 07:12:45 +00:00
Smit Vora
36c46bb344 Merge pull request #42366 from vorasmit/update-prop-backport
fix: remove redundant proprietorship field from customer type and supplier type (backport #42307)
2024-07-17 18:55:40 +05:30
Sanket322
8c1f6196b8 fix: remove proprietorship and update it with individual (backport #42307) 2024-07-17 14:03:52 +05:30
ruthra kumar
2ce7300c3c Merge pull request #42337 from frappe/mergify/bp/version-14-hotfix/pr-42294
refactor: make reposting implicit (backport #42294)
2024-07-15 15:41:23 +05:30
ruthra kumar
b96b3b51b6 chore: resolve conflicts 2024-07-15 15:22:06 +05:30
ruthra kumar
8f03769bf2 chore: contextual comments
(cherry picked from commit 794a62aecb)
2024-07-15 09:41:56 +00:00
ruthra kumar
d20f3ab492 refactor(test): reposting happens implicitly
(cherry picked from commit c283cda169)
2024-07-15 09:41:56 +00:00
ruthra kumar
980ca1d8c5 refactor(test): no need to assert repost_required flag
Reposting happens implicitly upon 'Update After Submit'

(cherry picked from commit 8f135e9859)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/test_journal_entry.py
2024-07-15 09:41:56 +00:00
ruthra kumar
4668a2d7d8 refactor: make reposting implicit
(cherry picked from commit 722ef92324)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
2024-07-15 09:41:56 +00:00
ruthra kumar
1a7efbb654 fix(gross profit): incorrect valuation rate on different warehouses
(cherry picked from commit f9d2dd0a62)
2024-07-15 08:50:15 +00:00
ruthra kumar
ccc2a47e73 Merge pull request #42290 from frappe/mergify/bp/version-14-hotfix/pr-42192
refactor: tests for item wise sales register report (backport #42192)
2024-07-12 09:28:05 +05:30
ruthra kumar
f98716cc2a refactor(test): clear old records 2024-07-11 21:03:29 +05:30
ruthra kumar
7903e8d669 refactor(test): use each instance UOM for assertion
(cherry picked from commit cf4fbfb601)
2024-07-11 12:34:13 +00:00
ruthra kumar
9a50a0a129 refactor: test suite for item-wise sales register
(cherry picked from commit 3aaa22e672)
2024-07-11 12:34:12 +00:00
ruthra kumar
1646517dc4 chore: rename test suite for payable report
(cherry picked from commit 9474f72776)
2024-07-11 12:34:12 +00:00
ruthra kumar
38811e792c Merge pull request #42288 from frappe/mergify/bp/version-14-hotfix/pr-42287
fix: missing discount on POS Credit Notes (backport #42287)
2024-07-11 17:33:26 +05:30
ruthra kumar
edfb408464 chore: resolve conflict 2024-07-11 17:31:20 +05:30
ruthra kumar
ac48c3d4e7 fix: missing discount on POS Credit Notes
(cherry picked from commit 1049550951)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2024-07-11 11:58:57 +00:00
ruthra kumar
5c75bb8775 Merge pull request #42271 from frappe/mergify/bp/version-14-hotfix/pr-42247
fix: don't merge tax into stock account on purchase receipt repost (backport #42247)
2024-07-10 15:52:00 +05:30
ruthra kumar
115a0123ed chore: resolve conflict 2024-07-10 15:30:24 +05:30
ruthra kumar
fdf1dfe46e test: tax account heads on PR report without LCV
(cherry picked from commit 9562628ed6)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-07-10 09:58:30 +00:00
ruthra kumar
106c154a16 fix: tax on stock_rbnb on repost of Purchase Receipt
(cherry picked from commit 8633080dff)
2024-07-10 09:58:30 +00:00
Smit Vora
00e8b862dd Merge pull request #42264 from frappe/mergify/bp/version-14-hotfix/pr-42127
fix: removed max discount validation for sales return (backport #42127)
2024-07-10 15:22:51 +05:30
ljain112
4195c50f02 fix: removed max discount validation for sales return
(cherry picked from commit db807d433b)
2024-07-10 07:01:54 +00:00
Smit Vora
fdb8e5b379 Merge pull request #42262 from ljain112/fix-tds-backport
fix(tds): use doctype reference when mapping keys across multiple doctype (backport #42258)
2024-07-10 12:27:28 +05:30
ljain112
51cbbee4ca fix(tds): use doctype reference when mapping keys across multiple doctypes 2024-07-10 11:55:35 +05:30
Sagar Vora
5000c09759 Merge pull request #42261 from frappe/mergify/bp/version-14-hotfix/pr-42060
fix: updated logic for calculating tax_withholding_net_total in payment entry (backport #42060)
2024-07-10 11:24:31 +05:30
ljain112
49e50662b6 fix: updated logic for calculating tax_withholding_net_total in payment entry
(cherry picked from commit c8a34cde7f)
2024-07-10 05:53:37 +00:00
ruthra kumar
f2f1f32826 Merge pull request #42163 from frappe/mergify/bp/version-14-hotfix/pr-42162
refactor: remove obsolete function call (backport #42162)
2024-07-10 10:28:37 +05:30
mergify[bot]
fcf6500144 fix(Holiday List): sort holidays on save to avoid disorienting the user (backport #42236) (#42251)
* fix(Holiday List): sort holidays on save to avoid disorienting the user (#42236)

fix: sort holidays on save to avoid disorienting the user
(cherry picked from commit ad137250fc)

# Conflicts:
#	erpnext/setup/doctype/holiday_list/holiday_list.py

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-07-09 18:44:08 +05:30
Raffael Meyer
f2d5a69af4 Merge pull request #42237 from frappe/mergify/bp/version-14-hotfix/pr-42235
fix: add missing german translations (backport #42235)
2024-07-08 19:53:18 +02:00
barredterra
d5c1c62622 fix: add missing german translations
(cherry picked from commit 2f89461ace)
2024-07-08 17:51:41 +00:00
mergify[bot]
e2f8e02c73 fix: stock qty validation in SCR (backport #42124) (#42224)
* fix: stock qty validation in SCR (#42124)

(cherry picked from commit 99f2735ad3)

# Conflicts:
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-08 17:06:23 +05:30
ruthra kumar
e9357c193d Merge pull request #42184 from frappe/mergify/bp/version-14-hotfix/pr-42183
fix: empty item-wise sales/purchase register reports on initial load (backport #42183)
2024-07-04 15:10:30 +05:30
ruthra kumar
13895fa060 fix: empty item-wise sales/purchase register reports on initial load
(cherry picked from commit ee862126e4)
2024-07-04 09:36:58 +00:00
ruthra kumar
64f8498576 Merge pull request #42180 from frappe/mergify/bp/version-14-hotfix/pr-41975
fix: group by in item-wise purchase register (backport #41975)
2024-07-04 14:59:50 +05:30
Nihantra C. Patel
62ad466a3b fix: group by in item-wise purchase register
(cherry picked from commit 3fab00135b)
2024-07-04 09:09:07 +00:00
Khushi Rawat
45899b3017 Merge pull request #42174 from khushi8112/fetch-expence-account-from-asset-category
fix: fetch expense account from asset category
2024-07-04 13:14:39 +05:30
ruthra kumar
d92a042bf7 Merge pull request #42172 from frappe/mergify/bp/version-14-hotfix/pr-42143
refactor: validation to prevent recursion with mixed conditions (backport #42143)
2024-07-04 09:20:35 +05:30
Khushi Rawat
4d6a71ab4b fix: fetch expence account from asset category 2024-07-04 01:45:01 +05:30
ruthra kumar
d5fa968078 chore: resolve conflicts 2024-07-03 20:59:27 +05:30
ruthra kumar
71cbebd31b test: validation on mixed condition and recursion on pricing rule
(cherry picked from commit eb4af58bf0)

# Conflicts:
#	erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
2024-07-03 15:26:56 +00:00
ruthra kumar
99317768f6 test: validation on mixed condition with recursion
(cherry picked from commit 9bd4e7b709)

# Conflicts:
#	erpnext/accounts/doctype/promotional_scheme/test_promotional_scheme.py
2024-07-03 15:26:56 +00:00
ruthra kumar
9fde7330e0 fix: use standard method to get _doc_before_save
(cherry picked from commit 9d7be293ae)
2024-07-03 15:26:56 +00:00
ruthra kumar
49fb6bec6a refactor: validation to prevent recursion with mixed conditions
(cherry picked from commit 406dfd528f)
2024-07-03 15:26:55 +00:00
ruthra kumar
0f1f5b6f3d Merge pull request #42169 from frappe/mergify/bp/version-14-hotfix/pr-42165
fix: multiple free items on same Item Group (backport #42165)
2024-07-03 20:55:34 +05:30
mergify[bot]
454e147592 fix: manual pick allow to pick more than available stock (backport #42155) (#42158)
* fix: manual pick allow to pick more than available stock (#42155)

(cherry picked from commit 938dd4b2aa)

# Conflicts:
#	erpnext/stock/doctype/pick_list/test_pick_list.py

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-07-03 19:28:18 +05:30
ruthra kumar
701dd9e19b fix: multiple free items on same Item Group
(cherry picked from commit c4ae0d283f)
2024-07-03 12:28:35 +00:00
Markus Lobedann
2cf82561f6 refactor: remove obsolete function call (#42162)
(cherry picked from commit 4512432816)
2024-07-03 10:22:23 +00:00
ruthra kumar
26c99351fd Merge pull request #42150 from frappe/mergify/bp/version-14-hotfix/pr-42073
fix: always post to tax account heads if LCV is booked (backport #42073)
2024-07-03 07:44:36 +05:30
ruthra kumar
4d99449aa8 chore: resolve conflict 2024-07-03 07:16:08 +05:30
ruthra kumar
72b93805fd refactor(test): fix flaky test
(cherry picked from commit 0e256b8b29)
2024-07-03 01:34:50 +00:00
ruthra kumar
f31ed75578 refactor(test): cleanup test data
(cherry picked from commit 6ba6b5aa33)
2024-07-03 01:34:50 +00:00
ruthra kumar
003d7e9f3e test: Repost should not merge expense accounts from LCV
(cherry picked from commit fa56555150)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-07-03 01:34:49 +00:00
ruthra kumar
650b25fc23 fix: always post to tax account heads if LCV is booked
(cherry picked from commit 0fcd5d5130)
2024-07-03 01:34:49 +00:00
ruthra kumar
d5366c5873 Merge pull request #42131 from frappe/mergify/bp/version-14-hotfix/pr-42126
fix: Re-open allows SO's to be over credit limit (backport #42126)
2024-07-01 17:25:50 +05:30
ruthra kumar
bf36b4fa11 chore: resolve conflict 2024-07-01 17:05:56 +05:30
ruthra kumar
f4fc26b52e test: credit check on Sales Order re-open
(cherry picked from commit 60694e09c4)

# Conflicts:
#	erpnext/selling/doctype/sales_order/test_sales_order.py
2024-07-01 11:33:36 +00:00
ruthra kumar
952a7b46d5 fix: Re-open allows SO's to be over credit limit
(cherry picked from commit 5eed781263)
2024-07-01 11:33:35 +00:00
Smit Vora
cc9857affd Merge pull request #42064 from frappe/mergify/bp/version-14-hotfix/pr-41979
fix: dynamic_link for party in customer and supplier dashboard (backport #41979)
2024-06-28 13:04:35 +05:30
ljain112
6de7a8de10 fix: dynamic_link for party in customer and supplier dashboard
(cherry picked from commit c0a8800832)
2024-06-28 06:35:17 +00:00
rohitwaghchaure
21bf7fd1f8 fix: timeout while cancelling LCV (#42030)
fix: timeout while canelling LCV
2024-06-25 17:38:03 +05:30
Khushi Rawat
a2ee4631cc fix: asset value correction in fixed asset register (#41943) 2024-06-25 16:04:20 +05:30
ruthra kumar
92ca6c6538 Merge pull request #41983 from frappe/mergify/bp/version-14-hotfix/pr-41981
fix: incorrect against_account upon reposting (backport #41981)
2024-06-21 19:10:41 +05:30
ruthra kumar
6028a19e6b fix: incorrect against_account upon reposting
(cherry picked from commit 20c4098399)
2024-06-21 12:30:39 +00:00
Raffael Meyer
87dc586543 Merge pull request #41440 from frappe/mergify/bp/version-14-hotfix/pr-41384
fix(SO, DN): only show permitted actions (backport #41384)
2024-06-20 15:51:18 +02:00
barredterra
22216b275c refactor: remove use of can_create for Payment Request (#41647)
(cherry picked from commit 47bc5691a1)
2024-06-20 14:21:30 +02:00
barredterra
0e6edf763e chore: resolve conflicts 2024-06-20 14:15:26 +02:00
barredterra
e77534ba2b Merge remote-tracking branch 'upstream/version-14-hotfix' into mergify/bp/version-14-hotfix/pr-41384 2024-06-20 13:47:58 +02:00
rohitwaghchaure
ae14b86a8c Merge pull request #41954 from ljain112/fix-41927
fix: consistent query field name in item wise purchase register with …
2024-06-20 14:03:12 +05:30
ljain112
9665212607 fix: consistent query field name in item wise purchase register with item wise sales register 2024-06-20 11:11:43 +05:30
Raffael Meyer
ee49e83020 Merge pull request #41944 from frappe/mergify/bp/version-14-hotfix/pr-41421
fix: migrate lead notes (backport #41421)
2024-06-19 01:17:48 +02:00
barredterra
598c581623 fix: only show user and date if available
(cherry picked from commit 895aede590)
2024-06-18 22:57:20 +00:00
barredterra
8f5278e3d4 fix: migrate lead notes
(cherry picked from commit 382d0ff453)
2024-06-18 22:57:19 +00:00
Raffael Meyer
aa38f69a67 Merge pull request #40543 from frappe/mergify/bp/version-14-hotfix/pr-40542 2024-06-18 12:51:55 +02:00
ruthra kumar
57a81c4012 Merge pull request #41937 from frappe/mergify/bp/version-14-hotfix/pr-41900
refactor: ignore unreconcile doc for PO and SO on cancel/delete (backport #41900)
2024-06-18 11:57:27 +05:30
ruthra kumar
2fabcb0c50 chore: resolve conflicts 2024-06-18 10:43:07 +05:30
ljain112
f833923f2f refactor: ignore unreconcile doc for PO and SO on cancel/delete
(cherry picked from commit b618d685c6)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.js
#	erpnext/selling/doctype/sales_order/sales_order.js
2024-06-18 04:57:52 +00:00
rohitwaghchaure
077cb9e983 Merge pull request #41934 from frappe/mergify/bp/version-14-hotfix/pr-41931
fix: reposting validation related PCV (backport #41931)
2024-06-18 09:41:58 +05:30
Rohit Waghchaure
bcfc83d8d5 fix: reposting validation related PCV
(cherry picked from commit 194f1dc674)
2024-06-17 12:22:00 +00:00
ruthra kumar
a5d1feef02 Merge pull request #41912 from frappe/mergify/bp/version-14-hotfix/pr-40187
fix: valuation tax entries on LCV after billing PR (backport #40187)
2024-06-17 13:54:06 +05:30
ruthra kumar
b050110544 chore: resolve conflicts 2024-06-17 07:12:51 +05:30
Gursheen Anand
e8f5c45751 chore: resolve conflicts
(cherry picked from commit 54a58e9205)
2024-06-15 15:12:23 +00:00
Gursheen Anand
eae5f27ec8 fix: reset perpetual inventory flag after test
(cherry picked from commit 0b36cbe307)
2024-06-15 15:12:23 +00:00
Gursheen Anand
d48455393e fix: parameters for PI references
(cherry picked from commit 8b3d46610e)
2024-06-15 15:12:23 +00:00
Gursheen Anand
7c699c8a38 test: LCV entries after billing
(cherry picked from commit 53642e7417)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-06-15 15:12:23 +00:00
Gursheen Anand
20b8ee1e90 fix: add LCV flag to determine negative expenses
(cherry picked from commit baa3fee1bf)

# Conflicts:
#	erpnext/controllers/stock_controller.py
2024-06-15 15:12:22 +00:00
Smit Vora
f9a7bb0544 Merge pull request #41889 from frappe/mergify/bp/version-14-hotfix/pr-41842
fix: regional overide for updating item valution (backport #41842)
2024-06-15 09:16:18 +05:30
ljain112
6441bc7862 fix: regional overide for updating item valution
(cherry picked from commit 1a10f0bcbd)
2024-06-13 08:09:01 +00:00
Raffael Meyer
a5df0f2c94 Merge pull request #41660 from frappe/mergify/bp/version-14-hotfix/pr-41659
fix: Auditor permissions (backport #41659)
2024-06-12 17:47:30 +02:00
mergify[bot]
e33416a4a7 Merge branch 'version-14-hotfix' into mergify/bp/version-14-hotfix/pr-41659 2024-06-12 12:13:11 +00:00
mergify[bot]
245c6d8672 fix: allow Employee role to select Department (backport #41877) (#41880)
* fix: allow Employee role to select Department (#41877)

(cherry picked from commit 56082f5a29)

# Conflicts:
#	erpnext/setup/doctype/department/department.json

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-06-12 17:19:16 +05:30
mergify[bot]
7234625d65 fix: terms and conditions for material request (backport #41834) (#41836)
fix: terms and conditions for material request (#41834)

(cherry picked from commit 4b026d66dc)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-10 15:17:06 +05:30
Deepesh Garg
625aa4ef6b Merge pull request #41829 from frappe/mergify/bp/version-14-hotfix/pr-41424
fix: Item-wise Sales and Purchase register with no item codes (#41424)
2024-06-09 22:38:15 +05:30
Deepesh Garg
e9b7d00afb chore: resolve conflicts 2024-06-09 22:17:30 +05:30
Deepesh Garg
e79e9e94d0 fix: Add additional condition application
(cherry picked from commit 8ec364df6f)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
2024-06-09 14:13:27 +00:00
Deepesh Garg
e94e15259b 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
2024-06-09 14:13:27 +00:00
Poorvi-R-Bhat
ab90b815e3 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
2024-06-09 14:13:25 +00:00
Poorvi-R-Bhat
ee47440063 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
2024-06-09 14:13:24 +00:00
Poorvi-R-Bhat
bc24e75c24 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
2024-06-09 14:13:23 +00:00
Poorvi
5d97c7cff9 fix: fixing Item-wise sales register
(cherry picked from commit c90185f533)
2024-06-09 14:13:23 +00:00
ruthra kumar
e38383a757 Merge pull request #41806 from frappe/mergify/bp/version-14-hotfix/pr-41804
chore: repost settings permission overhaul (backport #41804)
2024-06-06 16:34:18 +05:30
ruthra kumar
a5bda0180e chore: repost settings permission overhaul
(cherry picked from commit 458d8f5ed8)
2024-06-06 16:13:55 +05:30
mergify[bot]
5ab5bd138f fix: Ignore disabling default currency field while creating new company (backport #41699) (#41760)
fix: Ignore disabling default currency field while creating new company (#41699)

(cherry picked from commit 80f6228d45)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 11:55:42 +05:30
mergify[bot]
dc3265751c fix: payment term when creating PO from SO (backport #41376) (#41743)
fix: payment term when creating PO from SO (#41376)

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

(cherry picked from commit 441596f795)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-06-03 18:37:26 +05:30
ruthra kumar
cf8f0e4096 Merge pull request #41745 from frappe/mergify/bp/version-14-hotfix/pr-41742
chore: System Manager should have  submit permission for repost doctypes (backport #41742)
2024-06-03 18:33:55 +05:30
ruthra kumar
8c09968e1b chore: Sys Manager shluld have submit permission for repost doctypes
(cherry picked from commit 4558f64c0f)
2024-06-03 12:20:56 +00:00
Nabin Hait
39885b2b01 fix: get assets received but not billed account only if any asset item is received (#41734)
fix: get assets received but not billed account only if any asset item received
2024-06-03 14:05:57 +05:30
Deepesh Garg
6a6a6971ba Merge pull request #41679 from frappe/mergify/bp/version-14-hotfix/pr-41676
fix: Filters in account balance report (#41676)
2024-05-31 20:02:35 +05:30
Deepesh Garg
570985f40e fix: Filters in account balance report
(cherry picked from commit 1c9fe691ea)
2024-05-29 07:20:48 +00:00
Nabin Hait
eb418e8659 fix: Update depreciation schedule via asset repair (#41344)
* fix: Update depreciation schedule via asset repair

* fix: test cases related to modified depreciation schedule
2024-05-29 11:07:03 +05:30
Nabin Hait
014486de39 fix: set expense account as Assets RBNB only if it is booked in linked PR (#41368)
* fix: set expense account as Assets RBNB only if it is booked in linked PR

* fix: broken translations
2024-05-29 10:46:06 +05:30
barredterra
a53a80f01d chore: resolve conflicts 2024-05-27 18:54:17 +02:00
barredterra
b1a911aa9c fix: allow Auditor to read a Fiscal Year
(cherry picked from commit eaa4efbc45)

# Conflicts:
#	erpnext/accounts/doctype/fiscal_year/fiscal_year.json
2024-05-27 16:50:26 +00:00
barredterra
18b6d50a31 fix: allow Auditor to select a company
(cherry picked from commit 06401cc84f)

# Conflicts:
#	erpnext/setup/doctype/company/company.json
2024-05-27 16:50:26 +00:00
Akhil Narang
fcb2f4f084 Merge pull request #41624 from frappe/mergify/bp/version-14-hotfix/pr-41601
fix: add in some indices to speed up Purchase Order deletion (backport #41601)
2024-05-27 13:31:51 +05:30
Akhil Narang
308f200793 Merge pull request #41610 from frappe/mergify/bp/version-14-hotfix/pr-41609
refactor: use `json` directly instead of using `frappe.json` (backport #41609)
2024-05-27 13:31:29 +05:30
Akhil Narang
4fcfbe6e9f Merge pull request #41597 from frappe/mergify/bp/version-14-hotfix/pr-41576
chore: sync ruff config with framework (backport #41576)
2024-05-27 13:31:22 +05:30
Akhil Narang
5b2c13dacf refactor: use json directly instead of using frappe.json (#41609)
(cherry picked from commit 3f06f1905f)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-05-27 07:26:24 +00:00
Ankush Menat
76b7884fb7 ci: ruff only fix imports
(cherry picked from commit 85b1a8001b)
2024-05-27 07:26:14 +00:00
Ankush Menat
518dad8ecb ci: dont auto apply fixes
I've personally encountered ~5 instances of bad auto fixes, let
developers apply the fixes.

(cherry picked from commit 3b4913ec81)
2024-05-27 07:26:14 +00:00
Akhil Narang
220ae118e8 chore: resolve conflicts 2024-05-27 07:25:29 +00:00
Akhil Narang
f1f2f6e338 chore: resolve conflicts 2024-05-27 07:25:29 +00:00
Akhil Narang
c16c41ee59 fix: add in some indices to speed up Purchase Order deletion
`tabSales Order`.`inter_company_order_reference`
`tabSales Invoice Item`.`purchase_order`

Signed-off-by: Akhil Narang <me@akhilnarang.dev>
(cherry picked from commit 0303d7dbdc)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
#	erpnext/selling/doctype/sales_order/sales_order.json
2024-05-27 07:25:29 +00:00
ruthra kumar
dcffb3886b Merge pull request #41648 from frappe/mergify/bp/version-14-hotfix/pr-41401
fix: cost center filter according to the company in project (backport #41401)
2024-05-27 10:41:59 +05:30
Nihantra C. Patel
7035969db7 fix: cost center filter according to the company in project
(cherry picked from commit 501c6aa126)
2024-05-27 04:41:12 +00:00
Nihantra C. Patel
0cf97f2559 fix: cost center filter according to the company in project
(cherry picked from commit cfde8088b4)
2024-05-27 04:41:12 +00:00
Nihantra C. Patel
459d136368 fix: cost center filter according to the company in project
(cherry picked from commit 249e8264dd)
2024-05-27 04:41:11 +00:00
ruthra kumar
a2bfe31876 Merge pull request #40289 from Nihantra-Patel/fix_button_size_for_add_to_cart
fix: Add to Cart button width for Mobile/Tablet
2024-05-24 10:57:15 +05:30
ruthra kumar
75b021dc23 Merge pull request #41604 from frappe/mergify/bp/version-14-hotfix/pr-41603
refactor: remove 'format:' based naming in internal doctypes (backport #41603)
2024-05-24 10:54:45 +05:30
ruthra kumar
b2e2e951da Merge pull request #41606 from frappe/mergify/bp/version-14-hotfix/pr-41594
refactor: 'Payment Period Based On Invoice Date' report (backport #41594)
2024-05-24 10:54:07 +05:30
ruthra kumar
0f9b5074a6 chore: resolve conflicts 2024-05-23 17:47:47 +05:30
ruthra kumar
190900cd1b refactor: replace against_voucher with against_voucher_no
(cherry picked from commit c4e2abb973)
2024-05-23 12:16:41 +00:00
ruthra kumar
3512f7d528 refactor: remove debit and credit
(cherry picked from commit 014b542cf3)
2024-05-23 12:16:40 +00:00
ruthra kumar
0dc2f78a2e refactor: query payment ledger for payments
(cherry picked from commit cb3c20dcd3)
2024-05-23 12:16:40 +00:00
ruthra kumar
c834a9de85 refactor: remove 'format:' based naming in internal doctypes
(cherry picked from commit e2ec3e453a)

# Conflicts:
#	erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
#	erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
2024-05-23 12:15:21 +00:00
ruthra kumar
4d8c35aa5d Merge pull request #40957 from frappe/mergify/bp/version-14-hotfix/pr-40920
fix: Fetch correct outstanding and total amount for reference journal entry (backport #40920)
2024-05-23 16:08:14 +05:30
ruthra kumar
5230d411bf chore: resolve conflicts 2024-05-23 15:42:34 +05:30
ruthra kumar
a6bf7c1ebd chore: remove unused imports 2024-05-23 15:42:34 +05:30
Nabin Hait
50f6afd588 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
2024-05-23 15:42:34 +05:30
rohitwaghchaure
649c192abe fix: dict can not be used as parameter (#41598) 2024-05-23 15:37:00 +05:30
mergify[bot]
97fdda8a7c fix: priority not working for multiple pricing rules (backport #41516) (#41524)
* fix: priority not working for multiple pricing rules (#41516)

(cherry picked from commit 5cf5b18aea)

# Conflicts:
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.json
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.py
#	erpnext/patches.txt

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-20 13:39:39 +05:30
ruthra kumar
9802333397 Merge pull request #41527 from frappe/mergify/bp/version-14-hotfix/pr-41523
fix: minor Dr and Cr between Purchase Receipt and Purchase Invoice (backport #41523)
2024-05-20 08:32:24 +05:30
ruthra kumar
82d206b709 fix: minor Dr and Cr between Purchase Receipt and Purchase Invoice
This applies for Provisional Accounting for Non-stock items

(cherry picked from commit 1c0a24424a)
2024-05-17 12:21:28 +00:00
ruthra kumar
80810c2ebb Merge pull request #41518 from frappe/mergify/bp/version-14-hotfix/pr-41517
fix: typerror on hide_fields (backport #41517)
2024-05-17 14:54:06 +05:30
ruthra kumar
331a743d69 fix: typerror on hide_fields
(cherry picked from commit deb9766f2a)
2024-05-17 14:51:57 +05:30
ruthra kumar
32a1fea8f0 Merge pull request #41512 from frappe/mergify/bp/version-14-hotfix/pr-41511
fix: possible sql error on General Ledger (backport #41511)
2024-05-17 11:17:24 +05:30
ruthra kumar
dfb4c47089 fix: possible sql error on General Ledger
(cherry picked from commit 76131f8e10)
2024-05-17 05:26:54 +00:00
mergify[bot]
0cbf049608 chore(BOM Explorer): display items in the same order as in the BOM (backport #41496) (#41510)
chore(BOM Explorer): display items in the same order as in the BOM (#41496)

(cherry picked from commit bd381cc0c6)

Co-authored-by: Samuel Danieli <23150094+scdanieli@users.noreply.github.com>
2024-05-17 09:37:03 +05:30
ruthra kumar
3f0cb47464 Merge pull request #41500 from frappe/mergify/bp/version-14-hotfix/pr-40072
fix: print format bold for field "total" (backport #40072)
2024-05-16 15:35:48 +05:30
Nihantra C. Patel
89d507e07e fix: print format bold for field "total"
(cherry picked from commit 3c9640df27)
2024-05-16 10:04:03 +00:00
mergify[bot]
26595351cc fix: validate reorder group warehouse (backport #41478) (#41479)
fix: validate reorder group warehouse (#41478)

(cherry picked from commit 0363afcfd0)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-15 15:15:41 +05:30
Deepesh Garg
fc2614612b Merge pull request #41466 from frappe/mergify/bp/version-14-hotfix/pr-41258
fix: PSOA ageing (#41258)
2024-05-14 21:19:17 +05:30
Deepesh Garg
e69e5404d3 fix: PSOA ageing
(cherry picked from commit fed2d11905)
2024-05-14 14:40:36 +00:00
Nabin Hait
14ec6351ae Merge pull request #41448 from frappe/mergify/bp/version-14-hotfix/pr-41412
fix: Duplicate party name column in AR/AP report (backport #41412)
2024-05-14 20:02:56 +05:30
Deepesh Garg
a8be5f0789 fix: Duplicate party name column in AR/AP report
(cherry picked from commit 7501fe8ebd)
2024-05-14 02:53:49 +00:00
Deepesh Garg
42312c5bba Merge pull request #41170 from deepeshgarg007/default_dates_in_reports
fix: Default dates in report
2024-05-14 08:21:51 +05:30
mergify[bot]
7b28d7d2b8 feat: allow to pick manually qty / batches / serial nos (backport #40723) (#41435)
* feat: allow to pick manually qty / batches / serial nos

(cherry picked from commit 50dd9fa8a3)

# Conflicts:
#	erpnext/stock/doctype/pick_list/pick_list.json
#	erpnext/stock/doctype/pick_list/pick_list.py

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-05-13 21:37:13 +05:30
barredterra
0aa246c39e fix(Delivery Note): only show permitted actions
(cherry picked from commit 418bdc1dcc)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/delivery_note.js
2024-05-13 13:43:07 +00:00
barredterra
5468a3b0b7 fix(Sales Order): only show permitted actions
(cherry picked from commit c29d955371)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.js
2024-05-13 13:43:07 +00:00
mergify[bot]
5366356400 fix: data getting override in delivery trip (backport #41431) (#41432)
fix: data getting override in delivery trip (#41431)

fix: data getting override
(cherry picked from commit 663fcb374d)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-13 16:31:34 +05:30
Deepesh Garg
7a380f584d fix: default fiscal year 2024-05-11 17:51:53 +05:30
mergify[bot]
256d6a47ac fix: consistent use of "Address & Contact" (backport #41386) (#41387)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: consistent use of "Address & Contact" (#41386)
2024-05-10 17:42:27 +02:00
Akhil Narang
67e06615a3 Merge pull request #41406 from frappe/mergify/bp/version-14-hotfix/pr-37031
fix: "Based on" field always has the value "Not applicable" (backport #37031)
2024-05-10 16:44:33 +05:30
HarryPaulo
1078a98cce fix: "Based on" field always has the value "Not applicable"
(cherry picked from commit fae640c56f)
2024-05-10 11:13:03 +00:00
ruthra kumar
d87ffae03f Merge pull request #41394 from frappe/mergify/bp/version-14-hotfix/pr-41040
fix: address filter and quotation to for prospect (backport #41040)
2024-05-09 12:48:48 +05:30
ruthra kumar
0404941fb2 chore: resolve conflict 2024-05-09 12:21:29 +05:30
ruthra kumar
c4dfcbec96 refactor: make use of doc.quotation_to
(cherry picked from commit 754c7f6d1c)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.js
2024-05-09 06:45:53 +00:00
Nihantra Patel
c9e7f450c5 fix: address filter and quotation to for prospect
(cherry picked from commit 2896e3666c)
2024-05-09 06:45:53 +00:00
Nihantra Patel
690278042d fix: address filter and quotation to for prospect
(cherry picked from commit 24a68a79df)
2024-05-09 06:45:52 +00:00
Nihantra Patel
754e193c76 fix: address filter and quotation to for prospect
(cherry picked from commit fe5b88522e)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.js
2024-05-09 06:45:52 +00:00
mergify[bot]
4647ec8892 perf: index on item code for the Pick List Item doctype (backport #41357) (#41362)
* perf: index on item code for the Pick List Item doctype (#41357)

(cherry picked from commit 0887161f2a)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-08 11:38:02 +05:30
mergify[bot]
339256bc71 fix: filter validation for batch-wise balance history report (backport #41356) (#41360)
fix: filter validation for batch-wise balance history report (#41356)

fix: filter validation for batchwise balance history report
(cherry picked from commit 544fc60093)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-08 00:15:33 +05:30
ruthra kumar
c3d567b291 Merge pull request #41348 from frappe/mergify/bp/version-14-hotfix/pr-41288
fix: pricing rule rounding (backport #41288)
2024-05-07 10:32:20 +05:30
ruthra kumar
e068bec212 refactor(test): test floor based rounding
(cherry picked from commit c41a037174)
2024-05-07 04:32:04 +00:00
ruthra kumar
d2ce927891 fix: pricing rule rounding
Consider a pricing rule of 20:1 with recursion enabled, free items
should follow the below progression

|   Qty | Free item qty |
|-------+---------------|
|  0-19 |             0 |
| 20-39 |             1 |
| 40-59 |             2 |

(cherry picked from commit 9bf37426c1)
2024-05-07 04:32:03 +00:00
mergify[bot]
a26ae64385 fix: missing Item Name on Save for Quotation created from Item (backport #41233) (#41303)
fix: missing Item Name on Save for Quotation created from Item (#41233)

* fix: missing Item Name on Save for Quotation created from Item

* fix: missing Item Name on Save for Quotation created from Item

(cherry picked from commit c8e92cb1b2)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2024-05-06 21:46:18 +05:30
s-aga-r
cd33199da2 fix: reset rate for serial batch supplied items (#41293) 2024-05-06 21:37:27 +05:30
ruthra kumar
27100401aa Merge pull request #41336 from frappe/mergify/bp/version-14-hotfix/pr-41334
fix: incorrect query for Purchase Invoice rate in GP (backport #41334)
2024-05-06 13:17:58 +05:30
ruthra kumar
93b30d9f11 fix: incorrect query for Purchase Invoice rate in GP
(cherry picked from commit bd8382c592)
2024-05-06 07:24:49 +00:00
Deepesh Garg
904f369e99 Merge pull request #41324 from frappe/mergify/bp/version-14-hotfix/pr-41318
fix: Cost center not getting saved in PSOA (#41318)
2024-05-06 12:25:14 +05:30
Deepesh Garg
7b9c22775c chore: resolve conflicts 2024-05-06 11:52:26 +05:30
Deepesh Garg
6aa8d5fb4b chore: resolve conflicts 2024-05-06 11:29:53 +05:30
Deepesh Garg
e82ea12cbc fix: Cost center not getting saved in PSOA
(cherry picked from commit 58f7039630)

# Conflicts:
#	erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json
#	erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.py
2024-05-04 08:26:55 +00:00
mergify[bot]
d727c52421 fix: added brand column in Warehouse wise Item Balance Age and Value … (backport #41280) (#41281)
fix: added brand column in Warehouse wise Item Balance Age and Value … (#41280)

fix: added brand coulmn in Warehouse wise Item Balance Age and Value report
(cherry picked from commit 1cbc200770)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-03 17:53:52 +05:30
rohitwaghchaure
9aa054c400 fix: negative stock qty error for stock reconciliation (#41283)
fix: negative stock qty error for stock reco
2024-05-02 09:38:33 +05:30
ruthra kumar
82b2675aa8 Merge pull request #41269 from frappe/mergify/bp/version-14-hotfix/pr-41268
fix: validation to prevent overallocation (backport #41268)
2024-04-30 18:40:47 +05:30
ruthra kumar
8318286865 fix: validation to prevent overallocation
(cherry picked from commit bf755fab55)
2024-04-30 17:48:55 +05:30
ruthra kumar
f87411f40d Merge pull request #41254 from frappe/mergify/bp/version-14-hotfix/pr-41252
fix: permission issue when user permission restricts on company (backport #41252)
2024-04-30 14:19:39 +05:30
ruthra kumar
45c4167c86 fix: permission issue when user permission restricts on company 2024-04-30 12:24:32 +05:30
ruthra kumar
e0d1f2f6eb Merge pull request #41248 from frappe/mergify/bp/version-14-hotfix/pr-41240
fix: display term name for single term invoices in AR/AP (backport #41240)
2024-04-30 07:42:33 +05:30
ruthra kumar
ba45ea42f8 Merge pull request #41246 from frappe/mergify/bp/version-14-hotfix/pr-41194
fix: TDS incorrectly applied when Advance is in previous FY (backport #41194)
2024-04-30 07:42:23 +05:30
ruthra kumar
58b68b7597 fix: display term name for single term invoices
(cherry picked from commit 5fa4cfee04)
2024-04-30 01:40:17 +00:00
ruthra kumar
4d56c46446 test: TDS deduction across fiscal year
(cherry picked from commit 2f9a144023)
2024-04-30 07:04:21 +05:30
ruthra kumar
eb22fb9326 fix: incorrectly applying TDS when Advance is in previous FY
(cherry picked from commit b195f519e2)
2024-04-30 01:27:56 +00:00
rohitwaghchaure
54313b5db9 fix: multiple pricing rules with discount amount and discount percentage not working (#41211) 2024-04-29 20:53:10 +05:30
mergify[bot]
866b0c6ac7 chore: delete invalid translations (backport #41227) (#41228)
chore: delete invalid translations (#41227)

(cherry picked from commit 067419b7cd)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-04-29 10:41:54 +05:30
mergify[bot]
1e1319351d feat: allow to do reposting for all stock transactions (audit) (backport #41165) (#41205)
* feat: allow to do reposting for all transactions (audit)

(cherry picked from commit aefbe21b46)

# Conflicts:
#	erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
#	erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.py

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-04-26 14:25:51 +05:30
rohitwaghchaure
6b2874694e Merge pull request #41204 from rohitwaghchaure/fixed-unbuffered_cursor
fix: 'NoneType' object has no attribute '_read_rowdata_packet_unbuffe…
2024-04-26 13:50:07 +05:30
rohitwaghchaure
ff37706bef Merge pull request #41200 from frappe/mergify/bp/version-14-hotfix/pr-41185
fix: args when get the delivery note in delivery trip (backport #41185)
2024-04-26 13:36:14 +05:30
Rohit Waghchaure
949aa9346c fix: 'NoneType' object has no attribute '_read_rowdata_packet_unbuffered' 2024-04-26 13:25:46 +05:30
rohitwaghchaure
2f6fee9877 chore: fix conflicts 2024-04-26 13:15:32 +05:30
Nihantra Patel
abe64aa1ab fix: args when get the delivery note in delivery trip
(cherry picked from commit ca577f7aaa)
2024-04-26 07:40:32 +00:00
Nihantra Patel
1a7b3c437d fix: args when get the delivery note in delivery trip
(cherry picked from commit 2f359e201d)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/delivery_note.py
2024-04-26 07:40:31 +00:00
rohitwaghchaure
da69b1e71b Merge pull request #41196 from frappe/mergify/bp/version-14-hotfix/pr-41192
fix: duplicate column in the stock ledger report (backport #41192)
2024-04-26 12:49:35 +05:30
Rohit Waghchaure
3fcdcef178 fix: duplicate column in the stock ledger report
(cherry picked from commit be7fd6bfb4)
2024-04-26 06:53:08 +00:00
rohitwaghchaure
7656fe4bfc Merge pull request #41174 from rohitwaghchaure/fixed-performance-issue-for-serial-no-creation
perf: timeout issue while submitting purchase receipt (v14)
2024-04-26 10:56:28 +05:30
mergify[bot]
59010c9a61 fix: handle stock balance unbuffered_cursor error (backport #41186) (#41187)
fix: handle stock balance unbuffered_cursor error (#41186)

(cherry picked from commit 341fb6d8f3)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-04-25 17:26:29 +05:30
Rohit Waghchaure
113351e850 perf: timeout issue while submitting purchase receipt (v14) 2024-04-25 12:10:29 +05:30
ruthra kumar
b9d28fc1ad Merge pull request #41178 from frappe/mergify/bp/version-14-hotfix/pr-41142
fix: mode of payment has precedance in Payment Entry (backport #41142)
2024-04-25 09:02:37 +05:30
ruthra kumar
33d38ba3a7 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 08:58:01 +05:30
Deepesh Garg
ff8dba1cb7 Merge branch 'version-14-hotfix' of https://github.com/frappe/erpnext into default_dates_in_reports 2024-04-24 17:20:55 +05:30
Deepesh Garg
c3244f009b fix: Default dates in report 2024-04-24 16:59:51 +05:30
Deepesh Garg
3e81f0f578 Merge pull request #41100 from frappe/mergify/bp/version-14-hotfix/pr-41085
fix: Permission for lower deduction certificate (#41085)
2024-04-24 12:00:13 +05:30
mergify[bot]
bb48440591 fix: allow Employee role to select cost center & project (accounting dimensions) (backport #41160) (#41161)
* fix: allow Employee role to select cost center & project (accounting dimensions)

(cherry picked from commit d0d496a515)

# Conflicts:
#	erpnext/accounts/doctype/cost_center/cost_center.json
#	erpnext/projects/doctype/project/project.json

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-04-24 11:43:33 +05:30
Deepesh Garg
35230a9692 chore: Resolve conflicts 2024-04-24 11:33:34 +05:30
Nabin Hait
df3ff1097c Merge pull request #41140 from frappe/mergify/bp/version-14-hotfix/pr-41136
fix: Missing args while fetching items from delivery note in Installation Note (backport #41136)
2024-04-24 10:59:16 +05:30
rohitwaghchaure
521bf31fe3 Merge pull request #41154 from rohitwaghchaure/feat-new-batch-report-v14
feat: Available batches report as on specific date
2024-04-23 17:17:26 +05:30
Rohit Waghchaure
8868cb147d feat: Available batches report as on specific date 2024-04-23 17:10:05 +05:30
Deepesh Garg
0dfae12f14 Merge pull request #41130 from frappe/mergify/bp/version-14-hotfix/pr-40797
fix: Party type in Payment Order (#40797)
2024-04-23 12:05:25 +05:30
Nabin Hait
0df80ad923 fix: Missing args while fetching items from delivery note
(cherry picked from commit bbe323fbb4)
2024-04-23 04:55:02 +00:00
rohitwaghchaure
c71d1118a9 Merge pull request #41138 from rohitwaghchaure/fixed-performance-for-stock-reports
perf: stock ageing and batch-wise balance history report
2024-04-23 10:12:19 +05:30
Rohit Waghchaure
6017e7ac3e perf: stock ageing and batch-wise balance history report 2024-04-23 06:56:41 +05:30
Deepesh Garg
d5784cc629 Merge pull request #41126 from frappe/mergify/bp/version-14-hotfix/pr-40812
fix: Multiple partial payment requests against Purchase Invoice (#40812)
2024-04-22 11:36:30 +05:30
Deepesh Garg
a2e1d132df fix: Party type in Payment Order
(cherry picked from commit 91fa41c9ec)
2024-04-22 06:05:12 +00:00
Gursheen Kaur Anand
3e912993e1 Merge pull request #41123 from frappe/mergify/bp/version-14-hotfix/pr-40769
fix: budget validation for purchase orders (backport #40769)
2024-04-21 18:57:52 +05:30
Deepesh Garg
5aef9d2ef2 fix: Test case
(cherry picked from commit 071e5ed648)
2024-04-21 11:50:38 +00:00
Deepesh Garg
f1b75e8c54 fix: Multiple partial payment requests against Purchase Invoice
(cherry picked from commit 45d5f6e00a)
2024-04-21 11:50:38 +00:00
Gursheen Anand
5b1c5e3fea refactor: show list for expense breakup
(cherry picked from commit 9a12376e29)
2024-04-21 11:26:19 +00:00
Gursheen Anand
f087ec8df5 feat: show expense breakup
(cherry picked from commit 59292a09c4)
2024-04-21 11:26:19 +00:00
Gursheen Anand
ec4f07fd60 fix: do not add actual expense twice for validating budget
(cherry picked from commit af26ac96e9)
2024-04-21 11:26:19 +00:00
Deepesh Garg
a22be6f9b9 fix: Permission for lower dedcution certificate
(cherry picked from commit f6f118855b)

# Conflicts:
#	erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.json
2024-04-19 10:11:41 +00:00
Gursheen Kaur Anand
e8accd0256 Merge pull request #41094 from frappe/mergify/bp/version-14-hotfix/pr-41093
fix: accounts manager perm for FY (backport #41093)
2024-04-19 14:08:19 +05:30
Gursheen Kaur Anand
de3a423618 chore: resolve conflicts 2024-04-19 13:32:39 +05:30
Gursheen Anand
03ce9ee321 fix: account and stock manager read perm
(cherry picked from commit 572e844a91)

# Conflicts:
#	erpnext/accounts/doctype/fiscal_year/fiscal_year.json
2024-04-19 08:00:48 +00:00
mergify[bot]
9d0c1dc46f fix: validate uom is integer for PR item (backport #41074) (#41076)
* fix: validate uom is integer for PR item

(cherry picked from commit 9a290fdfc9)

# Conflicts:
#	erpnext/controllers/subcontracting_controller.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-04-18 07:53:33 +05:30
mergify[bot]
5d05bf8d4e fix: don't attempt to set gender from salutation (backport #40997) (#41072)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: don't attempt to set gender from salutation (#40997)
2024-04-17 17:54:03 +02:00
ruthra kumar
4cc0a5851b Merge pull request #40854 from frappe/mergify/bp/version-14-hotfix/pr-40786
fix(gp): SLEs not fetched for correct warehouse (backport #40786)
2024-04-17 10:36:52 +05:30
ruthra kumar
6e9da0a729 Merge branch 'version-14-hotfix' into mergify/bp/version-14-hotfix/pr-40786 2024-04-17 10:16:55 +05:30
Dany Robert
97e7b3f3d3 fix(gp): SLEs not fetched for correct warehouse
(cherry picked from commit f958e8be06)
2024-04-17 10:15:29 +05:30
mergify[bot]
e956dbbf68 fix: Delayed Order Report not working (backport #41037) (#41038)
fix: Delayed Order Report not working (#41037)

(cherry picked from commit d69a18b826)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-04-16 18:24:45 +05:30
rohitwaghchaure
ebf5f13447 Merge branch 'version-14' into version-14-hotfix 2024-04-16 17:59:35 +05:30
ruthra kumar
9404dea97e Merge pull request #41034 from frappe/mergify/bp/version-14-hotfix/pr-40373
fix: get address if multiple companies (backport #40373)
2024-04-16 16:41:26 +05:30
ruthra kumar
ee06448f0d chore: resolve conflict 2024-04-16 16:38:32 +05:30
Nihantra C. Patel
c2b6b64e2e fix: get address if multiple companies
(cherry picked from commit 655a1797be)
2024-04-16 11:01:59 +00:00
Nihantra Patel
04938726d9 fix: get address if multiple companies
(cherry picked from commit c6cf1bec76)

# Conflicts:
#	erpnext/selling/doctype/sales_order/sales_order.js
2024-04-16 11:01:58 +00:00
mergify[bot]
153e0ba81b fix: expense account set as COGS for stock entry Material Issue (backport #41026) (#41028)
fix: expense account set as COGS for stock entry Material Issue (#41026)

(cherry picked from commit 03231e99ef)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-04-16 14:22:53 +05:30
mergify[bot]
0bee921d40 fix: barcode not fetched on selection of item (backport #40814) (#41027)
* fix: barcode not fetched on selection of item

(cherry picked from commit b0730293e2)

# Conflicts:
#	erpnext/stock/get_item_details.py

* chore: fix conflicts

* chore: fix test case

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2024-04-16 14:22:32 +05:30
ruthra kumar
9d3c861766 Merge pull request #41022 from frappe/mergify/bp/version-14-hotfix/pr-41020
fix: incorrect exc gain/loss for PE against JE for payable accounts (backport #41020)
2024-04-16 11:31:40 +05:30
ruthra kumar
e8d05517c5 chore: resolve conflict 2024-04-16 11:07:39 +05:30
ruthra kumar
2ebdd93a83 test: exc gain/loss journals booking in Payable accounts
(cherry picked from commit 8821c98625)
2024-04-16 05:29:49 +00:00
ruthra kumar
50a74ee7fe fix: incorrect exc gain/loss for PE against JE for payable accounts
(cherry picked from commit 81b574053f)

# Conflicts:
#	erpnext/controllers/accounts_controller.py
2024-04-16 05:29:49 +00:00
Nabin Hait
da1c317c6c Merge pull request #41006 from frappe/mergify/bp/version-14-hotfix/pr-40858
fix: Don't set delivery date as today while making SO from Quotation (backport #40858)
2024-04-15 13:05:21 +05:30
Nabin Hait
79e23dad2c fix: test cases
(cherry picked from commit 65c74fa3c7)
2024-04-15 07:03:42 +00:00
Nabin Hait
b47e224a1c fix: Don't set delivery date as today while making SO from Quotation
(cherry picked from commit fec20decc1)
2024-04-15 07:03:42 +00:00
Deepesh Garg
3310358d36 Merge pull request #40947 from frappe/mergify/bp/version-14-hotfix/pr-40931
fix: Don't call get_fiscal_year if setup is not done yet (backport #40931)
2024-04-15 11:18:06 +05:30
Frappe PR Bot
7a6c0e5283 chore(release): Bumped to Version 14.67.1
## [14.67.1](https://github.com/frappe/erpnext/compare/v14.67.0...v14.67.1) (2024-04-12)

### Bug Fixes

* Subcontracting Receipt GL Entries (backport [#40773](https://github.com/frappe/erpnext/issues/40773)) (backport [#40978](https://github.com/frappe/erpnext/issues/40978)) ([#40982](https://github.com/frappe/erpnext/issues/40982)) ([4672f59](4672f59599))
2024-04-12 10:01:51 +00:00
mergify[bot]
4672f59599 fix: Subcontracting Receipt GL Entries (backport #40773) (backport #40978) (#40982)
* fix: Subcontracting Receipt GL Entries (backport #40773) (#40978)

* fix: Subcontracting Receipt GL Entries

(cherry picked from commit 9808ae92a4)

* chore: linter

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
(cherry picked from commit c2c4548cc0)

# Conflicts:
#	erpnext/subcontracting/doctype/subcontracting_receipt/subcontracting_receipt.py

* chore: `conflicts`

---------

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-04-12 15:30:27 +05:30
mergify[bot]
c2c4548cc0 fix: Subcontracting Receipt GL Entries (backport #40773) (#40978)
* fix: Subcontracting Receipt GL Entries

(cherry picked from commit 9808ae92a4)

* chore: linter

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-04-12 14:50:12 +05:30
Deepesh Garg
cc925ae938 fix: Resolve merge conflicts 2024-04-12 12:10:55 +05:30
Akhil Narang
f0ecc627fb Merge pull request #40943 from akhilnarang/v14-ruff
chore: backport ruff linting/formatting
2024-04-12 11:01:43 +05:30
Akhil Narang
cf3c26d80c chore: gitignore ruff format
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-12 11:01:32 +05:30
Corentin Flr
59cea9f4dd fix: Don't call get_fiscal_year if setup is not done yet
(cherry picked from commit c203fafb1b)

# Conflicts:
#	erpnext/public/js/utils.js
2024-04-10 15:17:44 +00:00
Frappe PR Bot
cc6bacb190 chore(release): Bumped to Version 14.67.0
# [14.67.0](https://github.com/frappe/erpnext/compare/v14.66.4...v14.67.0) (2024-04-10)

### Bug Fixes

* Get pro-rata depr amount based on correct days ([10d7600](10d760089e))
* group warehouse added in the stock reconciliation ([9dea6d3](9dea6d3393))
* ignore dimension validation for cancelled entries ([9745724](9745724d41))
* incorrect currency symbol in General Ledger print ([5896e75](5896e755bf))
* incorrect operator causing incorrect validation ([7e1ab75](7e1ab75b38))
* query_report.trigger_refresh is not a function ([a6145fa](a6145fa13c))
* translatable web footer ([#40834](https://github.com/frappe/erpnext/issues/40834)) ([b55d859](b55d8597e8))
* use reference type name to update exc rate ([09cda60](09cda60bdf))

### Features

* ledger health doctype ([b667a02](b667a02470))
* new hook `fields_for_group_similar_items` to group additional fields for print formats ([#40831](https://github.com/frappe/erpnext/issues/40831)) ([0172880](0172880fd3))

### Performance Improvements

* memory consumption for the Batch-Wise Balance History report ([3165682](3165682d7a))
2024-04-10 14:22:01 +00:00
Deepesh Garg
cebde2662d Merge pull request #40919 from frappe/version-14-hotfix
chore: release v14
2024-04-10 19:50:19 +05:30
ruthra kumar
b4ed2d2c16 fix: use 'eq' and isnull() on qb conditions
(cherry picked from commit eee86d2e4b)
(cherry picked from commit 22689958da)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-10 17:13:31 +05:30
Akhil Narang
2425119b5e fix: exclude some query builder lines from ruff rules
`== None` and `== True` are intentional here

(cherry picked from commit ac69513f60)
(cherry picked from commit 41d7c03cbb)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-10 17:13:31 +05:30
Akhil Narang
b087fb3d54 fix(treewide): manual ruff fixes
(cherry picked from commit f63396ef47)
(cherry picked from commit 7828eee014)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-10 17:13:31 +05:30
Akhil Narang
4d34b1ead7 refactor(treewide): formatting and ruff fixes, + manually enabled F401
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-10 17:13:31 +05:30
barredterra
c28d19cf7f chore: switch to ruff for python formatting/linting
(cherry picked from commit 8afb7790de)
(cherry picked from commit 9eeedd8515)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-04-10 17:07:51 +05:30
ruthra kumar
73d2595aa6 Merge pull request #40937 from frappe/mergify/bp/version-14-hotfix/pr-40936
fix: ignore dimension validation for cancelled entries (backport #40936)
2024-04-10 15:28:00 +05:30
ruthra kumar
9745724d41 fix: ignore dimension validation for cancelled entries
(cherry picked from commit 971c867f29)
2024-04-10 08:28:35 +00:00
ruthra kumar
a31b2e17f5 Merge pull request #40929 from frappe/mergify/bp/version-14-hotfix/pr-40695
feat: Periodically monitor ledger health (backport #40695)
2024-04-10 07:17:29 +05:30
ruthra kumar
46c76b166d chore: resolve conflicts 2024-04-09 19:59:09 +05:30
ruthra kumar
6079c5636e Merge pull request #40927 from frappe/mergify/bp/version-14-hotfix/pr-40926
fix: incorrect currency symbol in General Ledger print (backport #40926)
2024-04-09 19:54:29 +05:30
ruthra kumar
5808feaccf chore: use super() instead of super(__class__, self)
(cherry picked from commit 24d37d22a3)
2024-04-09 12:25:55 +00:00
ruthra kumar
98ad034b21 chore: make ledger health doctype read_only
(cherry picked from commit dc79213bb3)
2024-04-09 12:25:55 +00:00
ruthra kumar
277717a2e0 test: ledger monitoring function
(cherry picked from commit 4776d660b5)
2024-04-09 12:25:55 +00:00
ruthra kumar
0591f72e01 chore: schedule job to run daily
(cherry picked from commit f96cf111ed)
2024-04-09 12:25:54 +00:00
ruthra kumar
1af6b4256f chore: permission and UI changes
(cherry picked from commit 1a43ed763b)
2024-04-09 12:25:53 +00:00
ruthra kumar
6273a31b8c refactor: only run checks on specified companies
(cherry picked from commit 00eeacd06a)

# Conflicts:
#	erpnext/accounts/utils.py
2024-04-09 12:25:53 +00:00
ruthra kumar
f86c035f88 refactor: make health check configurable for companies
(cherry picked from commit 704925549b)
2024-04-09 12:25:52 +00:00
ruthra kumar
9981a900b2 refactor: control monitoring through settings page
(cherry picked from commit a42482ce35)

# Conflicts:
#	erpnext/accounts/utils.py
2024-04-09 12:25:52 +00:00
ruthra kumar
7a6ffccecc chore: settings page for health monitor
(cherry picked from commit b2fb7843d1)
2024-04-09 12:25:47 +00:00
ruthra kumar
58698c9aa4 refactor: barebones method to run checks
(cherry picked from commit 8c8d9be810)

# Conflicts:
#	erpnext/accounts/utils.py
2024-04-09 12:25:47 +00:00
ruthra kumar
bbe4ca7d74 refactor: flag for general and payment ledger mismatch
(cherry picked from commit d620b9eae8)
2024-04-09 12:25:46 +00:00
ruthra kumar
153fc91478 refactor: date on which vouchers was reported
(cherry picked from commit 402ffc6d27)
2024-04-09 12:25:45 +00:00
ruthra kumar
b667a02470 feat: ledger health doctype
(cherry picked from commit 9ed74dd8cc)
2024-04-09 12:25:45 +00:00
ruthra kumar
5896e755bf fix: incorrect currency symbol in General Ledger print
(cherry picked from commit 429e036e8c)
2024-04-09 12:16:41 +00:00
rohitwaghchaure
dd6c53df96 Merge pull request #40910 from rohitwaghchaure/fixed-perf-issue-for-batchwise-balance-history
perf: memory consumption for the Batch-Wise Balance History report
2024-04-09 17:36:43 +05:30
Rohit Waghchaure
3165682d7a perf: memory consumption for the Batch-Wise Balance History report 2024-04-08 19:03:48 +05:30
ruthra kumar
aff71970e5 Merge pull request #40904 from frappe/mergify/bp/version-14-hotfix/pr-40878
refactor: merge taxes from delivery note to Sales Invoice (backport #40878)
2024-04-08 16:18:48 +05:30
Sagar Vora
2b5ae1dbae Merge pull request #40906 from frappe/mergify/bp/version-14-hotfix/pr-40831 2024-04-08 10:22:43 +00:00
Sagar Vora
24709ab400 chore: fix conflict 2024-04-08 15:50:58 +05:30
Smit Vora
0172880fd3 feat: new hook fields_for_group_similar_items to group additional fields for print formats (#40831)
(cherry picked from commit f7c9e1538b)

# Conflicts:
#	erpnext/hooks.py
2024-04-08 10:18:15 +00:00
ruthra kumar
b76c00de68 chore: resolve conflict 2024-04-08 15:44:13 +05:30
ruthra kumar
ae1858f465 test: tax merging from 2 Delivery Note to Sales Invoice
(cherry picked from commit 39a48a2e2a)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2024-04-08 09:09:36 +00:00
ruthra kumar
22b16a6b0e refactor: merge taxes from delivery note to Sales Invoice
(cherry picked from commit 550cbbd91c)
2024-04-08 09:09:34 +00:00
Frappe PR Bot
8d8feadeae chore(release): Bumped to Version 14.66.4
## [14.66.4](https://github.com/frappe/erpnext/compare/v14.66.3...v14.66.4) (2024-04-07)

### Bug Fixes

* incorrect operator causing incorrect validation ([60ba62e](60ba62e882))
2024-04-07 12:34:56 +00:00
rohitwaghchaure
5629ad21d2 Merge pull request #40898 from frappe/mergify/bp/version-14/pr-40893
fix: incorrect operator causing incorrect validation (backport #40883) (backport #40893)
2024-04-07 18:03:33 +05:30
Nabin Hait
1eb720a7b0 Merge pull request #40897 from nabinhait/pro-rata-depr-fix
fix: Get pro-rata depr amount based on correct days
2024-04-07 15:23:42 +05:30
rohitwaghchaure
c4e950f6b5 Merge pull request #40835 from frappe/mergify/bp/version-14-hotfix/pr-40834
fix: translatable web footer (backport #40834)
2024-04-07 14:35:45 +05:30
rohitwaghchaure
d4313f7109 Merge pull request #40859 from frappe/mergify/bp/version-14-hotfix/pr-40848
fix: group warehouse added in the stock reconciliation (backport #40848)
2024-04-07 14:34:33 +05:30
Rohit Waghchaure
60ba62e882 fix: incorrect operator causing incorrect validation
(cherry picked from commit 6b317b0c0d)
(cherry picked from commit 7e1ab75b38)
2024-04-07 09:04:00 +00:00
rohitwaghchaure
26d7354973 Merge pull request #40893 from frappe/mergify/bp/version-14-hotfix/pr-40883
fix: incorrect operator causing incorrect validation (backport #40883)
2024-04-07 14:33:10 +05:30
Nabin Hait
10d760089e fix: Get pro-rata depr amount based on correct days 2024-04-07 14:08:45 +05:30
Rohit Waghchaure
7e1ab75b38 fix: incorrect operator causing incorrect validation
(cherry picked from commit 6b317b0c0d)
2024-04-07 06:34:07 +00:00
rohitwaghchaure
0f9af4b82c Merge pull request #40888 from frappe/mergify/bp/version-14-hotfix/pr-40887
fix: query_report.trigger_refresh is not a function (backport #40887)
2024-04-07 12:02:16 +05:30
Rohit Waghchaure
a6145fa13c fix: query_report.trigger_refresh is not a function
(cherry picked from commit 30bbb58ca1)
2024-04-07 06:27:49 +00:00
ruthra kumar
cc2f861bca Merge pull request #40868 from frappe/mergify/bp/version-14-hotfix/pr-40856
fix: unwanted Exc Gain/Loss journals on Payment against Journal entry (backport #40856)
2024-04-05 11:01:48 +05:30
ruthra kumar
8f2fd5dec9 test: payment against JE reconciliation with different rates
(cherry picked from commit fe84558b77)
2024-04-05 05:03:56 +00:00
ruthra kumar
09cda60bdf fix: use reference type name to update exc rate
(cherry picked from commit c15690e475)
2024-04-05 05:03:56 +00:00
Rohit Waghchaure
9dea6d3393 fix: group warehouse added in the stock reconciliation
(cherry picked from commit 8f53bc0096)
2024-04-04 10:09:55 +00:00
Raffael Meyer
b55d8597e8 fix: translatable web footer (#40834)
(cherry picked from commit f3bcdbe5bd)
2024-04-02 15:16:18 +00:00
barredterra
d0a0a35d72 chore: remove accidentally added file 2024-03-19 12:53:20 +01:00
barredterra
3b2044dcd7 chore: resolve conflicts 2024-03-19 12:46:14 +01:00
barredterra
7f2a54d95b refactor: usage of in_list
(cherry picked from commit d238751e6b)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.js
#	erpnext/buying/doctype/purchase_order/purchase_order.js
#	erpnext/public/js/controllers/accounts.js
#	erpnext/public/js/controllers/buying.js
#	erpnext/public/js/controllers/transaction.js
#	erpnext/public/js/utils/sales_common.js
#	erpnext/templates/form_grid/item_grid.html
2024-03-19 11:12:58 +00:00
Nihantra C. Patel
819ced4cb3 fix: Add to Cart button width for Mobile/Tablet 2024-03-05 17:24:17 +05:30
842 changed files with 17171 additions and 8764 deletions

View File

@@ -28,4 +28,7 @@ b147b85e6ac19a9220cd1e2958a6ebd99373283a
494bd9ef78313436f0424b918f200dab8fc7c20b
# bulk format python code with black
baec607ff5905b1c67531096a9cf50ec7ff00a5d
baec607ff5905b1c67531096a9cf50ec7ff00a5d
# ruff
4d34b1ead73baf4c5430a2ecbe44b9e8468d7626

View File

@@ -23,7 +23,7 @@ jobs:
run: git clone --depth 1 https://github.com/frappe/semgrep-rules.git frappe-semgrep-rules
- name: Download semgrep
run: pip install semgrep==0.97.0
run: pip install semgrep
- name: Run Semgrep rules
run: semgrep ci --config ./frappe-semgrep-rules/rules --config r/python.lang.correctness

View File

@@ -65,28 +65,18 @@ repos:
.*/loan_write_off.js
)$
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.2.0
hooks:
- id: flake8
additional_dependencies: [
'flake8-bugbear',
]
args: ['--config', '.github/helper/.flake8_strict']
exclude: ".*setup.py$"
- id: ruff
name: "Run ruff import sorter"
args: ["--select=I", "--fix"]
- repo: https://github.com/adityahase/black
rev: 9cb0a69f4d0030cdf687eddf314468b39ed54119
hooks:
- id: black
additional_dependencies: ['click==8.0.4']
- repo: https://github.com/PyCQA/isort
rev: 5.12.0
hooks:
- id: isort
exclude: ".*setup.py$"
- id: ruff
name: "Run ruff linter"
- id: ruff-format
name: "Run ruff formatter"
ci:
autoupdate_schedule: weekly

View File

@@ -4,22 +4,22 @@
# the repo. Unless a later match takes precedence,
erpnext/accounts/ @deepeshgarg007 @ruthra-kumar
erpnext/assets/ @anandbaburajan @deepeshgarg007
erpnext/assets/ @khushi8112 @deepeshgarg007
erpnext/loan_management/ @deepeshgarg007
erpnext/regional @deepeshgarg007 @ruthra-kumar
erpnext/selling @deepeshgarg007 @ruthra-kumar
erpnext/support/ @deepeshgarg007
pos*
erpnext/buying/ @rohitwaghchaure @s-aga-r
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
erpnext/stock/ @rohitwaghchaure @s-aga-r
erpnext/subcontracting @rohitwaghchaure @s-aga-r
erpnext/buying/ @rohitwaghchaure
erpnext/maintenance/ @rohitwaghchaure
erpnext/manufacturing/ @rohitwaghchaure
erpnext/quality_management/ @rohitwaghchaure
erpnext/stock/ @rohitwaghchaure
erpnext/subcontracting @rohitwaghchaure
erpnext/controllers/ @deepeshgarg007 @rohitwaghchaure
erpnext/patches/ @deepeshgarg007
.github/ @deepeshgarg007
pyproject.toml @ankush
pyproject.toml @akhilnarang

View File

@@ -3,7 +3,7 @@ import inspect
import frappe
__version__ = "14.66.3"
__version__ = "14.67.1"
def get_default_company(user=None):
@@ -36,10 +36,8 @@ def get_default_cost_center(company):
if not frappe.flags.company_cost_center:
frappe.flags.company_cost_center = {}
if not company in frappe.flags.company_cost_center:
frappe.flags.company_cost_center[company] = frappe.get_cached_value(
"Company", company, "cost_center"
)
if company not in frappe.flags.company_cost_center:
frappe.flags.company_cost_center[company] = frappe.get_cached_value("Company", company, "cost_center")
return frappe.flags.company_cost_center[company]
@@ -47,7 +45,7 @@ def get_company_currency(company):
"""Returns the default company currency"""
if not frappe.flags.company_currency:
frappe.flags.company_currency = {}
if not company in frappe.flags.company_currency:
if company not in frappe.flags.company_currency:
frappe.flags.company_currency[company] = frappe.db.get_value(
"Company", company, "default_currency", cache=True
)
@@ -81,7 +79,7 @@ def is_perpetual_inventory_enabled(company):
if not hasattr(frappe.local, "enable_perpetual_inventory"):
frappe.local.enable_perpetual_inventory = {}
if not company in frappe.local.enable_perpetual_inventory:
if company not in frappe.local.enable_perpetual_inventory:
frappe.local.enable_perpetual_inventory[company] = (
frappe.get_cached_value("Company", company, "enable_perpetual_inventory") or 0
)
@@ -96,7 +94,7 @@ def get_default_finance_book(company=None):
if not hasattr(frappe.local, "default_finance_book"):
frappe.local.default_finance_book = {}
if not company in frappe.local.default_finance_book:
if company not in frappe.local.default_finance_book:
frappe.local.default_finance_book[company] = frappe.get_cached_value(
"Company", company, "default_finance_book"
)
@@ -108,7 +106,7 @@ def get_party_account_type(party_type):
if not hasattr(frappe.local, "party_account_types"):
frappe.local.party_account_types = {}
if not party_type in frappe.local.party_account_types:
if party_type not in frappe.local.party_account_types:
frappe.local.party_account_types[party_type] = (
frappe.db.get_value("Party Type", party_type, "account_type") or ""
)

View File

@@ -11,14 +11,14 @@ class ERPNextAddress(Address):
def validate(self):
self.validate_reference()
self.update_compnay_address()
super(ERPNextAddress, self).validate()
super().validate()
def link_address(self):
"""Link address based on owner"""
if self.is_your_company_address:
return
return super(ERPNextAddress, self).link_address()
return super().link_address()
def update_compnay_address(self):
for link in self.get("links"):
@@ -26,11 +26,11 @@ class ERPNextAddress(Address):
self.is_your_company_address = 1
def validate_reference(self):
if self.is_your_company_address and not [
row for row in self.links if row.link_doctype == "Company"
]:
if self.is_your_company_address and not [row for row in self.links if row.link_doctype == "Company"]:
frappe.throw(
_("Address needs to be linked to a Company. Please add a row for Company in the Links table."),
_(
"Address needs to be linked to a Company. Please add a row for Company in the Links table."
),
title=_("Company Not Linked"),
)

View File

@@ -37,7 +37,7 @@ def get(
filters = frappe.parse_json(filters) or frappe.parse_json(chart.filters_json)
account = filters.get("account")
company = filters.get("company")
filters.get("company")
if not account and chart_name:
frappe.throw(
@@ -83,7 +83,6 @@ def build_result(account, dates, gl_entries):
# get balances in debit
for entry in gl_entries:
# entry date is after the current pointer, so move the pointer forward
while getdate(entry.posting_date) > result[date_index][0]:
date_index += 1
@@ -133,8 +132,6 @@ def get_dates_from_timegrain(from_date, to_date, timegrain):
dates = [get_period_ending(from_date, timegrain)]
while getdate(dates[-1]) < getdate(to_date):
date = get_period_ending(
add_to_date(dates[-1], years=years, months=months, days=days), timegrain
)
date = get_period_ending(add_to_date(dates[-1], years=years, months=months, days=days), timegrain)
dates.append(date)
return dates

View File

@@ -24,14 +24,10 @@ from erpnext.accounts.utils import get_account_currency
def validate_service_stop_date(doc):
"""Validates service_stop_date for Purchase Invoice and Sales Invoice"""
enable_check = (
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
)
enable_check = "enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
old_stop_dates = {}
old_doc = frappe.db.get_all(
"{0} Item".format(doc.doctype), {"parent": doc.name}, ["name", "service_stop_date"]
)
old_doc = frappe.db.get_all(f"{doc.doctype} Item", {"parent": doc.name}, ["name", "service_stop_date"])
for d in old_doc:
old_stop_dates[d.name] = d.service_stop_date or ""
@@ -62,16 +58,14 @@ def build_conditions(process_type, account, company):
)
if account:
conditions += "AND %s='%s'" % (deferred_account, account)
conditions += f"AND {deferred_account}={frappe.db.escape(account)}"
elif company:
conditions += f"AND p.company = {frappe.db.escape(company)}"
return conditions
def convert_deferred_expense_to_expense(
deferred_process, start_date=None, end_date=None, conditions=""
):
def convert_deferred_expense_to_expense(deferred_process, start_date=None, end_date=None, conditions=""):
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
if not start_date:
@@ -81,16 +75,14 @@ def convert_deferred_expense_to_expense(
# check for the purchase invoice for which GL entries has to be done
invoices = frappe.db.sql_list(
"""
f"""
select distinct item.parent
from `tabPurchase Invoice Item` item, `tabPurchase Invoice` p
where item.service_start_date<=%s and item.service_end_date>=%s
and item.enable_deferred_expense = 1 and item.parent=p.name
and item.docstatus = 1 and ifnull(item.amount, 0) > 0
{0}
""".format(
conditions
),
{conditions}
""",
(end_date, start_date),
) # nosec
@@ -103,9 +95,7 @@ def convert_deferred_expense_to_expense(
send_mail(deferred_process)
def convert_deferred_revenue_to_income(
deferred_process, start_date=None, end_date=None, conditions=""
):
def convert_deferred_revenue_to_income(deferred_process, start_date=None, end_date=None, conditions=""):
# book the expense/income on the last day, but it will be trigger on the 1st of month at 12:00 AM
if not start_date:
@@ -115,16 +105,14 @@ def convert_deferred_revenue_to_income(
# check for the sales invoice for which GL entries has to be done
invoices = frappe.db.sql_list(
"""
f"""
select distinct item.parent
from `tabSales Invoice Item` item, `tabSales Invoice` p
where item.service_start_date<=%s and item.service_end_date>=%s
and item.enable_deferred_revenue = 1 and item.parent=p.name
and item.docstatus = 1 and ifnull(item.amount, 0) > 0
{0}
""".format(
conditions
),
{conditions}
""",
(end_date, start_date),
) # nosec
@@ -243,9 +231,7 @@ def calculate_monthly_amount(
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
doc, item
)
base_amount = flt(
item.base_net_amount - already_booked_amount, item.precision("base_net_amount")
)
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
if account_currency == doc.company_currency:
amount = base_amount
else:
@@ -265,17 +251,13 @@ def calculate_amount(doc, item, last_gl_entry, total_days, total_booking_days, a
if account_currency == doc.company_currency:
amount = base_amount
else:
amount = flt(
item.net_amount * total_booking_days / flt(total_days), item.precision("net_amount")
)
amount = flt(item.net_amount * total_booking_days / flt(total_days), item.precision("net_amount"))
else:
already_booked_amount, already_booked_amount_in_account_currency = get_already_booked_amount(
doc, item
)
base_amount = flt(
item.base_net_amount - already_booked_amount, item.precision("base_net_amount")
)
base_amount = flt(item.base_net_amount - already_booked_amount, item.precision("base_net_amount"))
if account_currency == doc.company_currency:
amount = base_amount
else:
@@ -296,26 +278,22 @@ def get_already_booked_amount(doc, item):
gl_entries_details = frappe.db.sql(
"""
select sum({0}) as total_credit, sum({1}) as total_credit_in_account_currency, voucher_detail_no
select sum({}) as total_credit, sum({}) as total_credit_in_account_currency, voucher_detail_no
from `tabGL Entry` where company=%s and account=%s and voucher_type=%s and voucher_no=%s and voucher_detail_no=%s
and is_cancelled = 0
group by voucher_detail_no
""".format(
total_credit_debit, total_credit_debit_currency
),
""".format(total_credit_debit, total_credit_debit_currency),
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
as_dict=True,
)
journal_entry_details = frappe.db.sql(
"""
SELECT sum(c.{0}) as total_credit, sum(c.{1}) as total_credit_in_account_currency, reference_detail_no
SELECT sum(c.{}) as total_credit, sum(c.{}) as total_credit_in_account_currency, reference_detail_no
FROM `tabJournal Entry` p , `tabJournal Entry Account` c WHERE p.name = c.parent and
p.company = %s and c.account=%s and c.reference_type=%s and c.reference_name=%s and c.reference_detail_no=%s
and p.docstatus < 2 group by reference_detail_no
""".format(
total_credit_debit, total_credit_debit_currency
),
""".format(total_credit_debit, total_credit_debit_currency),
(doc.company, item.get(deferred_account), doc.doctype, doc.name, item.name),
as_dict=True,
)
@@ -337,9 +315,7 @@ def get_already_booked_amount(doc, item):
def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
enable_check = (
"enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
)
enable_check = "enable_deferred_revenue" if doc.doctype == "Sales Invoice" else "enable_deferred_expense"
accounts_frozen_upto = frappe.db.get_single_value("Accounts Settings", "acc_frozen_upto")
@@ -384,45 +360,45 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
)
if not amount:
return
gl_posting_date = end_date
prev_posting_date = None
# check if books nor frozen till endate:
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
prev_posting_date = end_date
if via_journal_entry:
book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
gl_posting_date = end_date
prev_posting_date = None
# check if books nor frozen till endate:
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
prev_posting_date = end_date
if via_journal_entry:
book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
# Returned in case of any errors because it tries to submit the same record again and again in case of errors
if frappe.flags.deferred_accounting_error:
@@ -440,9 +416,7 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
via_journal_entry = cint(
frappe.db.get_singles_value("Accounts Settings", "book_deferred_entries_via_journal_entry")
)
submit_journal_entry = cint(
frappe.db.get_singles_value("Accounts Settings", "submit_journal_entries")
)
submit_journal_entry = cint(frappe.db.get_singles_value("Accounts Settings", "submit_journal_entries"))
book_deferred_entries_based_on = frappe.db.get_singles_value(
"Accounts Settings", "book_deferred_entries_based_on"
)
@@ -462,9 +436,7 @@ def process_deferred_accounting(posting_date=None):
posting_date = today()
if not cint(
frappe.db.get_singles_value(
"Accounts Settings", "automatically_process_deferred_accounting_entry"
)
frappe.db.get_singles_value("Accounts Settings", "automatically_process_deferred_accounting_entry")
):
return
@@ -587,16 +559,13 @@ def book_revenue_via_journal_entry(
deferred_process=None,
submit="No",
):
if amount == 0:
return
journal_entry = frappe.new_doc("Journal Entry")
journal_entry.posting_date = posting_date
journal_entry.company = doc.company
journal_entry.voucher_type = (
"Deferred Revenue" if doc.doctype == "Sales Invoice" else "Deferred Expense"
)
journal_entry.voucher_type = "Deferred Revenue" if doc.doctype == "Sales Invoice" else "Deferred Expense"
journal_entry.process_deferred_accounting = deferred_process
debit_entry = {
@@ -645,7 +614,6 @@ def book_revenue_via_journal_entry(
def get_deferred_booking_accounts(doctype, voucher_detail_no, dr_or_cr):
if doctype == "Sales Invoice":
credit_account, debit_account = frappe.db.get_value(
"Sales Invoice Item",

View File

@@ -94,8 +94,8 @@ frappe.ui.form.on("Account", {
function () {
frappe.route_options = {
account: frm.doc.name,
from_date: frappe.sys_defaults.year_start_date,
to_date: frappe.sys_defaults.year_end_date,
from_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
to_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
company: frm.doc.company,
};
frappe.set_route("query-report", "General Ledger");

View File

@@ -29,7 +29,7 @@ class Account(NestedSet):
if frappe.local.flags.ignore_update_nsm:
return
else:
super(Account, self).on_update()
super().on_update()
def onload(self):
frozen_accounts_modifier = frappe.db.get_value(
@@ -87,9 +87,7 @@ class Account(NestedSet):
def set_root_and_report_type(self):
if self.parent_account:
par = frappe.db.get_value(
"Account", self.parent_account, ["report_type", "root_type"], as_dict=1
)
par = frappe.db.get_value("Account", self.parent_account, ["report_type", "root_type"], as_dict=1)
if par.report_type:
self.report_type = par.report_type
@@ -144,9 +142,7 @@ class Account(NestedSet):
def validate_root_company_and_sync_account_to_children(self):
# ignore validation while creating new compnay or while syncing to child companies
if (
frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation
):
if frappe.local.flags.ignore_root_company_validation or self.flags.ignore_root_company_validation:
return
ancestors = get_root_company(self.company)
if ancestors:
@@ -341,7 +337,7 @@ class Account(NestedSet):
if self.check_gle_exists():
throw(_("Account with existing transaction can not be deleted"))
super(Account, self).on_trash(True)
super().on_trash(True)
@frappe.whitelist()
@@ -349,9 +345,8 @@ class Account(NestedSet):
def get_parent_account(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(
"""select name from tabAccount
where is_group = 1 and docstatus != 2 and company = %s
and %s like %s order by name limit %s offset %s"""
% ("%s", searchfield, "%s", "%s", "%s"),
where is_group = 1 and docstatus != 2 and company = {}
and {} like {} order by name limit {} offset {}""".format("%s", searchfield, "%s", "%s", "%s"),
(filters["company"], "%%%s%%" % txt, page_len, start),
as_list=1,
)
@@ -409,9 +404,7 @@ def update_account_number(name, account_name, account_number=None, from_descenda
if not account:
return
old_acc_name, old_acc_number = frappe.db.get_value(
"Account", name, ["account_name", "account_number"]
)
old_acc_name, old_acc_number = frappe.db.get_value("Account", name, ["account_name", "account_number"])
# check if account exists in parent company
ancestors = get_ancestors_of("Company", account.company)
@@ -519,7 +512,5 @@ def sync_update_account_number_in_child(
if old_acc_number:
filters["account_number"] = old_acc_number
for d in frappe.db.get_values(
"Account", filters=filters, fieldname=["company", "name"], as_dict=True
):
for d in frappe.db.get_values("Account", filters=filters, fieldname=["company", "name"], as_dict=True):
update_account_number(d["name"], account_name, account_number, from_descendant=True)

View File

@@ -279,8 +279,8 @@ frappe.treeview_settings["Account"] = {
click: function (node, btn) {
frappe.route_options = {
account: node.label,
from_date: frappe.sys_defaults.year_start_date,
to_date: frappe.sys_defaults.year_end_date,
from_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[1],
to_date: erpnext.utils.get_fiscal_year(frappe.datetime.get_today(), true)[2],
company:
frappe.treeview_settings["Account"].treeview.page.fields_dict.company.get_value(),
};

View File

@@ -31,7 +31,6 @@ def create_charts(
"tax_rate",
"account_currency",
]:
account_number = cstr(child.get("account_number")).strip()
account_name, account_name_in_db = add_suffix_if_duplicate(
account_name, account_number, accounts
@@ -39,7 +38,9 @@ def create_charts(
is_group = identify_is_group(child)
report_type = (
"Balance Sheet" if root_type in ["Asset", "Liability", "Equity"] else "Profit and Loss"
"Balance Sheet"
if root_type in ["Asset", "Liability", "Equity"]
else "Profit and Loss"
)
account = frappe.get_doc(
@@ -141,7 +142,7 @@ def get_chart(chart_template, existing_company=None):
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if fname.endswith(".json"):
with open(os.path.join(path, fname), "r") as f:
with open(os.path.join(path, fname)) as f:
chart = f.read()
if chart and json.loads(chart).get("name") == chart_template:
return json.loads(chart).get("tree")
@@ -173,7 +174,7 @@ def get_charts_for_country(country, with_standard=False):
for fname in os.listdir(path):
fname = frappe.as_unicode(fname)
if (fname.startswith(country_code) or fname.startswith(country)) and fname.endswith(".json"):
with open(os.path.join(path, fname), "r") as f:
with open(os.path.join(path, fname)) as f:
_get_chart_name(f.read())
# if more than one charts, returned then add the standard
@@ -247,7 +248,13 @@ def validate_bank_account(coa, bank_account):
def _get_account_names(account_master):
for account_name, child in account_master.items():
if account_name not in ["account_number", "account_type", "root_type", "is_group", "tax_rate"]:
if account_name not in [
"account_number",
"account_type",
"root_type",
"is_group",
"tax_rate",
]:
accounts.append(account_name)
_get_account_names(child)

View File

@@ -26,7 +26,7 @@ def go():
default_account_types = get_default_account_types()
country_dirs = []
for basepath, folders, files in os.walk(path):
for basepath, _folders, _files in os.walk(path):
basename = os.path.basename(basepath)
if basename.startswith("l10n_"):
country_dirs.append(basename)
@@ -35,9 +35,7 @@ def go():
accounts, charts = {}, {}
country_path = os.path.join(path, country_dir)
manifest = ast.literal_eval(open(os.path.join(country_path, "__openerp__.py")).read())
data_files = (
manifest.get("data", []) + manifest.get("init_xml", []) + manifest.get("update_xml", [])
)
data_files = manifest.get("data", []) + manifest.get("init_xml", []) + manifest.get("update_xml", [])
files_path = [os.path.join(country_path, d) for d in data_files]
xml_roots = get_xml_roots(files_path)
csv_content = get_csv_contents(files_path)
@@ -90,10 +88,10 @@ def get_csv_contents(files_path):
fname = os.path.basename(filepath)
for file_type in ["account.account.template", "account.account.type", "account.chart.template"]:
if fname.startswith(file_type) and fname.endswith(".csv"):
with open(filepath, "r") as csvfile:
with open(filepath) as csvfile:
try:
csv_content.setdefault(file_type, []).append(read_csv_content(csvfile.read()))
except Exception as e:
except Exception:
continue
return csv_content
@@ -138,7 +136,7 @@ def get_account_types(root_list, csv_content, prefix=None):
if csv_content and csv_content[0][0] == "id":
for row in csv_content[1:]:
row_dict = dict(zip(csv_content[0], row))
row_dict = dict(zip(csv_content[0], row, strict=False))
data = {}
if row_dict.get("code") and account_type_map.get(row_dict["code"]):
data["account_type"] = account_type_map[row_dict["code"]]
@@ -150,7 +148,7 @@ def get_account_types(root_list, csv_content, prefix=None):
def make_maps_for_xml(xml_roots, account_types, country_dir):
"""make maps for `charts` and `accounts`"""
for model, root_list in xml_roots.items():
for _model, root_list in xml_roots.items():
for root in root_list:
for node in root[0].findall("record"):
if node.get("model") == "account.account.template":
@@ -186,7 +184,7 @@ def make_maps_for_xml(xml_roots, account_types, country_dir):
def make_maps_for_csv(csv_content, account_types, country_dir):
for content in csv_content.get("account.account.template", []):
for row in content[1:]:
data = dict(zip(content[0], row))
data = dict(zip(content[0], row, strict=False))
account = {
"name": data.get("name"),
"parent_id": data.get("parent_id:id") or data.get("parent_id/id"),
@@ -206,7 +204,7 @@ def make_maps_for_csv(csv_content, account_types, country_dir):
for content in csv_content.get("account.chart.template", []):
for row in content[1:]:
if row:
data = dict(zip(content[0], row))
data = dict(zip(content[0], row, strict=False))
charts.setdefault(data.get("id"), {}).update(
{
"account_root_id": data.get("account_root_id:id") or data.get("account_root_id/id"),
@@ -241,7 +239,7 @@ def make_charts():
if not src.get("name") or not src.get("account_root_id"):
continue
if not src["account_root_id"] in accounts:
if src["account_root_id"] not in accounts:
continue
filename = src["id"][5:] + "_" + chart_id
@@ -255,14 +253,20 @@ def make_charts():
for key, val in chart["tree"].items():
if key in ["name", "parent_id"]:
chart["tree"].pop(key)
if type(val) == dict:
if isinstance(val, dict):
val["root_type"] = ""
if chart:
fpath = os.path.join(
"erpnext", "erpnext", "accounts", "doctype", "account", "chart_of_accounts", filename + ".json"
"erpnext",
"erpnext",
"accounts",
"doctype",
"account",
"chart_of_accounts",
filename + ".json",
)
with open(fpath, "r") as chartfile:
with open(fpath) as chartfile:
old_content = chartfile.read()
if not old_content or (
json.loads(old_content).get("is_active", "No") == "No"

View File

@@ -260,28 +260,20 @@ class TestAccount(unittest.TestCase):
acc.insert()
self.assertTrue(
frappe.db.exists(
"Account", {"account_name": "Test Group Account", "company": "_Test Company 4"}
)
frappe.db.exists("Account", {"account_name": "Test Group Account", "company": "_Test Company 4"})
)
self.assertTrue(
frappe.db.exists(
"Account", {"account_name": "Test Group Account", "company": "_Test Company 5"}
)
frappe.db.exists("Account", {"account_name": "Test Group Account", "company": "_Test Company 5"})
)
# Try renaming child company account
acc_tc_5 = frappe.db.get_value(
"Account", {"account_name": "Test Group Account", "company": "_Test Company 5"}
)
self.assertRaises(
frappe.ValidationError, update_account_number, acc_tc_5, "Test Modified Account"
)
self.assertRaises(frappe.ValidationError, update_account_number, acc_tc_5, "Test Modified Account")
# Rename child company account with allow_account_creation_against_child_company enabled
frappe.db.set_value(
"Company", "_Test Company 5", "allow_account_creation_against_child_company", 1
)
frappe.db.set_value("Company", "_Test Company 5", "allow_account_creation_against_child_company", 1)
update_account_number(acc_tc_5, "Test Modified Account")
self.assertTrue(
@@ -290,9 +282,7 @@ class TestAccount(unittest.TestCase):
)
)
frappe.db.set_value(
"Company", "_Test Company 5", "allow_account_creation_against_child_company", 0
)
frappe.db.set_value("Company", "_Test Company 5", "allow_account_creation_against_child_company", 0)
to_delete = [
"Test Group Account - _TC3",
@@ -317,9 +307,7 @@ class TestAccount(unittest.TestCase):
self.assertEqual(acc.account_currency, "INR")
# Make a JV against this account
make_journal_entry(
"Test Currency Account - _TC", "Miscellaneous Expenses - _TC", 100, submit=True
)
make_journal_entry("Test Currency Account - _TC", "Miscellaneous Expenses - _TC", 100, submit=True)
acc.account_currency = "USD"
self.assertRaises(frappe.ValidationError, acc.save)

View File

@@ -17,16 +17,12 @@ class AccountClosingBalance(Document):
def make_closing_entries(closing_entries, voucher_name, company, closing_date):
accounting_dimensions = get_accounting_dimensions()
previous_closing_entries = get_previous_closing_entries(
company, closing_date, accounting_dimensions
)
previous_closing_entries = get_previous_closing_entries(company, closing_date, accounting_dimensions)
combined_entries = closing_entries + previous_closing_entries
merged_entries = aggregate_with_last_account_closing_balance(
combined_entries, accounting_dimensions
)
merged_entries = aggregate_with_last_account_closing_balance(combined_entries, accounting_dimensions)
for key, value in merged_entries.items():
for _key, value in merged_entries.items():
cle = frappe.new_doc("Account Closing Balance")
cle.update(value)
cle.update(value["dimensions"])

View File

@@ -17,7 +17,8 @@ class AccountingDimension(Document):
self.set_fieldname_and_label()
def validate(self):
if self.document_type in core_doctypes_list + (
if self.document_type in (
*core_doctypes_list,
"Accounting Dimension",
"Project",
"Cost Center",
@@ -25,13 +26,10 @@ class AccountingDimension(Document):
"Company",
"Account",
):
msg = _("Not allowed to create accounting dimension for {0}").format(self.document_type)
frappe.throw(msg)
exists = frappe.db.get_value(
"Accounting Dimension", {"document_type": self.document_type}, ["name"]
)
exists = frappe.db.get_value("Accounting Dimension", {"document_type": self.document_type}, ["name"])
if exists and self.is_new():
frappe.throw(_("Document Type already used as a dimension"))
@@ -89,7 +87,6 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
count = 0
for doctype in doclist:
if (doc_count + 1) % 2 == 0:
insert_after_field = "dimension_col_break"
else:
@@ -123,7 +120,7 @@ def add_dimension_to_budget_doctype(df, doc):
df.update(
{
"insert_after": "cost_center",
"depends_on": "eval:doc.budget_against == '{0}'".format(doc.document_type),
"depends_on": f"eval:doc.budget_against == '{doc.document_type}'",
}
)
@@ -157,19 +154,17 @@ def delete_accounting_dimension(doc):
frappe.db.sql(
"""
DELETE FROM `tabCustom Field`
WHERE fieldname = %s
AND dt IN (%s)"""
% ("%s", ", ".join(["%s"] * len(doclist))), # nosec
tuple([doc.fieldname] + doclist),
WHERE fieldname = {}
AND dt IN ({})""".format("%s", ", ".join(["%s"] * len(doclist))), # nosec
tuple([doc.fieldname, *doclist]),
)
frappe.db.sql(
"""
DELETE FROM `tabProperty Setter`
WHERE field_name = %s
AND doc_type IN (%s)"""
% ("%s", ", ".join(["%s"] * len(doclist))), # nosec
tuple([doc.fieldname] + doclist),
WHERE field_name = {}
AND doc_type IN ({})""".format("%s", ", ".join(["%s"] * len(doclist))), # nosec
tuple([doc.fieldname, *doclist]),
)
budget_against_property = frappe.get_doc("Property Setter", "Budget-budget_against-options")
@@ -218,7 +213,6 @@ def get_doctypes_with_dimensions():
def get_accounting_dimensions(as_list=True, filters=None):
if not filters:
filters = {"disabled": 0}
@@ -249,7 +243,6 @@ def get_checks_for_pl_and_bs_accounts():
def get_dimension_with_children(doctype, dimensions):
if isinstance(dimensions, str):
dimensions = [dimensions]
@@ -257,9 +250,7 @@ def get_dimension_with_children(doctype, dimensions):
for dimension in dimensions:
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
children = frappe.get_all(
doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft"
)
children = frappe.get_all(doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft")
all_dimensions += [c.name for c in children]
return all_dimensions

View File

@@ -57,9 +57,7 @@ class TestAccountingDimensionFilter(unittest.TestCase):
def create_accounting_dimension_filter():
if not frappe.db.get_value(
"Accounting Dimension Filter", {"accounting_dimension": "Cost Center"}
):
if not frappe.db.get_value("Accounting Dimension Filter", {"accounting_dimension": "Cost Center"}):
frappe.get_doc(
{
"doctype": "Accounting Dimension Filter",

View File

@@ -67,7 +67,10 @@ class AccountingPeriod(Document):
for doctype_for_closing in self.get_doctypes_for_closing():
self.append(
"closed_documents",
{"document_type": doctype_for_closing.document_type, "closed": doctype_for_closing.closed},
{
"document_type": doctype_for_closing.document_type,
"closed": doctype_for_closing.closed,
},
)

View File

@@ -34,9 +34,7 @@ class TestAccountingPeriod(unittest.TestCase):
ap1 = create_accounting_period(period_name="Test Accounting Period 2")
ap1.save()
doc = create_sales_invoice(
do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC"
)
doc = create_sales_invoice(do_not_save=1, cost_center="_Test Company - _TC", warehouse="Stores - _TC")
self.assertRaises(ClosedAccountingPeriod, doc.save)
def tearDown(self):

View File

@@ -469,7 +469,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-20 09:37:47.650347",
"modified": "2024-01-22 12:10:10.151819",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -208,8 +208,49 @@
"label": "Disabled"
}
],
"links": [],
"modified": "2024-02-02 17:50:09.768835",
"links": [
{
"group": "Transactions",
"link_doctype": "Payment Request",
"link_fieldname": "bank_account"
},
{
"group": "Transactions",
"link_doctype": "Payment Order",
"link_fieldname": "bank_account"
},
{
"group": "Transactions",
"link_doctype": "Bank Guarantee",
"link_fieldname": "bank_account"
},
{
"group": "Transactions",
"link_doctype": "Bank Transaction",
"link_fieldname": "bank_account"
},
{
"group": "Accounting",
"link_doctype": "Payment Entry",
"link_fieldname": "bank_account"
},
{
"group": "Accounting",
"link_doctype": "Journal Entry",
"link_fieldname": "bank_account"
},
{
"group": "Party",
"link_doctype": "Customer",
"link_fieldname": "default_bank_account"
},
{
"group": "Party",
"link_doctype": "Supplier",
"link_fieldname": "default_bank_account"
}
],
"modified": "2024-10-30 09:41:14.113414",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Account",
@@ -246,4 +287,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -1,20 +0,0 @@
from frappe import _
def get_data():
return {
"fieldname": "bank_account",
"non_standard_fieldnames": {
"Customer": "default_bank_account",
"Supplier": "default_bank_account",
},
"transactions": [
{
"label": _("Payments"),
"items": ["Payment Entry", "Payment Request", "Payment Order", "Payroll Entry"],
},
{"label": _("Party"), "items": ["Customer", "Supplier"]},
{"items": ["Bank Guarantee"]},
{"items": ["Journal Entry"]},
],
}

View File

@@ -37,11 +37,11 @@ class TestBankAccount(unittest.TestCase):
try:
bank_account.validate_iban()
except ValidationError:
msg = "BankAccount.validate_iban() failed for valid IBAN {}".format(iban)
msg = f"BankAccount.validate_iban() failed for valid IBAN {iban}"
self.fail(msg=msg)
for not_iban in invalid_ibans:
bank_account.iban = not_iban
msg = "BankAccount.validate_iban() accepted invalid IBAN {}".format(not_iban)
msg = f"BankAccount.validate_iban() accepted invalid IBAN {not_iban}"
with self.assertRaises(ValidationError, msg=msg):
bank_account.validate_iban()

View File

@@ -36,8 +36,12 @@ frappe.ui.form.on("Bank Clearance", {
refresh: function (frm) {
frm.disable_save();
frm.add_custom_button(__("Get Payment Entries"), () => frm.trigger("get_payment_entries"));
frm.change_custom_button_type("Get Payment Entries", null, "primary");
frm.change_custom_button_type(__("Get Payment Entries"), null, "primary");
if (frm.doc.payment_entries.length) {
frm.add_custom_button(__("Update Clearance Date"), () => frm.trigger("update_clearance_date"));
frm.change_custom_button_type(__("Get Payment Entries"), null, "default");
frm.change_custom_button_type(__("Update Clearance Date"), null, "primary");
}
},
update_clearance_date: function (frm) {
@@ -45,13 +49,7 @@ frappe.ui.form.on("Bank Clearance", {
method: "update_clearance_date",
doc: frm.doc,
callback: function (r, rt) {
frm.refresh_field("payment_entries");
frm.refresh_fields();
if (!frm.doc.payment_entries.length) {
frm.change_custom_button_type("Get Payment Entries", null, "primary");
frm.change_custom_button_type("Update Clearance Date", null, "default");
}
frm.refresh();
},
});
},
@@ -60,17 +58,8 @@ frappe.ui.form.on("Bank Clearance", {
return frappe.call({
method: "get_payment_entries",
doc: frm.doc,
callback: function (r, rt) {
frm.refresh_field("payment_entries");
if (frm.doc.payment_entries.length) {
frm.add_custom_button(__("Update Clearance Date"), () =>
frm.trigger("update_clearance_date")
);
frm.change_custom_button_type("Get Payment Entries", null, "default");
frm.change_custom_button_type("Update Clearance Date", null, "primary");
}
callback: function () {
frm.refresh();
},
});
},

View File

@@ -6,7 +6,7 @@ import frappe
from frappe import _, msgprint
from frappe.model.document import Document
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, fmt_money, getdate
from frappe.utils import flt, fmt_money, get_link_to_form, getdate
import erpnext
@@ -27,7 +27,7 @@ class BankClearance(Document):
condition = "and (clearance_date IS NULL or clearance_date='0000-00-00')"
journal_entries = frappe.db.sql(
"""
f"""
select
"Journal Entry" as payment_document, t1.name as payment_entry,
t1.cheque_no as cheque_number, t1.cheque_date,
@@ -41,9 +41,7 @@ class BankClearance(Document):
and ifnull(t1.is_opening, 'No') = 'No' {condition}
group by t2.account, t1.name
order by t1.posting_date ASC, t1.name DESC
""".format(
condition=condition
),
""",
{"account": self.account, "from": self.from_date, "to": self.to_date},
as_dict=1,
)
@@ -52,12 +50,12 @@ class BankClearance(Document):
condition += "and bank_account = %(bank_account)s"
payment_entries = frappe.db.sql(
"""
f"""
select
"Payment Entry" as payment_document, name as payment_entry,
reference_no as cheque_number, reference_date as cheque_date,
if(paid_from=%(account)s, paid_amount + total_taxes_and_charges, 0) as credit,
if(paid_from=%(account)s, 0, received_amount) as debit,
if(paid_from=%(account)s, 0, received_amount + total_taxes_and_charges) as debit,
posting_date, ifnull(party,if(paid_from=%(account)s,paid_to,paid_from)) as against_account, clearance_date,
if(paid_to=%(account)s, paid_to_account_currency, paid_from_account_currency) as account_currency
from `tabPayment Entry`
@@ -67,9 +65,7 @@ class BankClearance(Document):
{condition}
order by
posting_date ASC, name DESC
""".format(
condition=condition
),
""",
{
"account": self.account,
"from": self.from_date,
@@ -132,11 +128,9 @@ class BankClearance(Document):
query = query.where(loan_repayment.clearance_date.isnull())
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
query = query.where((loan_repayment.repay_from_salary == 0))
query = query.where(loan_repayment.repay_from_salary == 0)
query = query.orderby(loan_repayment.posting_date).orderby(
loan_repayment.name, order=frappe.qb.desc
)
query = query.orderby(loan_repayment.posting_date).orderby(loan_repayment.name, order=frappe.qb.desc)
loan_repayments = query.run(as_dict=True)
@@ -216,8 +210,11 @@ class BankClearance(Document):
if d.cheque_date and getdate(d.clearance_date) < getdate(d.cheque_date):
frappe.throw(
_("Row #{0}: Clearance date {1} cannot be before Cheque Date {2}").format(
d.idx, d.clearance_date, d.cheque_date
_("Row #{0}: For {1} Clearance date {2} cannot be before Cheque Date {3}").format(
d.idx,
get_link_to_form(d.payment_document, d.payment_entry),
d.clearance_date,
d.cheque_date,
)
)

View File

@@ -61,9 +61,7 @@ def get_bank_transactions(bank_account, from_date=None, to_date=None):
def get_account_balance(bank_account, till_date):
# returns account balance till the specified date
account = frappe.db.get_value("Bank Account", bank_account, "account")
filters = frappe._dict(
{"account": account, "report_date": till_date, "include_pos_transactions": 1}
)
filters = frappe._dict({"account": account, "report_date": till_date, "include_pos_transactions": 1})
data = get_entries(filters)
balance_as_per_system = get_balance_on(filters["account"], filters["report_date"])
@@ -76,10 +74,7 @@ def get_account_balance(bank_account, till_date):
amounts_not_reflected_in_system = get_amounts_not_reflected_in_system(filters)
bank_bal = (
flt(balance_as_per_system)
- flt(total_debit)
+ flt(total_credit)
+ amounts_not_reflected_in_system
flt(balance_as_per_system) - flt(total_debit) + flt(total_credit) + amounts_not_reflected_in_system
)
return bank_bal
@@ -377,12 +372,13 @@ def auto_reconcile_vouchers(
)
transaction = frappe.get_doc("Bank Transaction", transaction.name)
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
matched_trans = 0
for voucher in vouchers:
gl_entry = frappe.db.get_value(
"GL Entry",
dict(
account=account, voucher_type=voucher["payment_doctype"], voucher_no=voucher["payment_name"]
account=account,
voucher_type=voucher["payment_doctype"],
voucher_no=voucher["payment_name"],
),
["credit", "debit"],
as_dict=1,
@@ -731,7 +727,7 @@ def get_lr_matching_query(bank_account, exact_match, filters):
)
if frappe.db.has_column("Loan Repayment", "repay_from_salary"):
query = query.where((loan_repayment.repay_from_salary == 0))
query = query.where(loan_repayment.repay_from_salary == 0)
if exact_match:
query.where(loan_repayment.amount_paid == filters.get("amount"))
@@ -764,7 +760,7 @@ def get_pe_matching_query(
if cint(filter_by_reference_date):
filter_by_date = f"AND reference_date between '{from_reference_date}' and '{to_reference_date}'"
order_by = " reference_date"
if frappe.flags.auto_reconcile_vouchers == True:
if frappe.flags.auto_reconcile_vouchers is True:
filter_by_reference_no = f"AND reference_no = '{transaction.reference_number}'"
return f"""
SELECT
@@ -815,7 +811,7 @@ def get_je_matching_query(
if cint(filter_by_reference_date):
filter_by_date = f"AND je.cheque_date between '{from_reference_date}' and '{to_reference_date}'"
order_by = " je.cheque_date"
if frappe.flags.auto_reconcile_vouchers == True:
if frappe.flags.auto_reconcile_vouchers is True:
filter_by_reference_no = f"AND je.cheque_no = '{transaction.reference_number}'"
return f"""
SELECT

View File

@@ -21,7 +21,7 @@ INVALID_VALUES = ("", None)
class BankStatementImport(DataImport):
def __init__(self, *args, **kwargs):
super(BankStatementImport, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def validate(self):
doc_before_save = self.get_doc_before_save()
@@ -30,7 +30,6 @@ class BankStatementImport(DataImport):
or (doc_before_save and doc_before_save.import_file != self.import_file)
or (doc_before_save and doc_before_save.google_sheets_url != self.google_sheets_url)
):
template_options_dict = {}
column_to_field_map = {}
bank = frappe.get_doc("Bank", self.bank)
@@ -45,7 +44,6 @@ class BankStatementImport(DataImport):
self.validate_google_sheets_url()
def start_import(self):
preview = frappe.get_doc("Bank Statement Import", self.name).get_preview_from_template(
self.import_file, self.google_sheets_url
)
@@ -102,7 +100,7 @@ def download_errored_template(data_import_name):
def parse_data_from_template(raw_data):
data = []
for i, row in enumerate(raw_data):
for _i, row in enumerate(raw_data):
if all(v in INVALID_VALUES for v in row):
# empty row
continue
@@ -112,9 +110,7 @@ def parse_data_from_template(raw_data):
return data
def start_import(
data_import, bank_account, import_file_path, google_sheets_url, bank, template_options
):
def start_import(data_import, bank_account, import_file_path, google_sheets_url, bank, template_options):
"""This method runs in background job"""
update_mapping_db(bank, template_options)

View File

@@ -1,5 +1,3 @@
from typing import Tuple, Union
import frappe
from frappe.utils import flt
from rapidfuzz import fuzz, process
@@ -19,7 +17,7 @@ class AutoMatchParty:
def get(self, key):
return self.__dict__.get(key, None)
def match(self) -> Union[Tuple, None]:
def match(self) -> tuple | None:
result = None
result = AutoMatchbyAccountIBAN(
bank_party_account_number=self.bank_party_account_number,
@@ -50,7 +48,7 @@ class AutoMatchbyAccountIBAN:
result = self.match_account_in_party()
return result
def match_account_in_party(self) -> Union[Tuple, None]:
def match_account_in_party(self) -> tuple | None:
"""Check if there is a IBAN/Account No. match in Customer/Supplier/Employee"""
result = None
parties = get_parties_in_order(self.deposit)
@@ -97,7 +95,7 @@ class AutoMatchbyPartyNameDescription:
def get(self, key):
return self.__dict__.get(key, None)
def match(self) -> Union[Tuple, None]:
def match(self) -> tuple | None:
# fuzzy search by customer/supplier & employee
if not (self.bank_party_name or self.description):
return None
@@ -105,7 +103,7 @@ class AutoMatchbyPartyNameDescription:
result = self.match_party_name_desc_in_party()
return result
def match_party_name_desc_in_party(self) -> Union[Tuple, None]:
def match_party_name_desc_in_party(self) -> tuple | None:
"""Fuzzy search party name and/or description against parties in the system"""
result = None
parties = get_parties_in_order(self.deposit)
@@ -130,7 +128,7 @@ class AutoMatchbyPartyNameDescription:
return result
def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]:
def fuzzy_search_and_return_result(self, party, names, field) -> tuple | None:
skip = False
result = process.extract(
query=self.get(field),
@@ -147,7 +145,7 @@ class AutoMatchbyPartyNameDescription:
party_name,
), skip
def process_fuzzy_result(self, result: Union[list, None]):
def process_fuzzy_result(self, result: list | None):
"""
If there are multiple valid close matches return None as result may be faulty.
Return the result only if one accurate match stands out.

View File

@@ -156,13 +156,17 @@ class BankTransaction(StatusUpdater):
if self.party_type and self.party:
return
result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
result = None
try:
result = AutoMatchParty(
bank_party_account_number=self.bank_party_account_number,
bank_party_iban=self.bank_party_iban,
bank_party_name=self.bank_party_name,
description=self.description,
deposit=self.deposit,
).match()
except Exception:
frappe.log_error(title=_("Error in party matching for Bank Transaction {0}").format(self.name))
if result:
party_type, party = result
@@ -186,9 +190,7 @@ def get_clearance_details(transaction, payment_entry):
"""
gl_bank_account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")
gles = get_related_bank_gl_entries(payment_entry.payment_document, payment_entry.payment_entry)
bt_allocations = get_total_allocated_amount(
payment_entry.payment_document, payment_entry.payment_entry
)
bt_allocations = get_total_allocated_amount(payment_entry.payment_document, payment_entry.payment_entry)
unallocated_amount = min(
transaction.unallocated_amount,
@@ -286,7 +288,6 @@ def get_total_allocated_amount(doctype, docname):
def get_paid_amount(payment_entry, currency, gl_bank_account):
if payment_entry.payment_document in ["Payment Entry", "Sales Invoice", "Purchase Invoice"]:
paid_amount_field = "paid_amount"
if payment_entry.payment_document == "Payment Entry":
doc = frappe.get_doc("Payment Entry", payment_entry.payment_entry)
@@ -325,9 +326,7 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
)
elif payment_entry.payment_document == "Loan Repayment":
return frappe.db.get_value(
payment_entry.payment_document, payment_entry.payment_entry, "amount_paid"
)
return frappe.db.get_value(payment_entry.payment_document, payment_entry.payment_entry, "amount_paid")
elif payment_entry.payment_document == "Bank Transaction":
dep, wth = frappe.db.get_value(
@@ -337,9 +336,7 @@ def get_paid_amount(payment_entry, currency, gl_bank_account):
else:
frappe.throw(
"Please reconcile {0}: {1} manually".format(
payment_entry.payment_document, payment_entry.payment_entry
)
f"Please reconcile {payment_entry.payment_document}: {payment_entry.payment_entry} manually"
)

View File

@@ -18,12 +18,12 @@ def upload_bank_statement():
fcontent = frappe.local.uploaded_file
fname = frappe.local.uploaded_filename
if frappe.safe_encode(fname).lower().endswith("csv".encode("utf-8")):
if frappe.safe_encode(fname).lower().endswith(b"csv"):
from frappe.utils.csvutils import read_csv_content
rows = read_csv_content(fcontent, False)
elif frappe.safe_encode(fname).lower().endswith("xlsx".encode("utf-8")):
elif frappe.safe_encode(fname).lower().endswith(b"xlsx"):
from frappe.utils.xlsxutils import read_xlsx_file_from_attached_file
rows = read_xlsx_file_from_attached_file(fcontent=fcontent)

View File

@@ -430,9 +430,7 @@ def add_vouchers(gl_account="_Test Bank - _TC"):
mode_of_payment = frappe.get_doc({"doctype": "Mode of Payment", "name": "Cash"})
if not frappe.db.get_value(
"Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}
):
if not frappe.db.get_value("Mode of Payment Account", {"company": "_Test Company", "parent": "Cash"}):
mode_of_payment.append("accounts", {"company": "_Test Company", "default_account": gl_account})
mode_of_payment.save()

View File

@@ -14,26 +14,6 @@ from frappe.utils.data import guess_date_format
class BisectAccountingStatements(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
algorithm: DF.Literal["BFS", "DFS"]
b_s_summary: DF.Float
company: DF.Link | None
current_from_date: DF.Datetime | None
current_node: DF.Link | None
current_to_date: DF.Datetime | None
difference: DF.Float
from_date: DF.Datetime | None
p_l_summary: DF.Float
to_date: DF.Datetime | None
# end: auto-generated types
def validate(self):
self.validate_dates()

View File

@@ -40,10 +40,11 @@ class Budget(Document):
select
b.name, ba.account from `tabBudget` b, `tabBudget Account` ba
where
ba.parent = b.name and b.docstatus < 2 and b.company = %s and %s=%s and
b.fiscal_year=%s and b.name != %s and ba.account in (%s) """
% ("%s", budget_against_field, "%s", "%s", "%s", ",".join(["%s"] * len(accounts))),
(self.company, budget_against, self.fiscal_year, self.name) + tuple(accounts),
ba.parent = b.name and b.docstatus < 2 and b.company = {} and {}={} and
b.fiscal_year={} and b.name != {} and ba.account in ({}) """.format(
"%s", budget_against_field, "%s", "%s", "%s", ",".join(["%s"] * len(accounts))
),
(self.company, budget_against, self.fiscal_year, self.name, *tuple(accounts)),
as_dict=1,
)
@@ -66,12 +67,14 @@ class Budget(Document):
if account_details.is_group:
frappe.throw(_("Budget cannot be assigned against Group Account {0}").format(d.account))
elif account_details.company != self.company:
frappe.throw(_("Account {0} does not belongs to company {1}").format(d.account, self.company))
frappe.throw(
_("Account {0} does not belongs to company {1}").format(d.account, self.company)
)
elif account_details.report_type != "Profit and Loss":
frappe.throw(
_("Budget cannot be assigned against {0}, as it's not an Income or Expense account").format(
d.account
)
_(
"Budget cannot be assigned against {0}, as it's not an Income or Expense account"
).format(d.account)
)
if d.account in account_list:
@@ -118,9 +121,7 @@ def validate_expense_against_budget(args, expense_amount=0):
"Company", args.get("company"), "exception_budget_approver_role"
)
if not frappe.get_cached_value(
"Budget", {"fiscal_year": args.fiscal_year, "company": args.company}
): # nosec
if not frappe.get_cached_value("Budget", {"fiscal_year": args.fiscal_year, "company": args.company}): # nosec
return
if not args.account:
@@ -151,30 +152,24 @@ def validate_expense_against_budget(args, expense_amount=0):
and args.account
and (frappe.get_cached_value("Account", args.account, "root_type") == "Expense")
):
doctype = dimension.get("document_type")
if frappe.get_cached_value("DocType", doctype, "is_tree"):
lft, rgt = frappe.get_cached_value(doctype, args.get(budget_against), ["lft", "rgt"])
condition = """and exists(select name from `tab%s`
where lft<=%s and rgt>=%s and name=b.%s)""" % (
doctype,
lft,
rgt,
budget_against,
) # nosec
condition = f"""and exists(select name from `tab{doctype}`
where lft<={lft} and rgt>={rgt} and name=b.{budget_against})""" # nosec
args.is_tree = True
else:
condition = "and b.%s=%s" % (budget_against, frappe.db.escape(args.get(budget_against)))
condition = f"and b.{budget_against}={frappe.db.escape(args.get(budget_against))}"
args.is_tree = False
args.budget_against_field = budget_against
args.budget_against_doctype = doctype
budget_records = frappe.db.sql(
"""
f"""
select
b.{budget_against_field} as budget_against, ba.budget_amount, b.monthly_distribution,
b.{budget_against} as budget_against, ba.budget_amount, b.monthly_distribution,
ifnull(b.applicable_on_material_request, 0) as for_material_request,
ifnull(applicable_on_purchase_order, 0) as for_purchase_order,
ifnull(applicable_on_booking_actual_expenses,0) as for_actual_expenses,
@@ -187,9 +182,7 @@ def validate_expense_against_budget(args, expense_amount=0):
b.name=ba.parent and b.fiscal_year=%s
and ba.account=%s and b.docstatus=1
{condition}
""".format(
condition=condition, budget_against_field=budget_against
),
""",
(args.fiscal_year, args.account),
as_dict=True,
) # nosec
@@ -201,12 +194,18 @@ def validate_expense_against_budget(args, expense_amount=0):
def validate_budget_records(args, budget_records, expense_amount):
for budget in budget_records:
if flt(budget.budget_amount):
amount = expense_amount or get_amount(args, budget)
yearly_action, monthly_action = get_actions(args, budget)
args["for_material_request"] = budget.for_material_request
args["for_purchase_order"] = budget.for_purchase_order
if yearly_action in ("Stop", "Warn"):
compare_expense_with_budget(
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
args,
flt(budget.budget_amount),
_("Annual"),
yearly_action,
budget.budget_against,
expense_amount,
)
if monthly_action in ["Stop", "Warn"]:
@@ -217,18 +216,32 @@ def validate_budget_records(args, budget_records, expense_amount):
args["month_end_date"] = get_last_day(args.posting_date)
compare_expense_with_budget(
args, budget_amount, _("Accumulated Monthly"), monthly_action, budget.budget_against, amount
args,
budget_amount,
_("Accumulated Monthly"),
monthly_action,
budget.budget_against,
expense_amount,
)
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0):
actual_expense = get_actual_expense(args)
total_expense = actual_expense + amount
args.actual_expense, args.requested_amount, args.ordered_amount = get_actual_expense(args), 0, 0
if not amount:
args.requested_amount, args.ordered_amount = get_requested_amount(args), get_ordered_amount(args)
if args.get("doctype") == "Material Request" and args.for_material_request:
amount = args.requested_amount + args.ordered_amount
elif args.get("doctype") == "Purchase Order" and args.for_purchase_order:
amount = args.ordered_amount
total_expense = args.actual_expense + amount
if total_expense > budget_amount:
if actual_expense > budget_amount:
if args.actual_expense > budget_amount:
error_tense = _("is already")
diff = actual_expense - budget_amount
diff = args.actual_expense - budget_amount
else:
error_tense = _("will be")
diff = total_expense - budget_amount
@@ -245,9 +258,10 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
frappe.bold(fmt_money(diff, currency=currency)),
)
if (
frappe.flags.exception_approver_role
and frappe.flags.exception_approver_role in frappe.get_roles(frappe.session.user)
msg += get_expense_breakup(args, currency, budget_against)
if frappe.flags.exception_approver_role and frappe.flags.exception_approver_role in frappe.get_roles(
frappe.session.user
):
action = "Warn"
@@ -257,6 +271,83 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
frappe.msgprint(msg, indicator="orange", title=_("Budget Exceeded"))
def get_expense_breakup(args, currency, budget_against):
msg = "<hr>Total Expenses booked through - <ul>"
common_filters = frappe._dict(
{
args.budget_against_field: budget_against,
"account": args.account,
"company": args.company,
}
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"General Ledger",
label="Actual Expenses",
filters=common_filters.copy().update(
{
"from_date": frappe.get_cached_value("Fiscal Year", args.fiscal_year, "year_start_date"),
"to_date": frappe.get_cached_value("Fiscal Year", args.fiscal_year, "year_end_date"),
"is_cancelled": 0,
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.actual_expense, currency=currency))
+ "</li>"
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"Material Request",
label="Material Requests",
report_type="Report Builder",
doctype="Material Request",
filters=common_filters.copy().update(
{
"status": [["!=", "Stopped"]],
"docstatus": 1,
"material_request_type": "Purchase",
"schedule_date": [["fiscal year", "2023-2024"]],
"item_code": args.item_code,
"per_ordered": [["<", 100]],
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.requested_amount, currency=currency))
+ "</li>"
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"Purchase Order",
label="Unbilled Orders",
report_type="Report Builder",
doctype="Purchase Order",
filters=common_filters.copy().update(
{
"status": [["!=", "Closed"]],
"docstatus": 1,
"transaction_date": [["fiscal year", "2023-2024"]],
"item_code": args.item_code,
"per_billed": [["<", 100]],
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.ordered_amount, currency=currency))
+ "</li></ul>"
)
return msg
def get_actions(args, budget):
yearly_action = budget.action_if_annual_budget_exceeded
monthly_action = budget.action_if_accumulated_monthly_budget_exceeded
@@ -272,31 +363,15 @@ def get_actions(args, budget):
return yearly_action, monthly_action
def get_amount(args, budget):
amount = 0
if args.get("doctype") == "Material Request" and budget.for_material_request:
amount = (
get_requested_amount(args, budget) + get_ordered_amount(args, budget) + get_actual_expense(args)
)
elif args.get("doctype") == "Purchase Order" and budget.for_purchase_order:
amount = get_ordered_amount(args, budget) + get_actual_expense(args)
return amount
def get_requested_amount(args, budget):
def get_requested_amount(args):
item_code = args.get("item_code")
condition = get_other_condition(args, budget, "Material Request")
condition = get_other_condition(args, "Material Request")
data = frappe.db.sql(
""" select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount
from `tabMaterial Request Item` child, `tabMaterial Request` parent where parent.name = child.parent and
child.item_code = %s and parent.docstatus = 1 and child.stock_qty > child.ordered_qty and {0} and
parent.material_request_type = 'Purchase' and parent.status != 'Stopped'""".format(
condition
),
child.item_code = %s and parent.docstatus = 1 and child.stock_qty > child.ordered_qty and {} and
parent.material_request_type = 'Purchase' and parent.status != 'Stopped'""".format(condition),
item_code,
as_list=1,
)
@@ -304,17 +379,15 @@ def get_requested_amount(args, budget):
return data[0][0] if data else 0
def get_ordered_amount(args, budget):
def get_ordered_amount(args):
item_code = args.get("item_code")
condition = get_other_condition(args, budget, "Purchase Order")
condition = get_other_condition(args, "Purchase Order")
data = frappe.db.sql(
""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount
f""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount
from `tabPurchase Order Item` child, `tabPurchase Order` parent where
parent.name = child.parent and child.item_code = %s and parent.docstatus = 1 and child.amount > child.billed_amt
and parent.status != 'Closed' and {0}""".format(
condition
),
and parent.status != 'Closed' and {condition}""",
item_code,
as_list=1,
)
@@ -322,12 +395,12 @@ def get_ordered_amount(args, budget):
return data[0][0] if data else 0
def get_other_condition(args, budget, for_doc):
def get_other_condition(args, for_doc):
condition = "expense_account = '%s'" % (args.expense_account)
budget_against_field = args.get("budget_against_field")
if budget_against_field and args.get(budget_against_field):
condition += " and child.%s = '%s'" % (budget_against_field, args.get(budget_against_field))
condition += f" and child.{budget_against_field} = '{args.get(budget_against_field)}'"
if args.get("fiscal_year"):
date_field = "schedule_date" if for_doc == "Material Request" else "transaction_date"
@@ -335,12 +408,8 @@ def get_other_condition(args, budget, for_doc):
"Fiscal Year", args.get("fiscal_year"), ["year_start_date", "year_end_date"]
)
condition += """ and parent.%s
between '%s' and '%s' """ % (
date_field,
start_date,
end_date,
)
condition += f""" and parent.{date_field}
between '{start_date}' and '{end_date}' """
return condition
@@ -359,21 +428,17 @@ def get_actual_expense(args):
args.update(lft_rgt)
condition2 = """and exists(select name from `tab{doctype}`
condition2 = f"""and exists(select name from `tab{args.budget_against_doctype}`
where lft>=%(lft)s and rgt<=%(rgt)s
and name=gle.{budget_against_field})""".format(
doctype=args.budget_against_doctype, budget_against_field=budget_against_field # nosec
)
and name=gle.{budget_against_field})"""
else:
condition2 = """and exists(select name from `tab{doctype}`
where name=gle.{budget_against} and
gle.{budget_against} = %({budget_against})s)""".format(
doctype=args.budget_against_doctype, budget_against=budget_against_field
)
condition2 = f"""and exists(select name from `tab{args.budget_against_doctype}`
where name=gle.{budget_against_field} and
gle.{budget_against_field} = %({budget_against_field})s)"""
amount = flt(
frappe.db.sql(
"""
f"""
select sum(gle.debit) - sum(gle.credit)
from `tabGL Entry` gle
where
@@ -384,9 +449,7 @@ def get_actual_expense(args):
and gle.company=%(company)s
and gle.docstatus=1
{condition2}
""".format(
condition1=condition1, condition2=condition2
),
""",
(args),
)[0][0]
) # nosec

View File

@@ -41,9 +41,7 @@ class TestBudget(unittest.TestCase):
budget = make_budget(budget_against="Cost Center")
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
@@ -63,9 +61,7 @@ class TestBudget(unittest.TestCase):
budget = make_budget(budget_against="Cost Center")
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
@@ -97,9 +93,7 @@ class TestBudget(unittest.TestCase):
)
fiscal_year = get_fiscal_year(nowdate())[0]
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
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)
mr = frappe.get_doc(
@@ -138,9 +132,7 @@ class TestBudget(unittest.TestCase):
)
fiscal_year = get_fiscal_year(nowdate())[0]
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
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)
po = create_purchase_order(transaction_date=nowdate(), do_not_submit=True)
@@ -158,9 +150,7 @@ class TestBudget(unittest.TestCase):
budget = make_budget(budget_against="Project")
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
project = frappe.get_value("Project", {"project_name": "_Test Project"})
@@ -223,7 +213,7 @@ class TestBudget(unittest.TestCase):
if month > 9:
month = 9
for i in range(month + 1):
for _i in range(month + 1):
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC",
@@ -237,9 +227,7 @@ class TestBudget(unittest.TestCase):
frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv.name})
)
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
self.assertRaises(BudgetError, jv.cancel)
@@ -255,7 +243,7 @@ class TestBudget(unittest.TestCase):
month = 9
project = frappe.get_value("Project", {"project_name": "_Test Project"})
for i in range(month + 1):
for _i in range(month + 1):
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
"_Test Bank - _TC",
@@ -270,9 +258,7 @@ class TestBudget(unittest.TestCase):
frappe.db.get_value("GL Entry", {"voucher_type": "Journal Entry", "voucher_no": jv.name})
)
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
self.assertRaises(BudgetError, jv.cancel)
@@ -284,9 +270,7 @@ class TestBudget(unittest.TestCase):
set_total_expense_zero(nowdate(), "cost_center", "_Test Cost Center 2 - _TC")
budget = make_budget(budget_against="Cost Center", cost_center="_Test Company - _TC")
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
@@ -316,9 +300,7 @@ class TestBudget(unittest.TestCase):
).insert(ignore_permissions=True)
budget = make_budget(budget_against="Cost Center", cost_center=cost_center)
frappe.db.set_value(
"Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop"
)
frappe.db.set_value("Budget", budget.name, "action_if_accumulated_monthly_budget_exceeded", "Stop")
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
@@ -423,13 +405,11 @@ def make_budget(**args):
fiscal_year = get_fiscal_year(nowdate())[0]
if budget_against == "Project":
project_name = "{0}%".format("_Test Project/" + fiscal_year)
project_name = "{}%".format("_Test Project/" + fiscal_year)
budget_list = frappe.get_all("Budget", fields=["name"], filters={"name": ("like", project_name)})
else:
cost_center_name = "{0}%".format(cost_center or "_Test Cost Center - _TC/" + fiscal_year)
budget_list = frappe.get_all(
"Budget", fields=["name"], filters={"name": ("like", cost_center_name)}
)
cost_center_name = "{}%".format(cost_center or "_Test Cost Center - _TC/" + fiscal_year)
budget_list = frappe.get_all("Budget", fields=["name"], filters={"name": ("like", cost_center_name)})
for d in budget_list:
frappe.db.sql("delete from `tabBudget` where name = %(name)s", d)
frappe.db.sql("delete from `tabBudget Account` where parent = %(name)s", d)
@@ -451,24 +431,18 @@ def make_budget(**args):
budget.action_if_annual_budget_exceeded = "Stop"
budget.action_if_accumulated_monthly_budget_exceeded = "Ignore"
budget.budget_against = budget_against
budget.append(
"accounts", {"account": "_Test Account Cost for Goods Sold - _TC", "budget_amount": 200000}
)
budget.append("accounts", {"account": "_Test Account Cost for Goods Sold - _TC", "budget_amount": 200000})
if args.applicable_on_material_request:
budget.applicable_on_material_request = 1
budget.action_if_annual_budget_exceeded_on_mr = (
args.action_if_annual_budget_exceeded_on_mr or "Warn"
)
budget.action_if_annual_budget_exceeded_on_mr = args.action_if_annual_budget_exceeded_on_mr or "Warn"
budget.action_if_accumulated_monthly_budget_exceeded_on_mr = (
args.action_if_accumulated_monthly_budget_exceeded_on_mr or "Warn"
)
if args.applicable_on_purchase_order:
budget.applicable_on_purchase_order = 1
budget.action_if_annual_budget_exceeded_on_po = (
args.action_if_annual_budget_exceeded_on_po or "Warn"
)
budget.action_if_annual_budget_exceeded_on_po = args.action_if_annual_budget_exceeded_on_po or "Warn"
budget.action_if_accumulated_monthly_budget_exceeded_on_po = (
args.action_if_accumulated_monthly_budget_exceeded_on_po or "Warn"
)

View File

@@ -26,9 +26,7 @@ from erpnext.accounts.doctype.account.chart_of_accounts.chart_of_accounts import
class ChartofAccountsImporter(Document):
def validate(self):
if self.import_file:
get_coa(
"Chart of Accounts Importer", "All Accounts", file_name=self.import_file, for_validate=1
)
get_coa("Chart of Accounts Importer", "All Accounts", file_name=self.import_file, for_validate=1)
def validate_columns(data):
@@ -104,7 +102,7 @@ def generate_data_from_csv(file_doc, as_dict=False):
file_path = file_doc.get_full_path()
data = []
with open(file_path, "r") as in_file:
with open(file_path) as in_file:
csv_reader = list(csv.reader(in_file))
headers = csv_reader[0]
del csv_reader[0] # delete top row and headers row
@@ -203,10 +201,10 @@ def build_forest(data):
for row in data:
account_name, parent_account, account_number, parent_account_number = row[0:4]
if account_number:
account_name = "{} - {}".format(account_number, account_name)
account_name = f"{account_number} - {account_name}"
if parent_account_number:
parent_account_number = cstr(parent_account_number).strip()
parent_account = "{} - {}".format(parent_account_number, parent_account)
parent_account = f"{parent_account_number} - {parent_account}"
if parent_account == account_name == child:
return [parent_account]
@@ -218,7 +216,7 @@ def build_forest(data):
frappe.bold(parent_account)
)
)
return [child] + parent_account_list
return [child, *parent_account_list]
charts_map, paths = {}, []
@@ -238,12 +236,12 @@ def build_forest(data):
) = i
if not account_name:
error_messages.append("Row {0}: Please enter Account Name".format(line_no))
error_messages.append(f"Row {line_no}: Please enter Account Name")
name = account_name
if account_number:
account_number = cstr(account_number).strip()
account_name = "{} - {}".format(account_number, account_name)
account_name = f"{account_number} - {account_name}"
charts_map[account_name] = {}
charts_map[account_name]["account_name"] = name
@@ -340,9 +338,9 @@ def get_template(template_type, company):
def get_sample_template(writer, company):
currency = frappe.db.get_value("Company", company, "default_currency")
with open(os.path.join(os.path.dirname(__file__), "coa_sample_template.csv"), "r") as f:
with open(os.path.join(os.path.dirname(__file__), "coa_sample_template.csv")) as f:
for row in f:
row = row.strip().split(",") + [currency]
row = [*row.strip().split(","), currency]
writer.writerow(row)
return writer
@@ -451,7 +449,7 @@ def unset_existing_data(company):
"Purchase Taxes and Charges Template",
]:
frappe.db.sql(
'''delete from `tab{0}` where `company`="%s"'''.format(doctype) % (company) # nosec
f'''delete from `tab{doctype}` where `company`="%s"''' % (company) # nosec
)

View File

@@ -31,71 +31,71 @@ def create_or_update_cheque_print_format(template_name):
cheque_print.html = """
<style>
.print-format {
.print-format {{
padding: 0px;
}
@media screen {
.print-format {
}}
@media screen {{
.print-format {{
padding: 0in;
}
}
}}
}}
</style>
<div style="position: relative; top:%(starting_position_from_top_edge)scm">
<div style="width:%(cheque_width)scm;height:%(cheque_height)scm;">
<span style="top:%(acc_pay_dist_from_top_edge)scm; left:%(acc_pay_dist_from_left_edge)scm;
<div style="position: relative; top:{starting_position_from_top_edge}cm">
<div style="width:{cheque_width}cm;height:{cheque_height}cm;">
<span style="top:{acc_pay_dist_from_top_edge}cm; left:{acc_pay_dist_from_left_edge}cm;
border-bottom: solid 1px;border-top:solid 1px; width:2cm;text-align: center; position: absolute;">
%(message_to_show)s
{message_to_show}
</span>
<span style="top:%(date_dist_from_top_edge)scm; left:%(date_dist_from_left_edge)scm;
<span style="top:{date_dist_from_top_edge}cm; left:{date_dist_from_left_edge}cm;
position: absolute;">
{{ frappe.utils.formatdate(doc.reference_date) or '' }}
{{{{ frappe.utils.formatdate(doc.reference_date) or '' }}}}
</span>
<span style="top:%(acc_no_dist_from_top_edge)scm;left:%(acc_no_dist_from_left_edge)scm;
<span style="top:{acc_no_dist_from_top_edge}cm;left:{acc_no_dist_from_left_edge}cm;
position: absolute; min-width: 6cm;">
{{ doc.account_no or '' }}
{{{{ doc.account_no or '' }}}}
</span>
<span style="top:%(payer_name_from_top_edge)scm;left: %(payer_name_from_left_edge)scm;
<span style="top:{payer_name_from_top_edge}cm;left: {payer_name_from_left_edge}cm;
position: absolute; min-width: 6cm;">
{{doc.party_name}}
{{{{doc.party_name}}}}
</span>
<span style="top:%(amt_in_words_from_top_edge)scm; left:%(amt_in_words_from_left_edge)scm;
position: absolute; display: block; width: %(amt_in_word_width)scm;
line-height:%(amt_in_words_line_spacing)scm; word-wrap: break-word;">
{{frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount)}}
<span style="top:{amt_in_words_from_top_edge}cm; left:{amt_in_words_from_left_edge}cm;
position: absolute; display: block; width: {amt_in_word_width}cm;
line-height:{amt_in_words_line_spacing}cm; word-wrap: break-word;">
{{{{frappe.utils.money_in_words(doc.base_paid_amount or doc.base_received_amount)}}}}
</span>
<span style="top:%(amt_in_figures_from_top_edge)scm;left: %(amt_in_figures_from_left_edge)scm;
<span style="top:{amt_in_figures_from_top_edge}cm;left: {amt_in_figures_from_left_edge}cm;
position: absolute; min-width: 4cm;">
{{doc.get_formatted("base_paid_amount") or doc.get_formatted("base_received_amount")}}
{{{{doc.get_formatted("base_paid_amount") or doc.get_formatted("base_received_amount")}}}}
</span>
<span style="top:%(signatory_from_top_edge)scm;left: %(signatory_from_left_edge)scm;
<span style="top:{signatory_from_top_edge}cm;left: {signatory_from_left_edge}cm;
position: absolute; min-width: 6cm;">
{{doc.company}}
{{{{doc.company}}}}
</span>
</div>
</div>""" % {
"starting_position_from_top_edge": doc.starting_position_from_top_edge
</div>""".format(
starting_position_from_top_edge=doc.starting_position_from_top_edge
if doc.cheque_size == "A4"
else 0.0,
"cheque_width": doc.cheque_width,
"cheque_height": doc.cheque_height,
"acc_pay_dist_from_top_edge": doc.acc_pay_dist_from_top_edge,
"acc_pay_dist_from_left_edge": doc.acc_pay_dist_from_left_edge,
"message_to_show": doc.message_to_show if doc.message_to_show else _("Account Pay Only"),
"date_dist_from_top_edge": doc.date_dist_from_top_edge,
"date_dist_from_left_edge": doc.date_dist_from_left_edge,
"acc_no_dist_from_top_edge": doc.acc_no_dist_from_top_edge,
"acc_no_dist_from_left_edge": doc.acc_no_dist_from_left_edge,
"payer_name_from_top_edge": doc.payer_name_from_top_edge,
"payer_name_from_left_edge": doc.payer_name_from_left_edge,
"amt_in_words_from_top_edge": doc.amt_in_words_from_top_edge,
"amt_in_words_from_left_edge": doc.amt_in_words_from_left_edge,
"amt_in_word_width": doc.amt_in_word_width,
"amt_in_words_line_spacing": doc.amt_in_words_line_spacing,
"amt_in_figures_from_top_edge": doc.amt_in_figures_from_top_edge,
"amt_in_figures_from_left_edge": doc.amt_in_figures_from_left_edge,
"signatory_from_top_edge": doc.signatory_from_top_edge,
"signatory_from_left_edge": doc.signatory_from_left_edge,
}
cheque_width=doc.cheque_width,
cheque_height=doc.cheque_height,
acc_pay_dist_from_top_edge=doc.acc_pay_dist_from_top_edge,
acc_pay_dist_from_left_edge=doc.acc_pay_dist_from_left_edge,
message_to_show=doc.message_to_show if doc.message_to_show else _("Account Pay Only"),
date_dist_from_top_edge=doc.date_dist_from_top_edge,
date_dist_from_left_edge=doc.date_dist_from_left_edge,
acc_no_dist_from_top_edge=doc.acc_no_dist_from_top_edge,
acc_no_dist_from_left_edge=doc.acc_no_dist_from_left_edge,
payer_name_from_top_edge=doc.payer_name_from_top_edge,
payer_name_from_left_edge=doc.payer_name_from_left_edge,
amt_in_words_from_top_edge=doc.amt_in_words_from_top_edge,
amt_in_words_from_left_edge=doc.amt_in_words_from_left_edge,
amt_in_word_width=doc.amt_in_word_width,
amt_in_words_line_spacing=doc.amt_in_words_line_spacing,
amt_in_figures_from_top_edge=doc.amt_in_figures_from_top_edge,
amt_in_figures_from_left_edge=doc.amt_in_figures_from_left_edge,
signatory_from_top_edge=doc.signatory_from_top_edge,
signatory_from_left_edge=doc.signatory_from_left_edge,
)
cheque_print.save(ignore_permissions=True)

View File

@@ -125,7 +125,7 @@
"idx": 1,
"is_tree": 1,
"links": [],
"modified": "2022-01-31 13:22:58.916273",
"modified": "2024-04-24 10:55:54.083042",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cost Center",
@@ -163,6 +163,15 @@
{
"read": 1,
"role": "Purchase User"
},
{
"email": 1,
"export": 1,
"print": 1,
"report": 1,
"role": "Employee",
"select": 1,
"share": 1
}
],
"search_fields": "parent_cost_center, is_group",

View File

@@ -15,9 +15,7 @@ class CostCenter(NestedSet):
def autoname(self):
from erpnext.accounts.utils import get_autoname_with_number
self.name = get_autoname_with_number(
self.cost_center_number, self.cost_center_name, self.company
)
self.name = get_autoname_with_number(self.cost_center_number, self.cost_center_name, self.company)
def validate(self):
self.validate_mandatory()
@@ -90,14 +88,14 @@ class CostCenter(NestedSet):
new_cost_center = get_name_with_abbr(newdn, self.company)
# Validate properties before merging
super(CostCenter, self).before_rename(olddn, new_cost_center, merge, "is_group")
super().before_rename(olddn, new_cost_center, merge, "is_group")
if not merge:
new_cost_center = get_name_with_number(new_cost_center, self.cost_center_number)
return new_cost_center
def after_rename(self, olddn, newdn, merge=False):
super(CostCenter, self).after_rename(olddn, newdn, merge)
super().after_rename(olddn, newdn, merge)
if not merge:
new_cost_center = frappe.db.get_value(

View File

@@ -10,7 +10,6 @@ test_records = frappe.get_test_records("Cost Center")
class TestCostCenter(unittest.TestCase):
def test_cost_center_creation_against_child_node(self):
if not frappe.db.get_value("Cost Center", {"name": "_Test Cost Center 2 - _TC"}):
frappe.get_doc(test_records[1]).insert()

View File

@@ -29,7 +29,7 @@ class InvalidDateError(frappe.ValidationError):
class CostCenterAllocation(Document):
def __init__(self, *args, **kwargs):
super(CostCenterAllocation, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self._skip_from_date_validation = False
def validate(self):
@@ -44,9 +44,7 @@ class CostCenterAllocation(Document):
total_percentage = sum([d.percentage for d in self.get("allocation_percentages", [])])
if total_percentage != 100:
frappe.throw(
_("Total percentage against cost centers should be 100"), WrongPercentageAllocation
)
frappe.throw(_("Total percentage against cost centers should be 100"), WrongPercentageAllocation)
def validate_from_date_based_on_existing_gle(self):
# Check if GLE exists against the main cost center

View File

@@ -22,8 +22,10 @@ class TestCostCenterAllocation(unittest.TestCase):
cost_centers = [
"Main Cost Center 1",
"Main Cost Center 2",
"Main Cost Center 3",
"Sub Cost Center 1",
"Sub Cost Center 2",
"Sub Cost Center 3",
]
for cc in cost_centers:
create_cost_center(cost_center_name=cc, company="_Test Company")
@@ -36,7 +38,7 @@ class TestCostCenterAllocation(unittest.TestCase):
)
jv = make_journal_entry(
"_Test Cash - _TC", "Sales - _TC", 100, cost_center="Main Cost Center 1 - _TC", submit=True
"Cash - _TC", "Sales - _TC", 100, cost_center="Main Cost Center 1 - _TC", submit=True
)
expected_values = [["Sub Cost Center 1 - _TC", 0.0, 60], ["Sub Cost Center 2 - _TC", 0.0, 40]]
@@ -120,7 +122,7 @@ class TestCostCenterAllocation(unittest.TestCase):
def test_valid_from_based_on_existing_gle(self):
# GLE posted against Sub Cost Center 1 on today
jv = make_journal_entry(
"_Test Cash - _TC",
"Cash - _TC",
"Sales - _TC",
100,
cost_center="Main Cost Center 1 - _TC",
@@ -141,6 +143,53 @@ class TestCostCenterAllocation(unittest.TestCase):
jv.cancel()
def test_multiple_cost_center_allocation_on_same_main_cost_center(self):
coa1 = create_cost_center_allocation(
"_Test Company",
"Main Cost Center 3 - _TC",
{"Sub Cost Center 1 - _TC": 30, "Sub Cost Center 2 - _TC": 30, "Sub Cost Center 3 - _TC": 40},
valid_from=add_days(today(), -5),
)
coa2 = create_cost_center_allocation(
"_Test Company",
"Main Cost Center 3 - _TC",
{"Sub Cost Center 1 - _TC": 50, "Sub Cost Center 2 - _TC": 50},
valid_from=add_days(today(), -1),
)
jv = make_journal_entry(
"Cash - _TC",
"Sales - _TC",
100,
cost_center="Main Cost Center 3 - _TC",
posting_date=today(),
submit=True,
)
expected_values = {"Sub Cost Center 1 - _TC": 50, "Sub Cost Center 2 - _TC": 50}
gle = frappe.qb.DocType("GL Entry")
gl_entries = (
frappe.qb.from_(gle)
.select(gle.cost_center, gle.debit, gle.credit)
.where(gle.voucher_type == "Journal Entry")
.where(gle.voucher_no == jv.name)
.where(gle.account == "Sales - _TC")
.orderby(gle.cost_center)
).run(as_dict=1)
self.assertTrue(gl_entries)
for gle in gl_entries:
self.assertTrue(gle.cost_center in expected_values)
self.assertEqual(gle.debit, 0)
self.assertEqual(gle.credit, expected_values[gle.cost_center])
coa1.cancel()
coa2.cancel()
jv.cancel()
def create_cost_center_allocation(
company,

View File

@@ -18,7 +18,6 @@ class CurrencyExchangeSettings(Document):
def set_parameters_and_result(self):
if self.service_provider == "exchangerate.host":
if not self.access_key:
frappe.throw(
_("Access Key is required for Service Provider: {0}").format(
@@ -53,9 +52,7 @@ class CurrencyExchangeSettings(Document):
transaction_date=nowdate(), to_currency="INR", from_currency="USD"
)
api_url = self.api_endpoint.format(
transaction_date=nowdate(), to_currency="INR", from_currency="USD"
)
api_url = self.api_endpoint.format(transaction_date=nowdate(), to_currency="INR", from_currency="USD")
try:
response = requests.get(api_url, params=params)
@@ -75,19 +72,19 @@ class CurrencyExchangeSettings(Document):
]
except Exception:
frappe.throw(_("Invalid result key. Response:") + " " + response.text)
if not isinstance(value, (int, float)):
if not isinstance(value, int | float):
frappe.throw(_("Returned exchange rate is neither integer not float."))
self.url = response.url
@frappe.whitelist()
def get_api_endpoint(service_provider: str = None, use_http: bool = False):
def get_api_endpoint(service_provider: str | None = None, use_http: bool = False):
if service_provider and service_provider in ["exchangerate.host", "frankfurter.app"]:
if service_provider == "exchangerate.host":
api = "api.exchangerate.host/convert"
elif service_provider == "frankfurter.app":
api = "frankfurter.app/{transaction_date}"
api = "api.frankfurter.app/{transaction_date}"
protocol = "https://"
if use_http:

View File

@@ -129,19 +129,31 @@ def calculate_interest_and_amount(outstanding_amount, rate_of_interest, dunning_
@frappe.whitelist()
def get_dunning_letter_text(dunning_type, doc, language=None):
def get_dunning_letter_text(dunning_type: str, doc: str | dict, language: str | None = None) -> dict:
DOCTYPE = "Dunning Letter Text"
FIELDS = ["body_text", "closing_text", "language"]
if isinstance(doc, str):
doc = json.loads(doc)
if not language:
language = doc.get("language")
if language:
filters = {"parent": dunning_type, "language": language}
else:
filters = {"parent": dunning_type, "is_default_language": 1}
letter_text = frappe.db.get_value(
"Dunning Letter Text", filters, ["body_text", "closing_text", "language"], as_dict=1
)
if letter_text:
return {
"body_text": frappe.render_template(letter_text.body_text, doc),
"closing_text": frappe.render_template(letter_text.closing_text, doc),
"language": letter_text.language,
}
letter_text = frappe.db.get_value(
DOCTYPE, {"parent": dunning_type, "language": language}, FIELDS, as_dict=1
)
if not letter_text:
letter_text = frappe.db.get_value(
DOCTYPE, {"parent": dunning_type, "is_default_language": 1}, FIELDS, as_dict=1
)
if not letter_text:
return {}
return {
"body_text": frappe.render_template(letter_text.body_text, doc),
"closing_text": frappe.render_template(letter_text.closing_text, doc),
"language": letter_text.language,
}

View File

@@ -52,6 +52,21 @@ class ExchangeRateRevaluation(Document):
if not (self.company and self.posting_date):
frappe.throw(_("Please select Company and Posting Date to getting entries"))
def before_submit(self):
self.remove_accounts_without_gain_loss()
def remove_accounts_without_gain_loss(self):
self.accounts = [account for account in self.accounts if account.gain_loss]
if not self.accounts:
frappe.throw(_("At least one account with exchange gain or loss is required"))
frappe.msgprint(
_("Removing rows without exchange gain or loss"),
alert=True,
indicator="yellow",
)
def on_cancel(self):
self.ignore_linked_doctypes = "GL Entry"
@@ -226,27 +241,26 @@ class ExchangeRateRevaluation(Document):
new_exchange_rate = get_exchange_rate(d.account_currency, company_currency, posting_date)
new_balance_in_base_currency = flt(d.balance_in_account_currency * new_exchange_rate)
gain_loss = flt(new_balance_in_base_currency, precision) - flt(d.balance, precision)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": d.balance_in_account_currency,
"gain_loss": gain_loss,
}
)
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": d.balance_in_account_currency,
"gain_loss": gain_loss,
}
)
# Handle Accounts with '0' balance in Account/Base Currency
for d in [x for x in account_details if x.zero_balance]:
if d.balance != 0:
current_exchange_rate = new_exchange_rate = 0
@@ -259,30 +273,30 @@ class ExchangeRateRevaluation(Document):
new_balance_in_account_currency = 0
current_exchange_rate = (
calculate_exchange_rate_using_last_gle(company, d.account, d.party_type, d.party) or 0.0
calculate_exchange_rate_using_last_gle(company, d.account, d.party_type, d.party)
or 0.0
)
gain_loss = new_balance_in_account_currency - (
current_exchange_rate * d.balance_in_account_currency
)
if gain_loss:
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": new_balance_in_account_currency,
"gain_loss": gain_loss,
}
)
accounts.append(
{
"account": d.account,
"party_type": d.party_type,
"party": d.party,
"account_currency": d.account_currency,
"balance_in_base_currency": d.balance,
"balance_in_account_currency": d.balance_in_account_currency,
"zero_balance": d.zero_balance,
"current_exchange_rate": current_exchange_rate,
"new_exchange_rate": new_exchange_rate,
"new_balance_in_base_currency": new_balance_in_base_currency,
"new_balance_in_account_currency": new_balance_in_account_currency,
"gain_loss": gain_loss,
}
)
return accounts
@@ -313,9 +327,7 @@ class ExchangeRateRevaluation(Document):
revaluation_jv = self.make_jv_for_revaluation()
if revaluation_jv:
frappe.msgprint(
f"Revaluation Journal: {get_link_to_form('Journal Entry', revaluation_jv.name)}"
)
frappe.msgprint(f"Revaluation Journal: {get_link_to_form('Journal Entry', revaluation_jv.name)}")
return {
"revaluation_jv": revaluation_jv.name if revaluation_jv else None,
@@ -372,7 +384,8 @@ class ExchangeRateRevaluation(Document):
journal_account.update(
{
dr_or_cr: flt(
abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")
abs(d.get("balance_in_account_currency")),
d.precision("balance_in_account_currency"),
),
reverse_dr_or_cr: 0,
"debit": 0,
@@ -498,7 +511,9 @@ class ExchangeRateRevaluation(Document):
abs(d.get("balance_in_account_currency")), d.precision("balance_in_account_currency")
),
"cost_center": erpnext.get_default_cost_center(self.company),
"exchange_rate": flt(d.get("current_exchange_rate"), d.precision("current_exchange_rate")),
"exchange_rate": flt(
d.get("current_exchange_rate"), d.precision("current_exchange_rate")
),
"reference_type": "Exchange Rate Revaluation",
"reference_name": self.name,
}
@@ -576,7 +591,7 @@ def calculate_exchange_rate_using_last_gle(company, account, party_type, party):
@frappe.whitelist()
def get_account_details(
company, posting_date, account, party_type=None, party=None, rounding_loss_allowance: float = None
company, posting_date, account, party_type=None, party=None, rounding_loss_allowance: float | None = None
):
if not (company and posting_date):
frappe.throw(_("Company and Posting Date is mandatory"))
@@ -589,7 +604,7 @@ def get_account_details(
frappe.throw(_("Party Type and Party is mandatory for {0} account").format(account_type))
account_details = {}
company_currency = erpnext.get_company_currency(company)
erpnext.get_company_currency(company)
account_details = {
"account_currency": account_currency,
@@ -603,9 +618,7 @@ def get_account_details(
rounding_loss_allowance=rounding_loss_allowance,
)
if account_balance and (
account_balance[0].balance or account_balance[0].balance_in_account_currency
):
if account_balance and (account_balance[0].balance or account_balance[0].balance_in_account_currency):
if account_with_new_balance := ExchangeRateRevaluation.calculate_new_account_balance(
company, posting_date, account_balance
):

View File

@@ -1,21 +1,14 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe import qb
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, flt, today
from erpnext import get_default_cost_center
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
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
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.accounts.party import get_party_account
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
from erpnext.stock.doctype.item.test_item import create_item
class TestExchangeRateRevaluation(AccountsTestMixin, FrappeTestCase):
@@ -73,9 +66,7 @@ class TestExchangeRateRevaluation(AccountsTestMixin, FrappeTestCase):
err.extend("accounts", accounts)
row = err.accounts[0]
row.new_exchange_rate = 85
row.new_balance_in_base_currency = flt(
row.new_exchange_rate * flt(row.balance_in_account_currency)
)
row.new_balance_in_base_currency = flt(row.new_exchange_rate * flt(row.balance_in_account_currency))
row.gain_loss = row.new_balance_in_base_currency - flt(row.balance_in_base_currency)
err.set_total_gain_loss()
err = err.save().submit()
@@ -127,9 +118,9 @@ class TestExchangeRateRevaluation(AccountsTestMixin, FrappeTestCase):
pe.save().submit()
# Cancel the auto created gain/loss JE to simulate balance only in base currency
je = frappe.db.get_all(
"Journal Entry Account", filters={"reference_name": si.name}, pluck="parent"
)[0]
je = frappe.db.get_all("Journal Entry Account", filters={"reference_name": si.name}, pluck="parent")[
0
]
frappe.get_doc("Journal Entry", je).cancel()
err = frappe.new_doc("Exchange Rate Revaluation")
@@ -235,9 +226,9 @@ class TestExchangeRateRevaluation(AccountsTestMixin, FrappeTestCase):
self.assertEqual(flt(acc.debit, precision), 0.0)
self.assertEqual(flt(acc.credit, precision), 0.0)
row = [x for x in je.accounts if x.account == self.debtors_usd][0]
row = next(x for x in je.accounts if x.account == self.debtors_usd)
self.assertEqual(flt(row.credit_in_account_currency, precision), 5.0) # in USD
row = [x for x in je.accounts if x.account != self.debtors_usd][0]
row = next(x for x in je.accounts if x.account != self.debtors_usd)
self.assertEqual(flt(row.debit_in_account_currency, precision), 421.06) # in INR
# total_debit and total_credit will be 0.0, as JV is posting only to account currency fields
@@ -294,5 +285,5 @@ class TestExchangeRateRevaluation(AccountsTestMixin, FrappeTestCase):
"new_balance_in_account_currency": 100.0,
}
for key, val in expected_data.items():
for key, _val in expected_data.items():
self.assertEqual(expected_data.get(key), account_details.get(key))

View File

@@ -82,7 +82,7 @@
"icon": "fa fa-calendar",
"idx": 1,
"links": [],
"modified": "2020-11-05 12:16:53.081573",
"modified": "2024-05-27 17:29:55.560840",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Fiscal Year",
@@ -118,9 +118,21 @@
{
"read": 1,
"role": "Employee"
},
{
"read": 1,
"role": "Accounts Manager"
},
{
"read": 1,
"role": "Stock Manager"
},
{
"read": 1,
"role": "Auditor"
}
],
"show_name_in_global_search": 1,
"sort_field": "name",
"sort_order": "DESC"
}
}

View File

@@ -98,9 +98,9 @@ class FiscalYear(Document):
if overlap:
frappe.throw(
_("Year start date or end date is overlapping with {0}. To avoid please set company").format(
existing.name
),
_(
"Year start date or end date is overlapping with {0}. To avoid please set company"
).format(existing.name),
frappe.NameError,
)
@@ -116,9 +116,9 @@ def check_duplicate_fiscal_year(doc):
not frappe.flags.in_test
):
frappe.throw(
_("Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}").format(
fiscal_year
)
_(
"Fiscal Year Start Date and Fiscal Year End Date are already set in Fiscal Year {0}"
).format(fiscal_year)
)

View File

@@ -63,13 +63,18 @@ class GLEntry(Document):
]:
# Update outstanding amt on against voucher
if (
self.against_voucher_type in ["Journal Entry", "Sales Invoice", "Purchase Invoice", "Fees"]
self.against_voucher_type
in ["Journal Entry", "Sales Invoice", "Purchase Invoice", "Fees"]
and self.against_voucher
and self.flags.update_outstanding == "Yes"
and not frappe.flags.is_reverse_depr_entry
):
update_outstanding_amt(
self.account, self.party_type, self.party, self.against_voucher_type, self.against_voucher
self.account,
self.party_type,
self.party,
self.against_voucher_type,
self.against_voucher,
)
def check_mandatory(self):
@@ -135,12 +140,13 @@ class GLEntry(Document):
and self.company == dimension.company
and dimension.mandatory_for_pl
and not dimension.disabled
and not self.is_cancelled
):
if not self.get(dimension.fieldname):
frappe.throw(
_("Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.").format(
dimension.label, self.account
)
_(
"Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}."
).format(dimension.label, self.account)
)
if (
@@ -148,12 +154,13 @@ class GLEntry(Document):
and self.company == dimension.company
and dimension.mandatory_for_bs
and not dimension.disabled
and not self.is_cancelled
):
if not self.get(dimension.fieldname):
frappe.throw(
_("Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}.").format(
dimension.label, self.account
)
_(
"Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}."
).format(dimension.label, self.account)
)
def check_pl_account(self):
@@ -201,9 +208,7 @@ class GLEntry(Document):
if not self.cost_center:
return
is_group, company = frappe.get_cached_value(
"Cost Center", self.cost_center, ["is_group", "company"]
)
is_group, company = frappe.get_cached_value("Cost Center", self.cost_center, ["is_group", "company"])
if company != self.company:
frappe.throw(
@@ -272,7 +277,7 @@ def update_outstanding_amt(
account, party_type, party, against_voucher_type, against_voucher, on_cancel=False
):
if party_type and party:
party_condition = " and party_type={0} and party={1}".format(
party_condition = " and party_type={} and party={}".format(
frappe.db.escape(party_type), frappe.db.escape(party)
)
else:
@@ -280,23 +285,19 @@ def update_outstanding_amt(
if against_voucher_type == "Sales Invoice":
party_account = frappe.get_cached_value(against_voucher_type, against_voucher, "debit_to")
account_condition = "and account in ({0}, {1})".format(
frappe.db.escape(account), frappe.db.escape(party_account)
)
account_condition = f"and account in ({frappe.db.escape(account)}, {frappe.db.escape(party_account)})"
else:
account_condition = " and account = {0}".format(frappe.db.escape(account))
account_condition = f" and account = {frappe.db.escape(account)}"
# get final outstanding amt
bal = flt(
frappe.db.sql(
"""
f"""
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
from `tabGL Entry`
where against_voucher_type=%s and against_voucher=%s
and voucher_type != 'Invoice Discounting'
{0} {1}""".format(
party_condition, account_condition
),
{party_condition} {account_condition}""",
(against_voucher_type, against_voucher),
)[0][0]
or 0.0
@@ -307,12 +308,10 @@ def update_outstanding_amt(
elif against_voucher_type == "Journal Entry":
against_voucher_amount = flt(
frappe.db.sql(
"""
f"""
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
from `tabGL Entry` where voucher_type = 'Journal Entry' and voucher_no = %s
and account = %s and (against_voucher is null or against_voucher='') {0}""".format(
party_condition
),
and account = %s and (against_voucher is null or against_voucher='') {party_condition}""",
(against_voucher, account),
)[0][0]
)
@@ -331,7 +330,9 @@ def update_outstanding_amt(
# Validation : Outstanding can not be negative for JV
if bal < 0 and not on_cancel:
frappe.throw(
_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal))
_("Outstanding for {0} cannot be less than zero ({1})").format(
against_voucher, fmt_money(bal)
)
)
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
@@ -404,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(
"UPDATE `tab{}` SET name = %s, to_rename = 0 where name = %s".format(doctype),
f"UPDATE `tab{doctype}` SET name = %s, to_rename = 0 where name = %s",
(newname, oldname),
auto_commit=True,
)

View File

@@ -14,9 +14,7 @@ from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journ
class TestGLEntry(unittest.TestCase):
def test_round_off_entry(self):
frappe.db.set_value("Company", "_Test Company", "round_off_account", "_Test Write Off - _TC")
frappe.db.set_value(
"Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC"
)
frappe.db.set_value("Company", "_Test Company", "round_off_cost_center", "_Test Cost Center - _TC")
jv = make_journal_entry(
"_Test Account Cost for Goods Sold - _TC",
@@ -73,7 +71,9 @@ class TestGLEntry(unittest.TestCase):
)
self.assertTrue(all(entry.to_rename == 0 for entry in new_gl_entries))
self.assertTrue(all(new.name != old.name for new, old in zip(gl_entries, new_gl_entries)))
self.assertTrue(
all(new.name != old.name for new, old in zip(gl_entries, new_gl_entries, strict=False))
)
new_naming_series_current_value = frappe.db.sql(
"SELECT current from tabSeries where name = %s", naming_series

View File

@@ -55,9 +55,7 @@ class InvoiceDiscounting(AccountsController):
frappe.throw(
_(
"Row({0}): Outstanding Amount cannot be greater than actual Outstanding Amount {1} in {2}"
).format(
record.idx, frappe.bold(actual_outstanding), frappe.bold(record.sales_invoice)
)
).format(record.idx, frappe.bold(actual_outstanding), frappe.bold(record.sales_invoice))
)
def calculate_total_amount(self):
@@ -77,7 +75,9 @@ class InvoiceDiscounting(AccountsController):
self.status = status
self.db_set("status", status)
for d in self.invoices:
frappe.get_doc("Sales Invoice", d.sales_invoice).set_status(update=True, update_modified=False)
frappe.get_doc("Sales Invoice", d.sales_invoice).set_status(
update=True, update_modified=False
)
else:
self.status = "Draft"
if self.docstatus == 1:

View File

@@ -75,8 +75,8 @@ class TestInvoiceDiscounting(unittest.TestCase):
gle = get_gl_entries("Invoice Discounting", inv_disc.name)
expected_gle = {inv.debit_to: [0.0, 200], self.ar_credit: [200, 0.0]}
for i, gle in enumerate(gle):
self.assertEqual([gle.debit, gle.credit], expected_gle.get(gle.account))
for _i, gle_value in enumerate(gle):
self.assertEqual([gle_value.debit, gle_value.credit], expected_gle.get(gle_value.account))
def test_loan_on_submit(self):
inv = create_sales_invoice(rate=300)
@@ -92,9 +92,7 @@ class TestInvoiceDiscounting(unittest.TestCase):
period=60,
)
self.assertEqual(inv_disc.status, "Sanctioned")
self.assertEqual(
inv_disc.loan_end_date, add_days(inv_disc.loan_start_date, inv_disc.loan_period)
)
self.assertEqual(inv_disc.loan_end_date, add_days(inv_disc.loan_start_date, inv_disc.loan_period))
def test_on_disbursed(self):
inv = create_sales_invoice(rate=500)
@@ -262,13 +260,9 @@ class TestInvoiceDiscounting(unittest.TestCase):
je_on_payment.submit()
self.assertEqual(je_on_payment.accounts[0].account, self.ar_discounted)
self.assertEqual(
je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount)
)
self.assertEqual(je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount))
self.assertEqual(je_on_payment.accounts[1].account, self.bank_account)
self.assertEqual(
je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount)
)
self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount))
inv.reload()
self.assertEqual(inv.outstanding_amount, 0)
@@ -304,13 +298,9 @@ class TestInvoiceDiscounting(unittest.TestCase):
je_on_payment.submit()
self.assertEqual(je_on_payment.accounts[0].account, self.ar_unpaid)
self.assertEqual(
je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount)
)
self.assertEqual(je_on_payment.accounts[0].credit_in_account_currency, flt(inv.outstanding_amount))
self.assertEqual(je_on_payment.accounts[1].account, self.bank_account)
self.assertEqual(
je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount)
)
self.assertEqual(je_on_payment.accounts[1].debit_in_account_currency, flt(inv.outstanding_amount))
inv.reload()
self.assertEqual(inv.outstanding_amount, 0)

View File

@@ -14,7 +14,7 @@ class ItemTaxTemplate(Document):
def autoname(self):
if self.company and self.title:
abbr = frappe.get_cached_value("Company", self.company, "abbr")
self.name = "{0} - {1}".format(self.title, abbr)
self.name = f"{self.title} - {abbr}"
def validate_tax_accounts(self):
"""Check whether Tax Rate is not entered twice for same Tax Type"""

View File

@@ -171,7 +171,7 @@ frappe.ui.form.on("Journal Entry", {
!(frm.doc.accounts || []).length ||
((frm.doc.accounts || []).length === 1 && !frm.doc.accounts[0].account)
) {
if (in_list(["Bank Entry", "Cash Entry"], frm.doc.voucher_type)) {
if (["Bank Entry", "Cash Entry"].includes(frm.doc.voucher_type)) {
return frappe.call({
type: "GET",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_default_bank_cash_account",
@@ -283,7 +283,7 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
filters: [[jvd.reference_type, "docstatus", "=", 1]],
};
if (in_list(["Sales Invoice", "Purchase Invoice"], jvd.reference_type)) {
if (["Sales Invoice", "Purchase Invoice"].includes(jvd.reference_type)) {
out.filters.push([jvd.reference_type, "outstanding_amount", "!=", 0]);
// Filter by cost center
if (jvd.cost_center) {
@@ -295,7 +295,7 @@ erpnext.accounts.JournalEntry = class JournalEntry extends frappe.ui.form.Contro
out.filters.push([jvd.reference_type, party_account_field, "=", jvd.account]);
}
if (in_list(["Sales Order", "Purchase Order"], jvd.reference_type)) {
if (["Sales Order", "Purchase Order"].includes(jvd.reference_type)) {
// party_type and party mandatory
frappe.model.validate_missing(jvd, "party_type");
frappe.model.validate_missing(jvd, "party");

View File

@@ -557,7 +557,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2023-11-23 12:11:04.128015",
"modified": "2024-07-18 15:32:29.413598",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -33,7 +33,7 @@ class StockAccountInvalidTransaction(frappe.ValidationError):
class JournalEntry(AccountsController):
def __init__(self, *args, **kwargs):
super(JournalEntry, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def get_feed(self):
return self.voucher_type
@@ -102,7 +102,7 @@ class JournalEntry(AccountsController):
def on_cancel(self):
# References for this Journal are removed on the `on_cancel` event in accounts_controller
super(JournalEntry, self).on_cancel()
super().on_cancel()
self.ignore_linked_doctypes = (
"GL Entry",
"Stock Ledger Entry",
@@ -137,10 +137,7 @@ class JournalEntry(AccountsController):
frappe.get_doc(voucher_type, voucher_no).set_total_advance_paid()
def validate_inter_company_accounts(self):
if (
self.voucher_type == "Inter Company Journal Entry"
and self.inter_company_journal_entry_reference
):
if self.voucher_type == "Inter Company Journal Entry" and self.inter_company_journal_entry_reference:
doc = frappe.get_doc("Journal Entry", self.inter_company_journal_entry_reference)
account_currency = frappe.get_cached_value("Company", self.company, "default_currency")
previous_account_currency = frappe.get_cached_value("Company", doc.company, "default_currency")
@@ -156,7 +153,7 @@ class JournalEntry(AccountsController):
frappe.throw(_("Journal Entry type should be set as Depreciation Entry for asset depreciation"))
def validate_stock_accounts(self):
stock_accounts = get_stock_accounts(self.company, self.doctype, self.name)
stock_accounts = get_stock_accounts(self.company, accounts=self.accounts)
for account in stock_accounts:
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
account, self.posting_date, self.company
@@ -286,10 +283,7 @@ class JournalEntry(AccountsController):
asset.set_status()
def update_inter_company_jv(self):
if (
self.voucher_type == "Inter Company Journal Entry"
and self.inter_company_journal_entry_reference
):
if self.voucher_type == "Inter Company Journal Entry" and self.inter_company_journal_entry_reference:
frappe.db.set_value(
"Journal Entry",
self.inter_company_journal_entry_reference,
@@ -317,17 +311,25 @@ class JournalEntry(AccountsController):
if d.account == inv_disc_doc.short_term_loan and d.reference_name == inv_disc:
if self.docstatus == 1:
if d.credit > 0:
_validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Sanctioned", d.idx)
_validate_invoice_discounting_status(
inv_disc, inv_disc_doc.status, "Sanctioned", d.idx
)
status = "Disbursed"
elif d.debit > 0:
_validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Disbursed", d.idx)
_validate_invoice_discounting_status(
inv_disc, inv_disc_doc.status, "Disbursed", d.idx
)
status = "Settled"
else:
if d.credit > 0:
_validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Disbursed", d.idx)
_validate_invoice_discounting_status(
inv_disc, inv_disc_doc.status, "Disbursed", d.idx
)
status = "Sanctioned"
elif d.debit > 0:
_validate_invoice_discounting_status(inv_disc, inv_disc_doc.status, "Settled", d.idx)
_validate_invoice_discounting_status(
inv_disc, inv_disc_doc.status, "Settled", d.idx
)
status = "Disbursed"
break
if status:
@@ -384,10 +386,7 @@ class JournalEntry(AccountsController):
)
def unlink_inter_company_jv(self):
if (
self.voucher_type == "Inter Company Journal Entry"
and self.inter_company_journal_entry_reference
):
if self.voucher_type == "Inter Company Journal Entry" and self.inter_company_journal_entry_reference:
frappe.db.set_value(
"Journal Entry",
self.inter_company_journal_entry_reference,
@@ -409,9 +408,9 @@ class JournalEntry(AccountsController):
if account_type in ["Receivable", "Payable"]:
if not (d.party_type and d.party):
frappe.throw(
_("Row {0}: Party Type and Party is required for Receivable / Payable account {1}").format(
d.idx, d.account
)
_(
"Row {0}: Party Type and Party is required for Receivable / Payable account {1}"
).format(d.idx, d.account)
)
elif (
d.party_type
@@ -476,16 +475,18 @@ class JournalEntry(AccountsController):
def system_generated_gain_loss(self):
return (
self.voucher_type == "Exchange Gain Or Loss"
and self.multi_currency
and self.is_system_generated
self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency and self.is_system_generated
)
def validate_against_jv(self):
for d in self.get("accounts"):
if d.reference_type == "Journal Entry":
account_root_type = frappe.get_cached_value("Account", d.account, "root_type")
if account_root_type == "Asset" and flt(d.debit) > 0 and not self.system_generated_gain_loss():
if (
account_root_type == "Asset"
and flt(d.debit) > 0
and not self.system_generated_gain_loss()
):
frappe.throw(
_(
"Row #{0}: For {1}, you can select reference document only if account gets credited"
@@ -567,11 +568,13 @@ class JournalEntry(AccountsController):
if d.reference_type == "Purchase Order" and flt(d.credit) > 0:
frappe.throw(
_("Row {0}: Credit entry can not be linked with a {1}").format(d.idx, d.reference_type)
_("Row {0}: Credit entry can not be linked with a {1}").format(
d.idx, d.reference_type
)
)
# set totals
if not d.reference_name in self.reference_totals:
if d.reference_name not in self.reference_totals:
self.reference_totals[d.reference_name] = 0.0
if self.voucher_type not in ("Deferred Revenue", "Deferred Expense"):
@@ -589,7 +592,10 @@ class JournalEntry(AccountsController):
# check if party and account match
if d.reference_type in ("Sales Invoice", "Purchase Invoice"):
if self.voucher_type in ("Deferred Revenue", "Deferred Expense") and d.reference_detail_no:
if (
self.voucher_type in ("Deferred Revenue", "Deferred Expense")
and d.reference_detail_no
):
debit_or_credit = "Debit" if d.debit else "Credit"
party_account = get_deferred_booking_accounts(
d.reference_type, d.reference_detail_no, debit_or_credit
@@ -598,7 +604,8 @@ class JournalEntry(AccountsController):
else:
if d.reference_type == "Sales Invoice":
party_account = (
get_party_account_based_on_invoice_discounting(d.reference_name) or against_voucher[1]
get_party_account_based_on_invoice_discounting(d.reference_name)
or against_voucher[1]
)
else:
party_account = against_voucher[1]
@@ -722,7 +729,9 @@ class JournalEntry(AccountsController):
if not (self.voucher_type == "Exchange Gain Or Loss" and self.multi_currency):
if self.difference:
frappe.throw(
_("Total Debit must be equal to Total Credit. The difference is {0}").format(self.difference)
_("Total Debit must be equal to Total Credit. The difference is {0}").format(
self.difference
)
)
def set_total_debit_credit(self):
@@ -786,7 +795,6 @@ class JournalEntry(AccountsController):
and self.posting_date
)
):
ignore_exchange_rate = False
if self.get("flags") and self.flags.get("ignore_exchange_rate"):
ignore_exchange_rate = True
@@ -1032,27 +1040,21 @@ class JournalEntry(AccountsController):
self.validate_total_debit_and_credit()
def get_values(self):
cond = (
" and outstanding_amount <= {0}".format(self.write_off_amount)
if flt(self.write_off_amount) > 0
else ""
)
cond = f" and outstanding_amount <= {self.write_off_amount}" if flt(self.write_off_amount) > 0 else ""
if self.write_off_based_on == "Accounts Receivable":
return frappe.db.sql(
"""select name, debit_to as account, customer as party, outstanding_amount
from `tabSales Invoice` where docstatus = 1 and company = %s
and outstanding_amount > 0 %s"""
% ("%s", cond),
from `tabSales Invoice` where docstatus = 1 and company = {}
and outstanding_amount > 0 {}""".format("%s", cond),
self.company,
as_dict=True,
)
elif self.write_off_based_on == "Accounts Payable":
return frappe.db.sql(
"""select name, credit_to as account, supplier as party, outstanding_amount
from `tabPurchase Invoice` where docstatus = 1 and company = %s
and outstanding_amount > 0 %s"""
% ("%s", cond),
from `tabPurchase Invoice` where docstatus = 1 and company = {}
and outstanding_amount > 0 {}""".format("%s", cond),
self.company,
as_dict=True,
)
@@ -1161,7 +1163,7 @@ def get_payment_entry_against_order(
"amount_field_bank": amount_field_bank,
"amount": amount,
"debit_in_account_currency": debit_in_account_currency,
"remarks": "Advance Payment received against {0} {1}".format(dt, dn),
"remarks": f"Advance Payment received against {dt} {dn}",
"is_advance": "Yes",
"bank_account": bank_account,
"journal_entry": journal_entry,
@@ -1200,7 +1202,7 @@ def get_payment_entry_against_invoice(
"amount_field_bank": amount_field_bank,
"amount": amount if amount else abs(ref_doc.outstanding_amount),
"debit_in_account_currency": debit_in_account_currency,
"remarks": "Payment received against {0} {1}. {2}".format(dt, dn, ref_doc.remarks),
"remarks": f"Payment received against {dt} {dn}. {ref_doc.remarks}",
"is_advance": "No",
"bank_account": bank_account,
"journal_entry": journal_entry,
@@ -1226,9 +1228,7 @@ def get_payment_entry(ref_doc, args):
)
je = frappe.new_doc("Journal Entry")
je.update(
{"voucher_type": "Bank Entry", "company": ref_doc.company, "remark": args.get("remarks")}
)
je.update({"voucher_type": "Bank Entry", "company": ref_doc.company, "remark": args.get("remarks")})
party_row = je.append(
"accounts",
@@ -1251,9 +1251,7 @@ def get_payment_entry(ref_doc, args):
bank_row = je.append("accounts")
# Make it bank_details
bank_account = get_default_bank_cash_account(
ref_doc.company, "Bank", account=args.get("bank_account")
)
bank_account = get_default_bank_cash_account(ref_doc.company, "Bank", account=args.get("bank_account"))
if bank_account:
bank_row.update(bank_account)
# Modified to include the posting date for which the exchange rate is required.
@@ -1293,7 +1291,7 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
return []
return frappe.db.sql(
"""
f"""
SELECT jv.name, jv.posting_date, jv.user_remark
FROM `tabJournal Entry` jv, `tabJournal Entry Account` jv_detail
WHERE jv_detail.parent = jv.name
@@ -1304,16 +1302,14 @@ def get_against_jv(doctype, txt, searchfield, start, page_len, filters):
OR jv_detail.reference_type = ''
)
AND jv.docstatus = 1
AND jv.`{0}` LIKE %(txt)s
AND jv.`{searchfield}` LIKE %(txt)s
ORDER BY jv.name DESC
LIMIT %(limit)s offset %(offset)s
""".format(
searchfield
),
""",
dict(
account=filters.get("account"),
party=cstr(filters.get("party")),
txt="%{0}%".format(txt),
txt=f"%{txt}%",
offset=start,
limit=page_len,
),
@@ -1335,19 +1331,15 @@ def get_outstanding(args):
condition = " and party=%(party)s" if args.get("party") else ""
against_jv_amount = frappe.db.sql(
"""
f"""
select sum(debit_in_account_currency) - sum(credit_in_account_currency)
from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {0}
and (reference_type is null or reference_type = '')""".format(
condition
),
from `tabJournal Entry Account` where parent=%(docname)s and account=%(account)s {condition}
and (reference_type is null or reference_type = '')""",
args,
)
against_jv_amount = flt(against_jv_amount[0][0]) if against_jv_amount else 0
amount_field = (
"credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency"
)
amount_field = "credit_in_account_currency" if against_jv_amount > 0 else "debit_in_account_currency"
return {amount_field: abs(against_jv_amount)}
elif args.get("doctype") in ("Sales Invoice", "Purchase Invoice"):
party_type = "Customer" if args.get("doctype") == "Sales Invoice" else "Supplier"
@@ -1360,9 +1352,7 @@ def get_outstanding(args):
due_date = invoice.get("due_date")
exchange_rate = (
invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1
)
exchange_rate = invoice.conversion_rate if (args.get("account_currency") != company_currency) else 1
if args["doctype"] == "Sales Invoice":
amount_field = (
@@ -1400,17 +1390,13 @@ def get_party_account_and_currency(company, party_type, party):
@frappe.whitelist()
def get_account_details_and_party_type(
account, date, company, debit=None, credit=None, exchange_rate=None
):
def get_account_details_and_party_type(account, date, company, debit=None, credit=None, exchange_rate=None):
"""Returns dict of account details and party type to be set in Journal Entry on selection of account."""
if not frappe.has_permission("Account"):
frappe.msgprint(_("No Permission"), raise_exception=1)
company_currency = erpnext.get_company_currency(company)
account_details = frappe.db.get_value(
"Account", account, ["account_type", "account_currency"], as_dict=1
)
account_details = frappe.db.get_value("Account", account, ["account_type", "account_currency"], as_dict=1)
if not account_details:
return

View File

@@ -69,10 +69,8 @@ class TestJournalEntry(unittest.TestCase):
self.assertTrue(
frappe.db.sql(
"""select name from `tabJournal Entry Account`
where reference_type = %s and reference_name = %s and {0}=400""".format(
dr_or_cr
),
f"""select name from `tabJournal Entry Account`
where reference_type = %s and reference_name = %s and {dr_or_cr}=400""",
(submitted_voucher.doctype, submitted_voucher.name),
)
)
@@ -84,9 +82,8 @@ class TestJournalEntry(unittest.TestCase):
def advance_paid_testcase(self, base_jv, test_voucher, dr_or_cr):
# Test advance paid field
advance_paid = frappe.db.sql(
"""select advance_paid from `tab%s`
where name=%s"""
% (test_voucher.doctype, "%s"),
"""select advance_paid from `tab{}`
where name={}""".format(test_voucher.doctype, "%s"),
(test_voucher.name),
)
payment_against_order = base_jv.get("accounts")[0].get(dr_or_cr)
@@ -149,19 +146,17 @@ class TestJournalEntry(unittest.TestCase):
"credit_in_account_currency": 0 if diff > 0 else abs(diff),
},
)
jv.insert()
if account_bal == stock_bal:
self.assertRaises(StockAccountInvalidTransaction, jv.submit)
self.assertRaises(StockAccountInvalidTransaction, jv.insert)
frappe.db.rollback()
else:
jv.insert()
jv.submit()
jv.cancel()
def test_multi_currency(self):
jv = make_journal_entry(
"_Test Bank USD - _TC", "_Test Bank - _TC", 100, exchange_rate=50, save=False
)
jv = make_journal_entry("_Test Bank USD - _TC", "_Test Bank - _TC", 100, exchange_rate=50, save=False)
jv.get("accounts")[1].credit_in_account_currency = 5000
jv.submit()
@@ -201,7 +196,7 @@ class TestJournalEntry(unittest.TestCase):
"credit",
"credit_in_account_currency",
):
for i, gle in enumerate(gl_entries):
for _i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account][field], gle[field])
# cancel
@@ -263,7 +258,7 @@ class TestJournalEntry(unittest.TestCase):
"credit",
"credit_in_account_currency",
):
for i, gle in enumerate(gl_entries):
for _i, gle in enumerate(gl_entries):
self.assertEqual(expected_values[gle.account][field], gle[field])
def test_disallow_change_in_account_currency_for_a_party(self):

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
// frappe.ui.form.on("Ledger Health", {
// refresh(frm) {
// },
// });

View File

@@ -0,0 +1,70 @@
{
"actions": [],
"autoname": "autoincrement",
"creation": "2024-03-26 17:01:47.443986",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"voucher_type",
"voucher_no",
"checked_on",
"debit_credit_mismatch",
"general_and_payment_ledger_mismatch"
],
"fields": [
{
"fieldname": "voucher_type",
"fieldtype": "Data",
"label": "Voucher Type"
},
{
"fieldname": "voucher_no",
"fieldtype": "Data",
"label": "Voucher No"
},
{
"default": "0",
"fieldname": "debit_credit_mismatch",
"fieldtype": "Check",
"label": "Debit-Credit mismatch"
},
{
"fieldname": "checked_on",
"fieldtype": "Datetime",
"label": "Checked On"
},
{
"default": "0",
"fieldname": "general_and_payment_ledger_mismatch",
"fieldtype": "Check",
"label": "General and Payment Ledger mismatch"
}
],
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2024-04-09 11:16:07.044484",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Ledger Health",
"naming_rule": "Autoincrement",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"read_only": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,25 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class LedgerHealth(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
checked_on: DF.Datetime | None
debit_credit_mismatch: DF.Check
general_and_payment_ledger_mismatch: DF.Check
name: DF.Int | None
voucher_no: DF.Data | None
voucher_type: DF.Data | None
# end: auto-generated types
pass

View File

@@ -0,0 +1,109 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import frappe
from frappe import qb
from frappe.tests.utils import FrappeTestCase
from frappe.utils import nowdate
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
from erpnext.accounts.utils import run_ledger_health_checks
class TestLedgerHealth(AccountsTestMixin, FrappeTestCase):
def setUp(self):
self.create_company()
self.create_customer()
self.configure_monitoring_tool()
self.clear_old_entries()
def tearDown(self):
frappe.db.rollback()
def configure_monitoring_tool(self):
monitor_settings = frappe.get_doc("Ledger Health Monitor")
monitor_settings.enable_health_monitor = True
monitor_settings.enable_for_last_x_days = 60
monitor_settings.debit_credit_mismatch = True
monitor_settings.general_and_payment_ledger_mismatch = True
exists = [x for x in monitor_settings.companies if x.company == self.company]
if not exists:
monitor_settings.append("companies", {"company": self.company})
monitor_settings.save()
def clear_old_entries(self):
super().clear_old_entries()
lh = qb.DocType("Ledger Health")
qb.from_(lh).delete().run()
def create_journal(self):
je = frappe.new_doc("Journal Entry")
je.company = self.company
je.voucher_type = "Journal Entry"
je.posting_date = nowdate()
je.append(
"accounts",
{
"account": self.debit_to,
"party_type": "Customer",
"party": self.customer,
"debit_in_account_currency": 10000,
},
)
je.append("accounts", {"account": self.income_account, "credit_in_account_currency": 10000})
je.save().submit()
self.je = je
def test_debit_credit_mismatch(self):
self.create_journal()
# manually cause debit-credit mismatch
gle = frappe.db.get_all(
"GL Entry", filters={"voucher_no": self.je.name, "account": self.income_account}
)[0]
frappe.db.set_value("GL Entry", gle.name, "credit", 8000)
run_ledger_health_checks()
expected = {
"voucher_type": self.je.doctype,
"voucher_no": self.je.name,
"debit_credit_mismatch": True,
"general_and_payment_ledger_mismatch": False,
}
actual = frappe.db.get_all(
"Ledger Health",
fields=[
"voucher_type",
"voucher_no",
"debit_credit_mismatch",
"general_and_payment_ledger_mismatch",
],
)
self.assertEqual(len(actual), 1)
self.assertEqual(expected, actual[0])
def test_gl_and_pl_mismatch(self):
self.create_journal()
# manually cause GL and PL discrepancy
ple = frappe.db.get_all("Payment Ledger Entry", filters={"voucher_no": self.je.name})[0]
frappe.db.set_value("Payment Ledger Entry", ple.name, "amount", 11000)
run_ledger_health_checks()
expected = {
"voucher_type": self.je.doctype,
"voucher_no": self.je.name,
"debit_credit_mismatch": False,
"general_and_payment_ledger_mismatch": True,
}
actual = frappe.db.get_all(
"Ledger Health",
fields=[
"voucher_type",
"voucher_no",
"debit_credit_mismatch",
"general_and_payment_ledger_mismatch",
],
)
self.assertEqual(len(actual), 1)
self.assertEqual(expected, actual[0])

View File

@@ -0,0 +1,8 @@
// Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
// frappe.ui.form.on("Ledger Health Monitor", {
// refresh(frm) {
// },
// });

View File

@@ -0,0 +1,104 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2024-03-27 09:38:07.427997",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"enable_health_monitor",
"monitor_section",
"monitor_for_last_x_days",
"debit_credit_mismatch",
"general_and_payment_ledger_mismatch",
"section_break_xdsp",
"companies"
],
"fields": [
{
"default": "0",
"fieldname": "enable_health_monitor",
"fieldtype": "Check",
"label": "Enable Health Monitor"
},
{
"fieldname": "monitor_section",
"fieldtype": "Section Break",
"label": "Configuration"
},
{
"default": "0",
"fieldname": "debit_credit_mismatch",
"fieldtype": "Check",
"label": "Debit-Credit Mismatch"
},
{
"default": "0",
"fieldname": "general_and_payment_ledger_mismatch",
"fieldtype": "Check",
"label": "Discrepancy between General and Payment Ledger"
},
{
"default": "60",
"fieldname": "monitor_for_last_x_days",
"fieldtype": "Int",
"in_list_view": 1,
"label": "Monitor for Last 'X' days",
"reqd": 1
},
{
"fieldname": "section_break_xdsp",
"fieldtype": "Section Break",
"label": "Companies"
},
{
"fieldname": "companies",
"fieldtype": "Table",
"options": "Ledger Health Monitor Company"
}
],
"hide_toolbar": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2024-03-27 10:14:16.511681",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Ledger Health Monitor",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "System Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "Accounts Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "Accounts User",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class LedgerHealthMonitor(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
from erpnext.accounts.doctype.ledger_health_monitor_company.ledger_health_monitor_company import (
LedgerHealthMonitorCompany,
)
companies: DF.Table[LedgerHealthMonitorCompany]
debit_credit_mismatch: DF.Check
enable_health_monitor: DF.Check
general_and_payment_ledger_mismatch: DF.Check
monitor_for_last_x_days: DF.Int
# end: auto-generated types
pass

View File

@@ -0,0 +1,9 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
from frappe.tests.utils import FrappeTestCase
class TestLedgerHealthMonitor(FrappeTestCase):
pass

View File

@@ -0,0 +1,32 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2024-03-27 10:04:45.727054",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"company"
],
"fields": [
{
"fieldname": "company",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Company",
"options": "Company"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2024-03-27 10:06:22.806155",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Ledger Health Monitor Company",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,23 @@
# Copyright (c) 2024, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class LedgerHealthMonitorCompany(Document):
# begin: auto-generated types
# This code is auto-generated. Do not modify anything in this block.
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from frappe.types import DF
company: DF.Link | None
parent: DF.Data
parentfield: DF.Data
parenttype: DF.Data
# end: auto-generated types
pass

View File

@@ -83,7 +83,10 @@ class TestLedgerMerge(unittest.TestCase):
"account": "Indirect Income - _TC",
"merge_accounts": [
{"account": "Indirect Test Income - _TC", "account_name": "Indirect Test Income"},
{"account": "Administrative Test Income - _TC", "account_name": "Administrative Test Income"},
{
"account": "Administrative Test Income - _TC",
"account_name": "Administrative Test Income",
},
],
}
).insert(ignore_permissions=True)

View File

@@ -25,13 +25,11 @@ def get_loyalty_details(
condition += " and expiry_date>='%s' " % expiry_date
loyalty_point_details = frappe.db.sql(
"""select sum(loyalty_points) as loyalty_points,
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""".format(
condition=condition
),
group by customer""",
(customer, loyalty_program, expiry_date),
as_dict=1,
)
@@ -52,9 +50,7 @@ def get_loyalty_program_details_with_points(
include_expired_entry=False,
current_transaction_amount=0,
):
lp_details = get_loyalty_program_details(
customer, loyalty_program, company=company, silent=silent
)
lp_details = get_loyalty_program_details(customer, loyalty_program, company=company, silent=silent)
loyalty_program = frappe.get_doc("Loyalty Program", loyalty_program)
lp_details.update(
get_loyalty_details(customer, loyalty_program.name, expiry_date, company, include_expired_entry)

View File

@@ -19,9 +19,7 @@ class TestLoyaltyProgram(unittest.TestCase):
create_records()
def test_loyalty_points_earned_single_tier(self):
frappe.db.set_value(
"Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty"
)
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty")
# create a new sales invoice
si_original = create_sales_invoice_record()
si_original.insert()
@@ -69,9 +67,7 @@ class TestLoyaltyProgram(unittest.TestCase):
d.cancel()
def test_loyalty_points_earned_multiple_tier(self):
frappe.db.set_value(
"Customer", "Test Loyalty Customer", "loyalty_program", "Test Multiple Loyalty"
)
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Multiple Loyalty")
# assign multiple tier program to the customer
customer = frappe.get_doc("Customer", {"customer_name": "Test Loyalty Customer"})
customer.loyalty_program = frappe.get_doc(
@@ -128,9 +124,7 @@ class TestLoyaltyProgram(unittest.TestCase):
def test_cancel_sales_invoice(self):
"""cancelling the sales invoice should cancel the earned points"""
frappe.db.set_value(
"Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty"
)
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty")
# create a new sales invoice
si = create_sales_invoice_record()
si.insert()
@@ -140,7 +134,7 @@ class TestLoyaltyProgram(unittest.TestCase):
"Loyalty Point Entry",
{"invoice_type": "Sales Invoice", "invoice": si.name, "customer": si.customer},
)
self.assertEqual(True, not (lpe is None))
self.assertEqual(True, lpe is not None)
# cancelling sales invoice
si.cancel()
@@ -148,9 +142,7 @@ class TestLoyaltyProgram(unittest.TestCase):
self.assertEqual(True, (lpe is None))
def test_sales_invoice_return(self):
frappe.db.set_value(
"Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty"
)
frappe.db.set_value("Customer", "Test Loyalty Customer", "loyalty_program", "Test Single Loyalty")
# create a new sales invoice
si_original = create_sales_invoice_record(2)
si_original.conversion_rate = flt(1)
@@ -346,9 +338,7 @@ def create_records():
).insert()
# create item price
if not frappe.db.exists(
"Item Price", {"price_list": "Standard Selling", "item_code": "Loyal Item"}
):
if not frappe.db.exists("Item Price", {"price_list": "Standard Selling", "item_code": "Loyal Item"}):
frappe.get_doc(
{
"doctype": "Item Price",

View File

@@ -37,9 +37,7 @@ class MonthlyDistribution(Document):
total = sum(flt(d.percentage_allocation) for d in self.get("percentages"))
if flt(total, 2) != 100.0:
frappe.throw(
_("Percentage Allocation should be equal to 100%") + " ({0}%)".format(str(flt(total, 2)))
)
frappe.throw(_("Percentage Allocation should be equal to 100%") + f" ({flt(total, 2)!s}%)")
def get_periodwise_distribution_data(distribution_id, period_list, periodicity):

View File

@@ -83,9 +83,7 @@ class TestOpeningInvoiceCreationTool(FrappeTestCase):
company = "_Test Opening Invoice Company"
party_1, party_2 = make_customer("Customer A"), make_customer("Customer B")
old_default_receivable_account = frappe.db.get_value(
"Company", company, "default_receivable_account"
)
old_default_receivable_account = frappe.db.get_value("Company", company, "default_receivable_account")
frappe.db.set_value("Company", company, "default_receivable_account", "")
if not frappe.db.exists("Cost Center", "_Test Opening Invoice Company - _TOIC"):
@@ -121,9 +119,7 @@ class TestOpeningInvoiceCreationTool(FrappeTestCase):
self.assertTrue(error_log)
# teardown
frappe.db.set_value(
"Company", company, "default_receivable_account", old_default_receivable_account
)
frappe.db.set_value("Company", company, "default_receivable_account", old_default_receivable_account)
def test_renaming_of_invoice_using_invoice_number_field(self):
company = "_Test Opening Invoice Company"
@@ -169,7 +165,7 @@ def get_opening_invoice_creation_dict(**args):
{
"qty": 1.0,
"outstanding_amount": 300,
"party": args.get("party_1") or "_Test {0}".format(party),
"party": args.get("party_1") or f"_Test {party}",
"item_name": "Opening Item",
"due_date": "2016-09-10",
"posting_date": "2016-09-05",
@@ -179,7 +175,7 @@ def get_opening_invoice_creation_dict(**args):
{
"qty": 2.0,
"outstanding_amount": 250,
"party": args.get("party_2") or "_Test {0} 1".format(party),
"party": args.get("party_2") or f"_Test {party} 1",
"item_name": "Opening Item",
"due_date": "2016-09-10",
"posting_date": "2016-09-05",

View File

@@ -24,7 +24,10 @@ class PartyLink(Document):
if existing_party_link:
frappe.throw(
_("{} {} is already linked with {} {}").format(
self.primary_role, bold(self.primary_party), self.secondary_role, bold(self.secondary_party)
self.primary_role,
bold(self.primary_party),
self.secondary_role,
bold(self.secondary_party),
)
)

View File

@@ -15,14 +15,23 @@ frappe.ui.form.on('Payment Entry', {
}
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
if (frm.is_new()) {
set_default_party_type(frm);
}
},
setup: function(frm) {
frm.set_query("paid_from", function() {
frm.events.validate_company(frm);
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
var account_types = ["Pay", "Internal Transfer"].includes(frm.doc.payment_type) ?
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
if (frm.doc.party_type == "Shareholder") {
account_types.push("Equity");
}
return {
filters: {
"account_type": ["in", account_types],
@@ -75,8 +84,11 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query("paid_to", function() {
frm.events.validate_company(frm);
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
var account_types = ["Receive", "Internal Transfer"].includes(frm.doc.payment_type) ?
["Bank", "Cash"] : [frappe.boot.party_account_types[frm.doc.party_type]];
if (frm.doc.party_type == "Shareholder") {
account_types.push("Equity");
}
return {
filters: {
"account_type": ["in", account_types],
@@ -121,7 +133,7 @@ frappe.ui.form.on('Payment Entry', {
frm.set_query('payment_term', 'references', function(frm, cdt, cdn) {
const child = locals[cdt][cdn];
if (in_list(['Purchase Invoice', 'Sales Invoice'], child.reference_doctype) && child.reference_name) {
if (['Purchase Invoice', 'Sales Invoice'].includes(child.reference_doctype) && child.reference_name) {
return {
query: "erpnext.controllers.queries.get_payment_terms_for_references",
filters: {
@@ -145,10 +157,50 @@ frappe.ui.form.on('Payment Entry', {
filters: filters
};
});
frm.set_query("payment_request", "references", function (doc, cdt, cdn) {
const row = frappe.get_doc(cdt, cdn);
return {
query: "erpnext.accounts.doctype.payment_request.payment_request.get_open_payment_requests_query",
filters: {
reference_doctype: row.reference_doctype,
reference_name: row.reference_name,
company: doc.company,
status: ["!=", "Paid"],
outstanding_amount: [">", 0], // for compatibility with old data
docstatus: 1,
},
};
});
frm.set_query("sales_taxes_and_charges_template", function () {
return {
filters: {
company: frm.doc.company,
disabled: false,
},
};
});
frm.set_query("purchase_taxes_and_charges_template", function () {
return {
filters: {
company: frm.doc.company,
disabled: false,
},
};
});
frm.add_fetch(
"payment_request",
"outstanding_amount",
"payment_request_outstanding",
"Payment Entry Reference"
);
},
refresh: function(frm) {
erpnext.hide_company();
refresh: function (frm) {
erpnext.hide_company(frm);
frm.events.hide_unhide_fields(frm);
frm.events.set_dynamic_labels(frm);
frm.events.show_general_ledger(frm);
@@ -159,6 +211,7 @@ frappe.ui.form.on('Payment Entry', {
}
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
frappe.flags.allocate_payment_amount = true;
},
validate_company: (frm) => {
@@ -179,7 +232,7 @@ frappe.ui.form.on('Payment Entry', {
},
hide_unhide_fields: function(frm) {
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company)?.default_currency: "";
frm.toggle_display("source_exchange_rate",
(frm.doc.paid_amount && frm.doc.paid_from_account_currency != company_currency));
@@ -225,7 +278,7 @@ frappe.ui.form.on('Payment Entry', {
},
set_dynamic_labels: function(frm) {
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company).default_currency: "";
var company_currency = frm.doc.company? frappe.get_doc(":Company", frm.doc.company)?.default_currency: "";
frm.set_currency_labels(["base_paid_amount", "base_received_amount", "base_total_allocated_amount",
"difference_amount", "base_paid_amount_after_tax", "base_received_amount_after_tax",
@@ -275,6 +328,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",
"references", "total_allocated_amount"], function(i, field) {
@@ -309,6 +363,12 @@ frappe.ui.form.on('Payment Entry', {
return {
query: "erpnext.controllers.queries.customer_query"
}
} else if (frm.doc.party_type == "Shareholder") {
return {
filters: {
company: frm.doc.company,
},
};
}
});
@@ -485,8 +545,8 @@ frappe.ui.form.on('Payment Entry', {
if (frm.doc.paid_from_account_currency == company_currency) {
frm.set_value("source_exchange_rate", 1);
} else if (frm.doc.paid_from){
if (in_list(["Internal Transfer", "Pay"], frm.doc.payment_type)) {
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
if (["Internal Transfer", "Pay"].includes(frm.doc.payment_type)) {
let company_currency = frappe.get_doc(":Company", frm.doc.company)?.default_currency;
frappe.call({
method: "erpnext.setup.utils.get_exchange_rate",
args: {
@@ -602,10 +662,9 @@ frappe.ui.form.on('Payment Entry', {
frm.set_value("base_received_amount",
flt(frm.doc.received_amount) * flt(frm.doc.target_exchange_rate));
if(frm.doc.payment_type == "Pay")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount, 1);
else
frm.events.set_unallocated_amount(frm);
if (frm.doc.payment_type == "Pay")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.received_amount, true);
else frm.events.set_unallocated_amount(frm);
frm.set_paid_amount_based_on_received_amount = false;
frm.events.hide_unhide_fields(frm);
@@ -623,10 +682,9 @@ frappe.ui.form.on('Payment Entry', {
frm.set_value("base_received_amount", frm.doc.base_paid_amount);
}
if(frm.doc.payment_type == "Receive")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount, 1);
else
frm.events.set_unallocated_amount(frm);
if (frm.doc.payment_type == "Receive")
frm.events.allocate_party_amount_against_ref_docs(frm, frm.doc.paid_amount, true);
else frm.events.set_unallocated_amount(frm);
},
get_outstanding_invoices_or_orders: function(frm, get_outstanding_invoices, get_orders_to_be_billed) {
@@ -770,6 +828,7 @@ frappe.ui.form.on('Payment Entry', {
c.outstanding_amount = d.outstanding_amount;
c.bill_no = d.bill_no;
c.payment_term = d.payment_term;
c.payment_term_outstanding = d.payment_term_outstanding;
c.allocated_amount = d.allocated_amount;
if(!in_list(frm.events.get_order_doctypes(frm), d.voucher_type)) {
@@ -811,10 +870,12 @@ frappe.ui.form.on('Payment Entry', {
}
}
frm.events.allocate_party_amount_against_ref_docs(frm,
(frm.doc.payment_type=="Receive" ? frm.doc.paid_amount : frm.doc.received_amount));
}
frm.events.allocate_party_amount_against_ref_docs(
frm,
frm.doc.payment_type == "Receive" ? frm.doc.paid_amount : frm.doc.received_amount,
false
);
},
});
},
@@ -826,76 +887,13 @@ frappe.ui.form.on('Payment Entry', {
return ["Sales Invoice", "Purchase Invoice"];
},
allocate_party_amount_against_ref_docs: function(frm, paid_amount, paid_amount_change) {
var total_positive_outstanding_including_order = 0;
var total_negative_outstanding = 0;
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
function(d) { return flt(d.amount) }));
allocate_party_amount_against_ref_docs: async function (frm, paid_amount, paid_amount_change) {
await frm.call("allocate_amount_to_references", {
paid_amount: paid_amount,
paid_amount_change: paid_amount_change,
allocate_payment_amount: frappe.flags.allocate_payment_amount ?? false,
});
paid_amount -= total_deductions;
$.each(frm.doc.references || [], function(i, row) {
if(flt(row.outstanding_amount) > 0)
total_positive_outstanding_including_order += flt(row.outstanding_amount);
else
total_negative_outstanding += Math.abs(flt(row.outstanding_amount));
})
var allocated_negative_outstanding = 0;
if (
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")
) {
if(total_positive_outstanding_including_order > paid_amount) {
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ?
total_negative_outstanding : remaining_outstanding;
}
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
total_negative_outstanding = flt(total_negative_outstanding, precision("outstanding_amount"))
if(paid_amount > total_negative_outstanding) {
if(total_negative_outstanding == 0) {
frappe.msgprint(
__("Cannot {0} {1} {2} without any negative outstanding invoice", [frm.doc.payment_type,
(frm.doc.party_type=="Customer" ? "to" : "from"), frm.doc.party_type])
);
return false
} else {
frappe.msgprint(
__("Paid Amount cannot be greater than total negative outstanding amount {0}", [total_negative_outstanding])
);
return false;
}
} else {
allocated_positive_outstanding = total_negative_outstanding - paid_amount;
allocated_negative_outstanding = paid_amount +
(total_positive_outstanding_including_order < allocated_positive_outstanding ?
total_positive_outstanding_including_order : allocated_positive_outstanding)
}
}
$.each(frm.doc.references || [], function(i, row) {
if (frappe.flags.allocate_payment_amount == 0) {
//If allocate payment amount checkbox is unchecked, set zero to allocate amount
row.allocated_amount = 0;
} else if (frappe.flags.allocate_payment_amount != 0 && (!row.allocated_amount || paid_amount_change)) {
if (row.outstanding_amount > 0 && allocated_positive_outstanding >= 0) {
row.allocated_amount = (row.outstanding_amount >= allocated_positive_outstanding) ?
allocated_positive_outstanding : row.outstanding_amount;
allocated_positive_outstanding -= flt(row.allocated_amount);
} else if (row.outstanding_amount < 0 && allocated_negative_outstanding) {
row.allocated_amount = (Math.abs(row.outstanding_amount) >= allocated_negative_outstanding) ?
-1*allocated_negative_outstanding : row.outstanding_amount;
allocated_negative_outstanding -= Math.abs(flt(row.allocated_amount));
}
}
})
frm.refresh_fields()
frm.events.set_total_allocated_amount(frm);
},
@@ -988,7 +986,7 @@ frappe.ui.form.on('Payment Entry', {
}
if(frm.doc.party_type=="Customer" &&
!in_list(["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"], row.reference_doctype)
!["Sales Order", "Sales Invoice", "Journal Entry", "Dunning"].includes(row.reference_doctype)
) {
frappe.model.set_value(row.doctype, row.name, "reference_doctype", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Sales Order, Sales Invoice, Journal Entry or Dunning", [row.idx]));
@@ -996,7 +994,7 @@ frappe.ui.form.on('Payment Entry', {
}
if(frm.doc.party_type=="Supplier" &&
!in_list(["Purchase Order", "Purchase Invoice", "Journal Entry"], row.reference_doctype)
!["Purchase Order", "Purchase Invoice", "Journal Entry"].includes(row.reference_doctype)
) {
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
@@ -1080,7 +1078,7 @@ frappe.ui.form.on('Payment Entry', {
bank_account: function(frm) {
const field = frm.doc.payment_type == "Pay" ? "paid_from":"paid_to";
if (frm.doc.bank_account && in_list(['Pay', 'Receive'], frm.doc.payment_type)) {
if (frm.doc.bank_account && ['Pay', 'Receive'].includes(frm.doc.payment_type)) {
frappe.call({
method: "erpnext.accounts.doctype.bank_account.bank_account.get_bank_account_details",
args: {
@@ -1088,7 +1086,9 @@ frappe.ui.form.on('Payment Entry', {
},
callback: function(r) {
if (r.message) {
frm.set_value(field, r.message.account);
if (!frm.doc.mode_of_payment) {
frm.set_value(field, r.message.account);
}
frm.set_value('bank', r.message.bank);
frm.set_value('bank_account_no', r.message.bank_account_no);
}
@@ -1376,6 +1376,62 @@ frappe.ui.form.on('Payment Entry', {
return current_tax_amount;
},
cost_center: function (frm) {
if (frm.doc.posting_date && (frm.doc.paid_from || frm.doc.paid_to)) {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_and_account_balance",
args: {
company: frm.doc.company,
date: frm.doc.posting_date,
paid_from: frm.doc.paid_from,
paid_to: frm.doc.paid_to,
ptype: frm.doc.party_type,
pty: frm.doc.party,
cost_center: frm.doc.cost_center,
},
callback: function (r, rt) {
if (r.message) {
frappe.run_serially([
() => {
frm.set_value(
"paid_from_account_balance",
r.message.paid_from_account_balance
);
frm.set_value("paid_to_account_balance", r.message.paid_to_account_balance);
frm.set_value("party_balance", r.message.party_balance);
},
]);
}
},
});
}
},
after_save: function (frm) {
const { matched_payment_requests } = frappe.last_response;
if (!matched_payment_requests) return;
const COLUMN_LABEL = [
[__("Reference DocType"), __("Reference Name"), __("Allocated Amount"), __("Payment Request")],
];
frappe.msgprint({
title: __("Unset Matched Payment Request"),
message: COLUMN_LABEL.concat(matched_payment_requests),
as_table: true,
wide: true,
primary_action: {
label: __("Allocate Payment Request"),
action() {
frappe.hide_msgprint();
frm.call("set_matched_payment_requests", { matched_payment_requests }, () => {
frm.dirty();
});
},
},
});
},
});
@@ -1393,8 +1449,9 @@ frappe.ui.form.on('Payment Entry Reference', {
args: {
reference_doctype: row.reference_doctype,
reference_name: row.reference_name,
party_account_currency: frm.doc.payment_type=="Receive" ?
frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency
party_account_currency: frm.doc.payment_type == "Receive" ? frm.doc.paid_from_account_currency : frm.doc.paid_to_account_currency,
party_type: frm.doc.party_type,
party: frm.doc.party,
},
callback: function(r, rt) {
if(r.message) {
@@ -1461,35 +1518,18 @@ frappe.ui.form.on('Payment Entry Deduction', {
deductions_remove: function(frm) {
frm.events.set_unallocated_amount(frm);
}
})
frappe.ui.form.on('Payment Entry', {
cost_center: function(frm){
if (frm.doc.posting_date && (frm.doc.paid_from||frm.doc.paid_to)) {
return frappe.call({
method: "erpnext.accounts.doctype.payment_entry.payment_entry.get_party_and_account_balance",
args: {
company: frm.doc.company,
date: frm.doc.posting_date,
paid_from: frm.doc.paid_from,
paid_to: frm.doc.paid_to,
ptype: frm.doc.party_type,
pty: frm.doc.party,
cost_center: frm.doc.cost_center
},
callback: function(r, rt) {
if(r.message) {
frappe.run_serially([
() => {
frm.set_value("paid_from_account_balance", r.message.paid_from_account_balance);
frm.set_value("paid_to_account_balance", r.message.paid_to_account_balance);
frm.set_value("party_balance", r.message.party_balance);
}
]);
}
}
});
}
},
})
});
function set_default_party_type(frm) {
if (frm.doc.party) return;
let party_type;
if (frm.doc.payment_type == "Receive") {
party_type = "Customer";
} else if (frm.doc.payment_type == "Pay") {
party_type = "Supplier";
}
if (party_type) frm.set_value("party_type", party_type);
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,7 +2,6 @@
# See license.txt
import json
import unittest
import frappe
from frappe import qb
@@ -163,7 +162,7 @@ class TestPaymentEntry(FrappeTestCase):
supplier.on_hold = 0
supplier.save()
except:
except Exception:
pass
else:
raise Exception
@@ -470,9 +469,7 @@ class TestPaymentEntry(FrappeTestCase):
si.save()
si.submit()
pe = get_payment_entry(
"Sales Invoice", si.name, bank_account="_Test Bank - _TC", bank_amount=4700
)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC", bank_amount=4700)
pe.reference_no = si.name
pe.reference_date = nowdate()
@@ -639,9 +636,7 @@ class TestPaymentEntry(FrappeTestCase):
pe.set_exchange_rate()
pe.set_amounts()
self.assertEqual(
pe.source_exchange_rate, 65.1, "{0} is not equal to {1}".format(pe.source_exchange_rate, 65.1)
)
self.assertEqual(pe.source_exchange_rate, 65.1, f"{pe.source_exchange_rate} is not equal to {65.1}")
def test_internal_transfer_usd_to_inr(self):
pe = frappe.new_doc("Payment Entry")
@@ -910,9 +905,7 @@ class TestPaymentEntry(FrappeTestCase):
cost_center = "_Test Cost Center for BS Account - _TC"
create_cost_center(cost_center_name="_Test Cost Center for BS Account", company="_Test Company")
pi = make_purchase_invoice_against_cost_center(
cost_center=cost_center, credit_to="Creditors - _TC"
)
pi = make_purchase_invoice_against_cost_center(cost_center=cost_center, credit_to="Creditors - _TC")
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank - _TC")
self.assertEqual(pe.cost_center, pi.cost_center)
@@ -953,9 +946,7 @@ class TestPaymentEntry(FrappeTestCase):
si = create_sales_invoice_against_cost_center(cost_center=cost_center, debit_to="Debtors - _TC")
account_balance = get_balance_on(account="_Test Bank - _TC", cost_center=si.cost_center)
party_balance = get_balance_on(
party_type="Customer", party=si.customer, cost_center=si.cost_center
)
party_balance = get_balance_on(party_type="Customer", party=si.customer, cost_center=si.cost_center)
party_account_balance = get_balance_on(si.debit_to, cost_center=si.cost_center)
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank - _TC")
@@ -1096,7 +1087,9 @@ class TestPaymentEntry(FrappeTestCase):
pe.source_exchange_rate = 50
pe.save()
ref_details = get_reference_details(so.doctype, so.name, pe.paid_from_account_currency)
ref_details = get_reference_details(
so.doctype, so.name, pe.paid_from_account_currency, "Customer", so.customer
)
expected_response = {
"total_amount": 5000.0,
"outstanding_amount": 5000.0,
@@ -1214,7 +1207,7 @@ class TestPaymentEntry(FrappeTestCase):
Overallocation validation shouldn't fire for Template without "Allocate Payment based on Payment Terms" enabled
"""
customer = create_customer()
create_customer()
create_payment_terms_template()
template = frappe.get_doc("Payment Terms Template", "Test Receivable Template")
@@ -1273,9 +1266,7 @@ class TestPaymentEntry(FrappeTestCase):
create_payment_terms_template()
# SI has an earlier due date and SI2 has a later due date
si = create_sales_invoice(
qty=1, rate=100, customer=customer, posting_date=add_days(nowdate(), -4)
)
si = create_sales_invoice(qty=1, rate=100, customer=customer, posting_date=add_days(nowdate(), -4))
si2 = create_sales_invoice(do_not_save=1, qty=1, rate=100, customer=customer)
si2.payment_terms_template = "Test Receivable Template"
si2.submit()
@@ -1374,6 +1365,79 @@ class TestPaymentEntry(FrappeTestCase):
expected_out_str = json.dumps(sorted(expected_pl_entries, key=json.dumps))
self.assertEqual(out_str, expected_out_str)
@change_settings("Accounts Settings", {"delete_linked_ledger_entries": 1})
def test_delete_linked_exchange_gain_loss_journal(self):
from erpnext.accounts.doctype.account.test_account import create_account
from erpnext.accounts.doctype.opening_invoice_creation_tool.test_opening_invoice_creation_tool import (
make_customer,
)
debtors = create_account(
account_name="Debtors USD",
parent_account="Accounts Receivable - _TC",
company="_Test Company",
account_currency="USD",
account_type="Receivable",
)
# create a customer
customer = make_customer(customer="_Test Party USD")
cust_doc = frappe.get_doc("Customer", customer)
cust_doc.default_currency = "USD"
test_account_details = {
"company": "_Test Company",
"account": debtors,
}
cust_doc.append("accounts", test_account_details)
cust_doc.save()
# create a sales invoice
si = create_sales_invoice(
customer=customer,
currency="USD",
conversion_rate=83.970000000,
debit_to=debtors,
do_not_save=1,
)
si.party_account_currency = "USD"
si.save()
si.submit()
# create a payment entry for the invoice
pe = get_payment_entry("Sales Invoice", si.name)
pe.reference_no = "1"
pe.reference_date = frappe.utils.nowdate()
pe.paid_amount = 100
pe.source_exchange_rate = 90
pe.append(
"deductions",
{
"account": "_Test Exchange Gain/Loss - _TC",
"cost_center": "_Test Cost Center - _TC",
"amount": 2710,
},
)
pe.save()
pe.submit()
# check creation of journal entry
jv = frappe.get_all(
"Journal Entry Account",
{"reference_type": pe.doctype, "reference_name": pe.name, "docstatus": 1},
pluck="parent",
)
self.assertTrue(jv)
# check cancellation of payment entry and journal entry
pe.cancel()
self.assertTrue(pe.docstatus == 2)
self.assertTrue(frappe.db.get_value("Journal Entry", {"name": jv[0]}, "docstatus") == 2)
# check deletion of payment entry and journal entry
pe.delete()
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, pe.doctype, pe.name)
self.assertRaises(frappe.DoesNotExistError, frappe.get_doc, "Journal Entry", jv[0])
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
@@ -1401,12 +1465,11 @@ def create_payment_entry(**args):
def create_payment_terms_template():
create_payment_term("Basic Amount Receivable")
create_payment_term("Tax Receivable")
if not frappe.db.exists("Payment Terms Template", "Test Receivable Template"):
payment_term_template = frappe.get_doc(
frappe.get_doc(
{
"doctype": "Payment Terms Template",
"template_name": "Test Receivable Template",

View File

@@ -10,12 +10,15 @@
"due_date",
"bill_no",
"payment_term",
"payment_term_outstanding",
"column_break_4",
"total_amount",
"outstanding_amount",
"allocated_amount",
"exchange_rate",
"exchange_gain_loss"
"exchange_gain_loss",
"payment_request",
"payment_request_outstanding"
],
"fields": [
{
@@ -101,12 +104,33 @@
"label": "Exchange Gain/Loss",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"fieldname": "payment_request",
"fieldtype": "Link",
"label": "Payment Request",
"options": "Payment Request"
},
{
"depends_on": "eval: doc.payment_term",
"fieldname": "payment_term_outstanding",
"fieldtype": "Float",
"label": "Payment Term Outstanding",
"read_only": 1
},
{
"depends_on": "eval: doc.payment_request && doc.payment_request_outstanding",
"fieldname": "payment_request_outstanding",
"fieldtype": "Float",
"is_virtual": 1,
"label": "Payment Request Outstanding",
"read_only": 1
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-12-12 12:31:44.919895",
"modified": "2024-09-16 18:11:50.019343",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry Reference",

View File

@@ -1,9 +1,14 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import frappe
from frappe.model.document import Document
class PaymentEntryReference(Document):
pass
@property
def payment_request_outstanding(self):
if not self.payment_request:
return
return frappe.db.get_value("Payment Request", self.payment_request, "outstanding_amount")

View File

@@ -108,9 +108,9 @@ class PaymentLedgerEntry(Document):
):
if not self.get(dimension.fieldname):
frappe.throw(
_("Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}.").format(
dimension.label, self.account
)
_(
"Accounting Dimension <b>{0}</b> is required for 'Profit and Loss' account {1}."
).format(dimension.label, self.account)
)
if (
@@ -121,9 +121,9 @@ class PaymentLedgerEntry(Document):
):
if not self.get(dimension.fieldname):
frappe.throw(
_("Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}.").format(
dimension.label, self.account
)
_(
"Accounting Dimension <b>{0}</b> is required for 'Balance Sheet' account {1}."
).format(dimension.label, self.account)
)
def validate(self):

View File

@@ -84,11 +84,14 @@ class TestPaymentLedgerEntry(FrappeTestCase):
self.customer = customer.name
def create_sales_invoice(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
self, qty=1, rate=100, posting_date=None, do_not_save=False, do_not_submit=False
):
"""
Helper function to populate default values in sales invoice
"""
if posting_date is None:
posting_date = nowdate()
sinv = create_sales_invoice(
qty=qty,
rate=rate,
@@ -112,10 +115,12 @@ class TestPaymentLedgerEntry(FrappeTestCase):
)
return sinv
def create_payment_entry(self, amount=100, posting_date=nowdate()):
def create_payment_entry(self, amount=100, posting_date=None):
"""
Helper function to populate default values in payment entry
"""
if posting_date is None:
posting_date = nowdate()
payment = create_payment_entry(
company=self.company,
payment_type="Receive",
@@ -128,9 +133,10 @@ class TestPaymentLedgerEntry(FrappeTestCase):
payment.posting_date = posting_date
return payment
def create_sales_order(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
):
def create_sales_order(self, qty=1, rate=100, posting_date=None, do_not_save=False, do_not_submit=False):
if posting_date is None:
posting_date = nowdate()
so = make_sales_order(
company=self.company,
transaction_date=posting_date,
@@ -159,9 +165,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
for doctype in doctype_list:
qb.from_(qb.DocType(doctype)).delete().where(qb.DocType(doctype).company == self.company).run()
def create_journal_entry(
self, acc1=None, acc2=None, amount=0, posting_date=None, cost_center=None
):
def create_journal_entry(self, acc1=None, acc2=None, amount=0, posting_date=None, cost_center=None):
je = frappe.new_doc("Journal Entry")
je.posting_date = posting_date or nowdate()
je.company = self.company
@@ -319,9 +323,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
ple.amount,
ple.delinked,
)
.where(
(ple.against_voucher_type == cr_note1.doctype) & (ple.against_voucher_no == cr_note1.name)
)
.where((ple.against_voucher_type == cr_note1.doctype) & (ple.against_voucher_no == cr_note1.name))
.orderby(ple.creation)
.run(as_dict=True)
)
@@ -362,9 +364,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
)
cr_note2.is_return = 1
cr_note2 = cr_note2.save().submit()
je1 = self.create_journal_entry(
self.debit_to, self.debit_to, amount, posting_date=transaction_date
)
je1 = self.create_journal_entry(self.debit_to, self.debit_to, amount, posting_date=transaction_date)
je1.get("accounts")[0].party_type = je1.get("accounts")[1].party_type = "Customer"
je1.get("accounts")[0].party = je1.get("accounts")[1].party = self.customer
je1.get("accounts")[0].reference_type = cr_note2.doctype
@@ -419,9 +419,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
ple.amount,
ple.delinked,
)
.where(
(ple.against_voucher_type == cr_note2.doctype) & (ple.against_voucher_no == cr_note2.name)
)
.where((ple.against_voucher_type == cr_note2.doctype) & (ple.against_voucher_no == cr_note2.name))
.orderby(ple.creation)
.run(as_dict=True)
)
@@ -518,7 +516,7 @@ class TestPaymentLedgerEntry(FrappeTestCase):
amount = 100
so = self.create_sales_order(qty=1, rate=amount, posting_date=transaction_date).save().submit()
pe = get_payment_entry(so.doctype, so.name).save().submit()
get_payment_entry(so.doctype, so.name).save().submit()
so.reload()
so.cancel()

View File

@@ -36,7 +36,7 @@ frappe.ui.form.on("Payment Order", {
// payment Entry
if (frm.doc.docstatus === 1 && frm.doc.payment_order_type === "Payment Request") {
frm.add_custom_button(__("Create Payment Entries"), function () {
frm.add_custom_button(__("Create Journal Entries"), function () {
frm.trigger("make_payment_records");
});
}
@@ -71,6 +71,7 @@ frappe.ui.form.on("Payment Order", {
target: frm,
date_field: "posting_date",
setters: {
party_type: "Supplier",
party: frm.doc.supplier || "",
},
get_query_filters: {
@@ -91,6 +92,7 @@ frappe.ui.form.on("Payment Order", {
source_doctype: "Payment Request",
target: frm,
setters: {
party_type: "Supplier",
party: frm.doc.supplier || "",
},
get_query_filters: {

View File

@@ -66,9 +66,7 @@ def make_journal_entry(doc, supplier, mode_of_payment=None):
je = frappe.new_doc("Journal Entry")
je.payment_order = doc.name
je.posting_date = nowdate()
mode_of_payment_type = frappe._dict(
frappe.get_all("Mode of Payment", fields=["name", "type"], as_list=1)
)
mode_of_payment_type = frappe._dict(frappe.get_all("Mode of Payment", fields=["name", "type"], as_list=1))
je.voucher_type = "Bank Entry"
if mode_of_payment and mode_of_payment_type.get(mode_of_payment) == "Cash":

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe.tests.utils import FrappeTestCase
@@ -41,9 +40,7 @@ class TestPaymentOrder(FrappeTestCase):
payment_entry.insert()
payment_entry.submit()
doc = create_payment_order_against_payment_entry(
payment_entry, "Payment Entry", self.bank_account
)
doc = create_payment_order_against_payment_entry(payment_entry, "Payment Entry", self.bank_account)
reference_doc = doc.get("references")[0]
self.assertEqual(reference_doc.reference_name, payment_entry.name)
self.assertEqual(reference_doc.reference_doctype, "Payment Entry")

View File

@@ -25,7 +25,7 @@ from erpnext.controllers.accounts_controller import get_advance_payment_entries_
class PaymentReconciliation(Document):
def __init__(self, *args, **kwargs):
super(PaymentReconciliation, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
self.common_filter_conditions = []
self.accounting_dimension_filter_conditions = []
self.ple_posting_date_filter = []
@@ -144,12 +144,14 @@ class PaymentReconciliation(Document):
if self.get("cost_center"):
conditions.append(jea.cost_center == self.cost_center)
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "debit_in_account_currency"
)
conditions.append(jea[dr_or_cr].gt(0))
account_type = erpnext.get_party_account_type(self.party_type)
if account_type == "Receivable":
dr_or_cr = jea.credit_in_account_currency - jea.debit_in_account_currency
elif account_type == "Payable":
dr_or_cr = jea.debit_in_account_currency - jea.credit_in_account_currency
conditions.append(dr_or_cr.gt(0))
if self.bank_cash_account:
conditions.append(jea.against_account.like(f"%%{self.bank_cash_account}%%"))
@@ -164,7 +166,7 @@ class PaymentReconciliation(Document):
je.posting_date,
je.remark.as_("remarks"),
jea.name.as_("reference_row"),
jea[dr_or_cr].as_("amount"),
dr_or_cr.as_("amount"),
jea.is_advance,
jea.exchange_rate,
jea.account_currency.as_("currency"),
@@ -200,6 +202,7 @@ class PaymentReconciliation(Document):
conditions.append(doc.docstatus == 1)
conditions.append(doc[frappe.scrub(self.party_type)] == self.party)
conditions.append(doc.is_return == 1)
conditions.append(doc.outstanding_amount != 0)
if self.payment_name:
conditions.append(doc.name.like(f"%{self.payment_name}%"))
@@ -219,7 +222,6 @@ class PaymentReconciliation(Document):
self.return_invoices = self.return_invoices_query.run(as_dict=True)
def get_dr_or_cr_notes(self):
self.build_qb_filter_conditions(get_return_invoices=True)
ple = qb.DocType("Payment Ledger Entry")
@@ -256,6 +258,7 @@ class PaymentReconciliation(Document):
"posting_date": inv.posting_date,
"currency": inv.currency,
"cost_center": inv.cost_center,
"remarks": inv.remarks,
}
)
)
@@ -298,6 +301,10 @@ class PaymentReconciliation(Document):
if self.invoice_limit:
non_reconciled_invoices = non_reconciled_invoices[: self.invoice_limit]
non_reconciled_invoices = sorted(
non_reconciled_invoices, key=lambda k: k["posting_date"] or getdate(nowdate())
)
self.add_invoice_entries(non_reconciled_invoices)
def add_invoice_entries(self, non_reconciled_invoices):
@@ -340,9 +347,7 @@ class PaymentReconciliation(Document):
payment_entry[0].get("reference_name")
)
new_difference_amount = self.get_difference_amount(
payment_entry[0], invoice[0], allocated_amount
)
new_difference_amount = self.get_difference_amount(payment_entry[0], invoice[0], allocated_amount)
return new_difference_amount
@frappe.whitelist()
@@ -460,9 +465,9 @@ class PaymentReconciliation(Document):
if running_doc:
frappe.throw(
_("A Reconciliation Job {0} is running for the same filters. Cannot reconcile now").format(
get_link_to_form("Auto Reconcile", running_doc)
)
_(
"A Reconciliation Job {0} is running for the same filters. Cannot reconcile now"
).format(get_link_to_form("Auto Reconcile", running_doc))
)
return
@@ -555,9 +560,7 @@ class PaymentReconciliation(Document):
invoice_exchange_map.update(purchase_invoice_map)
journals = [
d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Journal Entry"
]
journals = [d.get("invoice_number") for d in invoices if d.get("invoice_type") == "Journal Entry"]
journals.extend(
[d.get("reference_name") for d in payments if d.get("reference_type") == "Journal Entry"]
)
@@ -677,7 +680,7 @@ class PaymentReconciliation(Document):
def get_journal_filter_conditions(self):
conditions = []
je = qb.DocType("Journal Entry")
jea = qb.DocType("Journal Entry Account")
qb.DocType("Journal Entry Account")
conditions.append(je.company == self.company)
if self.from_payment_date:
@@ -797,7 +800,7 @@ def adjust_allocations_for_taxes(doc):
@frappe.whitelist()
def get_queries_for_dimension_filters(company: str = None):
def get_queries_for_dimension_filters(company: str | None = None):
dimensions_with_filters = []
for d in get_dimensions()[0]:
filters = {}

View File

@@ -1,7 +1,6 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
import frappe
from frappe import qb
@@ -127,11 +126,14 @@ class TestPaymentReconciliation(FrappeTestCase):
setattr(self, x.attribute, acc.name)
def create_sales_invoice(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
self, qty=1, rate=100, posting_date=None, do_not_save=False, do_not_submit=False
):
"""
Helper function to populate default values in sales invoice
"""
if posting_date is None:
posting_date = nowdate()
sinv = create_sales_invoice(
qty=qty,
rate=rate,
@@ -155,10 +157,13 @@ class TestPaymentReconciliation(FrappeTestCase):
)
return sinv
def create_payment_entry(self, amount=100, posting_date=nowdate(), customer=None):
def create_payment_entry(self, amount=100, posting_date=None, customer=None):
"""
Helper function to populate default values in payment entry
"""
if posting_date is None:
posting_date = nowdate()
payment = create_payment_entry(
company=self.company,
payment_type="Receive",
@@ -172,11 +177,14 @@ class TestPaymentReconciliation(FrappeTestCase):
return payment
def create_purchase_invoice(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
self, qty=1, rate=100, posting_date=None, do_not_save=False, do_not_submit=False
):
"""
Helper function to populate default values in sales invoice
"""
if posting_date is None:
posting_date = nowdate()
pinv = make_purchase_invoice(
qty=qty,
rate=rate,
@@ -201,11 +209,14 @@ class TestPaymentReconciliation(FrappeTestCase):
return pinv
def create_purchase_order(
self, qty=1, rate=100, posting_date=nowdate(), do_not_save=False, do_not_submit=False
self, qty=1, rate=100, posting_date=None, do_not_save=False, do_not_submit=False
):
"""
Helper function to populate default values in sales invoice
"""
if posting_date is None:
posting_date = nowdate()
pord = create_purchase_order(
qty=qty,
rate=rate,
@@ -250,9 +261,7 @@ class TestPaymentReconciliation(FrappeTestCase):
pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate()
return pr
def create_journal_entry(
self, acc1=None, acc2=None, amount=0, posting_date=None, cost_center=None
):
def create_journal_entry(self, acc1=None, acc2=None, amount=0, posting_date=None, cost_center=None):
je = frappe.new_doc("Journal Entry")
je.posting_date = posting_date or nowdate()
je.company = self.company
@@ -402,7 +411,7 @@ class TestPaymentReconciliation(FrappeTestCase):
rate = 100
invoices = []
payments = []
for i in range(5):
for _i in range(5):
invoices.append(self.create_sales_invoice(qty=1, rate=rate, posting_date=transaction_date))
pe = self.create_payment_entry(amount=rate, posting_date=transaction_date).save().submit()
payments.append(pe)
@@ -606,6 +615,42 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(len(pr.get("invoices")), 0)
self.assertEqual(len(pr.get("payments")), 0)
def test_negative_debit_or_credit_journal_against_invoice(self):
transaction_date = nowdate()
amount = 100
si = self.create_sales_invoice(qty=1, rate=amount, posting_date=transaction_date)
# credit debtors account to record a payment
je = self.create_journal_entry(self.bank, self.debit_to, amount, transaction_date)
je.accounts[1].party_type = "Customer"
je.accounts[1].party = self.customer
je.accounts[1].credit_in_account_currency = 0
je.accounts[1].debit_in_account_currency = -1 * amount
je.save()
je.submit()
pr = self.create_payment_reconciliation()
pr.get_unreconciled_entries()
invoices = [x.as_dict() for x in pr.get("invoices")]
payments = [x.as_dict() for x in pr.get("payments")]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
# Difference amount should not be calculated for base currency accounts
for row in pr.allocation:
self.assertEqual(flt(row.get("difference_amount")), 0.0)
pr.reconcile()
# assert outstanding
si.reload()
self.assertEqual(si.status, "Paid")
self.assertEqual(si.outstanding_amount, 0)
# check PR tool output
self.assertEqual(len(pr.get("invoices")), 0)
self.assertEqual(len(pr.get("payments")), 0)
def test_journal_against_journal(self):
transaction_date = nowdate()
sales = "Sales - _PR"
@@ -821,9 +866,7 @@ class TestPaymentReconciliation(FrappeTestCase):
cr_note.cancel()
pay = self.create_payment_entry(
amount=amount, posting_date=transaction_date, customer=self.customer3
)
pay = self.create_payment_entry(amount=amount, posting_date=transaction_date, customer=self.customer3)
pay.paid_from = self.debtors_eur
pay.paid_from_account_currency = "EUR"
pay.source_exchange_rate = exchange_rate
@@ -930,6 +973,100 @@ class TestPaymentReconciliation(FrappeTestCase):
frappe.db.get_value("Journal Entry", jea_parent.parent, "voucher_type"), "Exchange Gain Or Loss"
)
def test_difference_amount_via_negative_debit_or_credit_journal_entry(self):
# Make Sale Invoice
si = self.create_sales_invoice(
qty=1, rate=100, posting_date=nowdate(), do_not_save=True, do_not_submit=True
)
si.customer = self.customer4
si.currency = "EUR"
si.conversion_rate = 85
si.debit_to = self.debtors_eur
si.save().submit()
# Make payment using Journal Entry
je1 = self.create_journal_entry("HDFC - _PR", self.debtors_eur, 100, nowdate())
je1.multi_currency = 1
je1.accounts[0].exchange_rate = 1
je1.accounts[0].credit_in_account_currency = -8000
je1.accounts[0].credit = -8000
je1.accounts[0].debit_in_account_currency = 0
je1.accounts[0].debit = 0
je1.accounts[1].party_type = "Customer"
je1.accounts[1].party = self.customer4
je1.accounts[1].exchange_rate = 80
je1.accounts[1].credit_in_account_currency = 100
je1.accounts[1].credit = 8000
je1.accounts[1].debit_in_account_currency = 0
je1.accounts[1].debit = 0
je1.save()
je1.submit()
je2 = self.create_journal_entry("HDFC - _PR", self.debtors_eur, 200, nowdate())
je2.multi_currency = 1
je2.accounts[0].exchange_rate = 1
je2.accounts[0].credit_in_account_currency = -16000
je2.accounts[0].credit = -16000
je2.accounts[0].debit_in_account_currency = 0
je2.accounts[0].debit = 0
je2.accounts[1].party_type = "Customer"
je2.accounts[1].party = self.customer4
je2.accounts[1].exchange_rate = 80
je2.accounts[1].credit_in_account_currency = 200
je1.accounts[1].credit = 16000
je1.accounts[1].debit_in_account_currency = 0
je1.accounts[1].debit = 0
je2.save()
je2.submit()
pr = self.create_payment_reconciliation()
pr.party = self.customer4
pr.receivable_payable_account = self.debtors_eur
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 2)
# Test exact payment allocation
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[0].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
# Test partial payment allocation (with excess payment entry)
pr.set("allocation", [])
pr.get_unreconciled_entries()
invoices = [x.as_dict() for x in pr.invoices]
payments = [pr.payments[1].as_dict()]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
pr.allocation[0].difference_account = "Exchange Gain/Loss - _PR"
self.assertEqual(pr.allocation[0].allocated_amount, 100)
self.assertEqual(pr.allocation[0].difference_amount, -500)
# Check if difference journal entry gets generated for difference amount after reconciliation
pr.reconcile()
total_credit_amount = frappe.db.get_all(
"Journal Entry Account",
{"account": self.debtors_eur, "docstatus": 1, "reference_name": si.name},
"sum(credit) as amount",
group_by="reference_name",
)[0].amount
# total credit includes the exchange gain/loss amount
self.assertEqual(flt(total_credit_amount, 2), 8500)
jea_parent = frappe.db.get_all(
"Journal Entry Account",
filters={"account": self.debtors_eur, "docstatus": 1, "reference_name": si.name, "credit": 500},
fields=["parent"],
)[0]
self.assertEqual(
frappe.db.get_value("Journal Entry", jea_parent.parent, "voucher_type"), "Exchange Gain Or Loss"
)
def test_difference_amount_via_payment_entry(self):
# Make Sale Invoice
si = self.create_sales_invoice(
@@ -1025,9 +1162,7 @@ class TestPaymentReconciliation(FrappeTestCase):
rate = 100
# 'Main - PR' Cost Center
si1 = self.create_sales_invoice(
qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True
)
si1 = self.create_sales_invoice(qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True)
si1.cost_center = self.main_cc.name
si1.submit()
@@ -1043,9 +1178,7 @@ class TestPaymentReconciliation(FrappeTestCase):
je1 = je1.save().submit()
# 'Sub - PR' Cost Center
si2 = self.create_sales_invoice(
qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True
)
si2 = self.create_sales_invoice(qty=1, rate=rate, posting_date=transaction_date, do_not_submit=True)
si2.cost_center = self.sub_cc.name
si2.submit()
@@ -1332,6 +1465,46 @@ class TestPaymentReconciliation(FrappeTestCase):
# Should not raise frappe.exceptions.ValidationError: Payment Entry has been modified after you pulled it. Please pull it again.
pr.reconcile()
def test_cr_note_payment_limit_filter(self):
transaction_date = nowdate()
amount = 100
for _ in range(6):
self.create_sales_invoice(qty=1, rate=amount, posting_date=transaction_date)
cr_note = self.create_sales_invoice(
qty=-1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
)
cr_note.is_return = 1
cr_note = cr_note.save().submit()
pr = self.create_payment_reconciliation()
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 6)
self.assertEqual(len(pr.payments), 6)
invoices = [x.as_dict() for x in pr.get("invoices")]
payments = [x.as_dict() for x in pr.get("payments")]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
pr.reconcile()
pr.get_unreconciled_entries()
self.assertEqual(pr.get("invoices"), [])
self.assertEqual(pr.get("payments"), [])
self.create_sales_invoice(qty=1, rate=amount, posting_date=transaction_date)
cr_note = self.create_sales_invoice(
qty=-1, rate=amount, posting_date=transaction_date, do_not_save=True, do_not_submit=True
)
cr_note.is_return = 1
cr_note = cr_note.save().submit()
# Limit should not affect in fetching the unallocated cr_note
pr.invoice_limit = 5
pr.payment_limit = 5
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
def make_customer(customer_name, currency=None):
if not frappe.db.exists("Customer", customer_name):

View File

@@ -14,7 +14,7 @@
"amount",
"difference_amount",
"sec_break1",
"remark",
"remarks",
"currency",
"exchange_rate",
"cost_center"
@@ -74,12 +74,6 @@
"fieldname": "sec_break1",
"fieldtype": "Section Break"
},
{
"fieldname": "remark",
"fieldtype": "Small Text",
"label": "Remark",
"read_only": 1
},
{
"fieldname": "currency",
"fieldtype": "Link",
@@ -105,12 +99,18 @@
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "remarks",
"fieldtype": "Small Text",
"label": "Remarks",
"read_only": 1
}
],
"is_virtual": 1,
"istable": 1,
"links": [],
"modified": "2023-11-17 17:33:34.818530",
"modified": "2024-10-29 16:24:43.021230",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",

View File

@@ -28,7 +28,7 @@ frappe.ui.form.on("Payment Request", "refresh", function (frm) {
if (
frm.doc.payment_request_type == "Inward" &&
frm.doc.payment_channel !== "Phone" &&
!in_list(["Initiated", "Paid"], frm.doc.status) &&
!["Initiated", "Paid"].includes(frm.doc.status) &&
!frm.doc.__islocal &&
frm.doc.docstatus == 1
) {
@@ -48,8 +48,8 @@ frappe.ui.form.on("Payment Request", "refresh", function (frm) {
}
if (
(!frm.doc.payment_gateway_account || frm.doc.payment_request_type == "Outward") &&
frm.doc.status == "Initiated"
frm.doc.payment_request_type == "Outward" &&
["Initiated", "Partially Paid"].includes(frm.doc.status)
) {
frm.add_custom_button(__("Create Payment Entry"), function () {
frappe.call({

View File

@@ -18,9 +18,11 @@
"reference_name",
"transaction_details",
"grand_total",
"currency",
"is_a_subscription",
"column_break_18",
"currency",
"outstanding_amount",
"party_account_currency",
"subscription_section",
"subscription_plans",
"bank_account_details",
@@ -68,6 +70,7 @@
{
"fieldname": "transaction_date",
"fieldtype": "Date",
"in_preview": 1,
"label": "Transaction Date"
},
{
@@ -132,7 +135,8 @@
"no_copy": 1,
"options": "reference_doctype",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "transaction_details",
@@ -140,11 +144,14 @@
"label": "Transaction Details"
},
{
"description": "Amount in customer's currency",
"description": "Amount in transaction currency",
"fieldname": "grand_total",
"fieldtype": "Currency",
"in_preview": 1,
"label": "Amount",
"options": "currency"
"non_negative": 1,
"options": "currency",
"reqd": 1
},
{
"default": "0",
@@ -388,13 +395,31 @@
"fieldtype": "Link",
"label": "Project",
"options": "Project"
},
{
"depends_on": "eval: doc.docstatus === 1",
"description": "Amount in party's bank account currency",
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"in_preview": 1,
"label": "Outstanding Amount",
"non_negative": 1,
"options": "party_account_currency",
"read_only": 1
},
{
"fieldname": "party_account_currency",
"fieldtype": "Link",
"label": "Party Account Currency",
"options": "Currency",
"read_only": 1
}
],
"in_create": 1,
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2022-12-21 16:56:40.115737",
"modified": "2024-09-16 17:50:54.440090",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
@@ -429,7 +454,8 @@
"write": 1
}
],
"show_preview_popup": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -7,9 +7,11 @@ import json
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.query_builder.functions import Sum
from frappe.utils import flt, get_url, nowdate
from frappe.utils.background_jobs import enqueue
from erpnext import get_company_currency
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
)
@@ -19,7 +21,7 @@ from erpnext.accounts.doctype.payment_entry.payment_entry import (
)
from erpnext.accounts.doctype.subscription_plan.subscription_plan import get_plan_rate
from erpnext.accounts.party import get_party_account, get_party_bank_account
from erpnext.accounts.utils import get_account_currency
from erpnext.accounts.utils import get_account_currency, get_currency_precision
from erpnext.erpnext_integrations.stripe_integration import create_stripe_subscription
from erpnext.utilities import payment_app_import_guard
@@ -37,7 +39,7 @@ class PaymentRequest(Document):
self.status = "Draft"
self.validate_reference_document()
self.validate_payment_request_amount()
self.validate_currency()
# self.validate_currency()
self.validate_subscription_details()
def validate_reference_document(self):
@@ -45,12 +47,18 @@ class PaymentRequest(Document):
frappe.throw(_("To create a Payment Request reference document is required"))
def validate_payment_request_amount(self):
if self.grand_total == 0:
frappe.throw(
_("{0} cannot be zero").format(self.get_label_from_fieldname("grand_total")),
title=_("Invalid Amount"),
)
existing_payment_request_amount = flt(
get_existing_payment_request_amount(self.reference_doctype, self.reference_name)
)
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if not hasattr(ref_doc, "order_type") or getattr(ref_doc, "order_type") != "Shopping Cart":
if not hasattr(ref_doc, "order_type") or ref_doc.order_type != "Shopping Cart":
ref_amount = get_amount(ref_doc, self.payment_account)
if existing_payment_request_amount + flt(self.grand_total) > ref_amount:
@@ -92,6 +100,29 @@ class PaymentRequest(Document):
).format(self.grand_total, amount)
)
def before_submit(self):
company = frappe.get_value(self.reference_doctype, self.reference_name, "company")
if (
self.currency != self.party_account_currency
and self.party_account_currency == get_company_currency(company)
):
# set outstanding amount in party account currency
invoice = frappe.get_value(
self.reference_doctype,
self.reference_name,
["rounded_total", "grand_total", "base_rounded_total", "base_grand_total"],
as_dict=1,
)
grand_total = invoice.get("rounded_total") or invoice.get("grand_total")
base_grand_total = invoice.get("base_rounded_total") or invoice.get("base_grand_total")
self.outstanding_amount = flt(
self.grand_total / grand_total * base_grand_total,
self.precision("outstanding_amount"),
)
else:
self.outstanding_amount = self.grand_total
def on_submit(self):
if self.payment_request_type == "Outward":
self.db_set("status", "Initiated")
@@ -103,7 +134,7 @@ class PaymentRequest(Document):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if (
hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"
hasattr(ref_doc, "order_type") and ref_doc.order_type == "Shopping Cart"
) or self.flags.mute_email:
send_mail = False
@@ -155,7 +186,7 @@ class PaymentRequest(Document):
def make_invoice(self):
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
if hasattr(ref_doc, "order_type") and ref_doc.order_type == "Shopping Cart":
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
@@ -207,12 +238,12 @@ class PaymentRequest(Document):
return controller.get_payment_url(
**{
"amount": flt(self.grand_total, self.precision("grand_total")),
"title": data.company.encode("utf-8"),
"description": self.subject.encode("utf-8"),
"title": data.company,
"description": self.subject,
"reference_doctype": "Payment Request",
"reference_docname": self.name,
"payer_email": self.email_to or frappe.session.user,
"payer_name": frappe.safe_encode(data.customer_name),
"payer_name": data.customer_name,
"order_id": self.name,
"currency": self.currency,
}
@@ -220,7 +251,7 @@ class PaymentRequest(Document):
def set_as_paid(self):
if self.payment_channel == "Phone":
self.db_set("status", "Paid")
self.db_set({"status": "Paid", "outstanding_amount": 0})
else:
payment_entry = self.create_payment_entry()
@@ -241,37 +272,42 @@ class PaymentRequest(Document):
else:
party_account = get_party_account("Customer", ref_doc.get("customer"), ref_doc.company)
party_account_currency = ref_doc.get("party_account_currency") or get_account_currency(
party_account
party_account_currency = (
self.get("party_account_currency")
or ref_doc.get("party_account_currency")
or get_account_currency(party_account)
)
bank_amount = self.grand_total
if (
party_account_currency == ref_doc.company_currency and party_account_currency != self.currency
):
party_amount = ref_doc.get("base_rounded_total") or ref_doc.get("base_grand_total")
else:
party_amount = self.grand_total
party_amount = bank_amount = self.outstanding_amount
if party_account_currency == ref_doc.company_currency and party_account_currency != self.currency:
exchange_rate = ref_doc.get("conversion_rate")
bank_amount = flt(self.outstanding_amount / exchange_rate, self.precision("grand_total"))
# outstanding amount is already in Part's account currency
payment_entry = get_payment_entry(
self.reference_doctype,
self.reference_name,
party_amount=party_amount,
bank_account=self.payment_account,
bank_amount=bank_amount,
created_from_payment_request=True,
)
payment_entry.update(
{
"mode_of_payment": self.mode_of_payment,
"reference_no": self.name,
"reference_no": self.name, # to prevent validation error
"reference_date": nowdate(),
"remarks": "Payment Entry against {0} {1} via Payment Request {2}".format(
"remarks": "Payment Entry against {} {} via Payment Request {}".format(
self.reference_doctype, self.reference_name, self.name
),
}
)
# Allocate payment_request for each reference in payment_entry (Payment Term can splits the row)
self._allocate_payment_request_to_pe_references(references=payment_entry.references)
# Update dimensions
payment_entry.update(
{
@@ -280,21 +316,20 @@ class PaymentRequest(Document):
}
)
# Update 'Paid Amount' on Forex transactions
if self.currency != ref_doc.company_currency:
if (
self.payment_request_type == "Outward"
and payment_entry.paid_from_account_currency == ref_doc.company_currency
and payment_entry.paid_from_account_currency != payment_entry.paid_to_account_currency
):
payment_entry.paid_amount = payment_entry.base_paid_amount = (
payment_entry.target_exchange_rate * payment_entry.received_amount
)
for dimension in get_accounting_dimensions():
payment_entry.update({dimension: self.get(dimension)})
if payment_entry.difference_amount:
company_details = get_company_defaults(ref_doc.company)
payment_entry.append(
"deductions",
{
"account": company_details.exchange_gain_loss_account,
"cost_center": company_details.cost_center,
"amount": payment_entry.difference_amount,
},
)
if submit:
payment_entry.insert(ignore_permissions=True)
payment_entry.submit()
@@ -380,14 +415,13 @@ class PaymentRequest(Document):
and hasattr(frappe.local, "session")
and frappe.local.session.user != "Guest"
) and self.payment_channel != "Phone":
success_url = shopping_cart_settings.payment_success_url
if success_url:
redirect_to = ({"Orders": "/orders", "Invoices": "/invoices", "My Account": "/me"}).get(
success_url, "/me"
)
else:
redirect_to = get_url("/orders/{0}".format(self.reference_name))
redirect_to = get_url(f"/orders/{self.reference_name}")
return redirect_to
@@ -395,6 +429,62 @@ class PaymentRequest(Document):
if payment_provider == "stripe":
return create_stripe_subscription(gateway_controller, data)
def _allocate_payment_request_to_pe_references(self, references):
"""
Allocate the Payment Request to the Payment Entry references based on\n
- Allocated Amount.
- Outstanding Amount of Payment Request.\n
Payment Request is doc itself and references are the rows of Payment Entry.
"""
if len(references) == 1:
references[0].payment_request = self.name
return
precision = references[0].precision("allocated_amount")
outstanding_amount = self.outstanding_amount
# to manage rows
row_number = 1
MOVE_TO_NEXT_ROW = 1
TO_SKIP_NEW_ROW = 2
NEW_ROW_ADDED = False
while row_number <= len(references):
row = references[row_number - 1]
# update the idx to maintain the order
row.idx = row_number
if outstanding_amount == 0:
if not NEW_ROW_ADDED:
break
row_number += MOVE_TO_NEXT_ROW
continue
# allocate the payment request to the row
row.payment_request = self.name
if row.allocated_amount <= outstanding_amount:
outstanding_amount = flt(outstanding_amount - row.allocated_amount, precision)
row_number += MOVE_TO_NEXT_ROW
else:
remaining_allocated_amount = flt(row.allocated_amount - outstanding_amount, precision)
row.allocated_amount = outstanding_amount
outstanding_amount = 0
# create a new row without PR for remaining unallocated amount
new_row = frappe.copy_doc(row)
references.insert(row_number, new_row)
# update new row
new_row.idx = row_number + 1
new_row.payment_request = None
new_row.allocated_amount = remaining_allocated_amount
NEW_ROW_ADDED = True
row_number += TO_SKIP_NEW_ROW
@frappe.whitelist(allow_guest=True)
def make_payment_request(**args):
@@ -413,15 +503,11 @@ def make_payment_request(**args):
frappe.db.set_value(
"Sales Order", args.dn, "loyalty_points", int(args.loyalty_points), update_modified=False
)
frappe.db.set_value(
"Sales Order", args.dn, "loyalty_amount", loyalty_amount, update_modified=False
)
frappe.db.set_value("Sales Order", args.dn, "loyalty_amount", loyalty_amount, update_modified=False)
grand_total = grand_total - loyalty_amount
bank_account = (
get_party_bank_account(args.get("party_type"), args.get("party"))
if args.get("party_type")
else ""
get_party_bank_account(args.get("party_type"), args.get("party")) if args.get("party_type") else ""
)
draft_payment_request = frappe.db.get_value(
@@ -429,11 +515,15 @@ def make_payment_request(**args):
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": 0},
)
existing_payment_request_amount = get_existing_payment_request_amount(args.dt, args.dn)
# fetches existing payment request `grand_total` amount
existing_payment_request_amount = get_existing_payment_request_amount(ref_doc.doctype, ref_doc.name)
if existing_payment_request_amount:
grand_total -= existing_payment_request_amount
if not grand_total:
frappe.throw(_("Payment Request is already created"))
if draft_payment_request:
frappe.db.set_value(
"Payment Request", draft_payment_request, "grand_total", grand_total, update_modified=False
@@ -441,6 +531,19 @@ def make_payment_request(**args):
pr = frappe.get_doc("Payment Request", draft_payment_request)
else:
pr = frappe.new_doc("Payment Request")
if not args.get("payment_request_type"):
args["payment_request_type"] = (
"Outward" if args.get("dt") in ["Purchase Order", "Purchase Invoice"] else "Inward"
)
party_type = args.get("party_type") or "Customer"
party_account_currency = ref_doc.get("party_account_currency")
if not party_account_currency:
party_account = get_party_account(party_type, ref_doc.get(party_type.lower()), ref_doc.company)
party_account_currency = get_account_currency(party_account)
pr.update(
{
"payment_gateway_account": gateway_account.get("name"),
@@ -449,6 +552,7 @@ def make_payment_request(**args):
"payment_channel": gateway_account.get("payment_channel"),
"payment_request_type": args.get("payment_request_type"),
"currency": ref_doc.currency,
"party_account_currency": party_account_currency,
"grand_total": grand_total,
"mode_of_payment": args.mode_of_payment,
"email_to": args.recipient_id or ref_doc.owner,
@@ -456,7 +560,7 @@ def make_payment_request(**args):
"message": gateway_account.get("message") or get_dummy_message(ref_doc),
"reference_doctype": args.dt,
"reference_name": args.dn,
"party_type": args.get("party_type") or "Customer",
"party_type": party_type,
"party": args.get("party") or ref_doc.get("customer"),
"bank_account": bank_account,
}
@@ -499,9 +603,11 @@ def get_amount(ref_doc, payment_account=None):
elif dt in ["Sales Invoice", "Purchase Invoice"]:
if not ref_doc.get("is_pos"):
if ref_doc.party_account_currency == ref_doc.currency:
grand_total = flt(ref_doc.outstanding_amount)
grand_total = flt(ref_doc.rounded_total or ref_doc.grand_total)
else:
grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate
grand_total = flt(
flt(ref_doc.base_rounded_total or ref_doc.base_grand_total) / ref_doc.conversion_rate
)
elif dt == "Sales Invoice":
for pay in ref_doc.payments:
if pay.type == "Phone" and pay.account == payment_account:
@@ -516,31 +622,27 @@ def get_amount(ref_doc, payment_account=None):
grand_total = ref_doc.outstanding_amount
if grand_total > 0:
return grand_total
return flt(grand_total, get_currency_precision())
else:
frappe.throw(_("Payment Entry is already created"))
def get_existing_payment_request_amount(ref_dt, ref_dn):
"""
Get the existing payment request which are unpaid or partially paid for payment channel other than Phone
and get the summation of existing paid payment request for Phone payment channel.
Return the total amount of Payment Requests against a reference document.
"""
existing_payment_request_amount = frappe.db.sql(
"""
select sum(grand_total)
from `tabPayment Request`
where
reference_doctype = %s
and reference_name = %s
and docstatus = 1
and (status != 'Paid'
or (payment_channel = 'Phone'
and status = 'Paid'))
""",
(ref_dt, ref_dn),
PR = frappe.qb.DocType("Payment Request")
response = (
frappe.qb.from_(PR)
.select(Sum(PR.grand_total))
.where(PR.reference_doctype == ref_dt)
.where(PR.reference_name == ref_dn)
.where(PR.docstatus == 1)
.run()
)
return flt(existing_payment_request_amount[0][0]) if existing_payment_request_amount else 0
return response[0][0] if response[0] else 0
def get_gateway_details(args): # nosemgrep
@@ -588,37 +690,66 @@ def make_payment_entry(docname):
return doc.create_payment_entry(submit=False).as_dict()
def update_payment_req_status(doc, method):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_reference_details
def update_payment_requests_as_per_pe_references(references=None, cancel=False):
"""
Update Payment Request's `Status` and `Outstanding Amount` based on Payment Entry Reference's `Allocated Amount`.
"""
if not references:
return
for ref in doc.references:
payment_request_name = frappe.db.get_value(
"Payment Request",
{
"reference_doctype": ref.reference_doctype,
"reference_name": ref.reference_name,
"docstatus": 1,
},
precision = references[0].precision("allocated_amount")
referenced_payment_requests = frappe.get_all(
"Payment Request",
filters={"name": ["in", {row.payment_request for row in references if row.payment_request}]},
fields=[
"name",
"grand_total",
"outstanding_amount",
"payment_request_type",
],
)
referenced_payment_requests = {pr.name: pr for pr in referenced_payment_requests}
for ref in references:
if not ref.payment_request:
continue
payment_request = referenced_payment_requests[ref.payment_request]
pr_outstanding = payment_request["outstanding_amount"]
# update outstanding amount
new_outstanding_amount = flt(
pr_outstanding + ref.allocated_amount if cancel else pr_outstanding - ref.allocated_amount,
precision,
)
if payment_request_name:
ref_details = get_reference_details(
ref.reference_doctype, ref.reference_name, doc.party_account_currency
# to handle same payment request for the multiple allocations
payment_request["outstanding_amount"] = new_outstanding_amount
if not cancel and new_outstanding_amount < 0:
frappe.throw(
msg=_(
"The allocated amount is greater than the outstanding amount of Payment Request {0}"
).format(ref.payment_request),
title=_("Invalid Allocated Amount"),
)
pay_req_doc = frappe.get_doc("Payment Request", payment_request_name)
status = pay_req_doc.status
if status != "Paid" and not ref_details.outstanding_amount:
status = "Paid"
elif status != "Partially Paid" and ref_details.outstanding_amount != ref_details.total_amount:
status = "Partially Paid"
elif ref_details.outstanding_amount == ref_details.total_amount:
if pay_req_doc.payment_request_type == "Outward":
status = "Initiated"
elif pay_req_doc.payment_request_type == "Inward":
status = "Requested"
# update status
if new_outstanding_amount == payment_request["grand_total"]:
status = "Initiated" if payment_request["payment_request_type"] == "Outward" else "Requested"
elif new_outstanding_amount == 0:
status = "Paid"
elif new_outstanding_amount > 0:
status = "Partially Paid"
pay_req_doc.db_set("status", status)
# update database
frappe.db.set_value(
"Payment Request",
ref.payment_request,
{"outstanding_amount": new_outstanding_amount, "status": status},
)
def get_dummy_message(doc):
@@ -702,3 +833,31 @@ def validate_payment(doc, method=None):
doc.reference_docname
)
)
@frappe.whitelist()
def get_open_payment_requests_query(doctype, txt, searchfield, start, page_len, filters):
# permission checks in `get_list()`
filters = frappe._dict(filters)
if not filters.reference_doctype or not filters.reference_name:
return []
if txt:
filters.name = ["like", f"%{txt}%"]
open_payment_requests = frappe.get_list(
"Payment Request",
filters=filters,
fields=["name", "grand_total", "outstanding_amount"],
order_by="transaction_date ASC,creation ASC",
)
return [
(
pr.name,
_("<strong>Grand Total:</strong> {0}").format(pr.grand_total),
_("<strong>Outstanding Amount:</strong> {0}").format(pr.outstanding_amount),
)
for pr in open_payment_requests
]

View File

@@ -0,0 +1,14 @@
from frappe import _
def get_data():
return {
"fieldname": "payment_request",
"internal_links": {
"Payment Entry": ["references", "payment_request"],
"Payment Order": ["references", "payment_order"],
},
"transactions": [
{"label": _("Payment"), "items": ["Payment Entry", "Payment Order"]},
],
}

View File

@@ -1,19 +1,18 @@
const INDICATORS = {
"Partially Paid": "orange",
Cancelled: "red",
Draft: "gray",
Failed: "red",
Initiated: "green",
Paid: "blue",
Requested: "green",
};
frappe.listview_settings["Payment Request"] = {
add_fields: ["status"],
get_indicator: function (doc) {
if (doc.status == "Draft") {
return [__("Draft"), "gray", "status,=,Draft"];
}
if (doc.status == "Requested") {
return [__("Requested"), "green", "status,=,Requested"];
} else if (doc.status == "Initiated") {
return [__("Initiated"), "green", "status,=,Initiated"];
} else if (doc.status == "Partially Paid") {
return [__("Partially Paid"), "orange", "status,=,Partially Paid"];
} else if (doc.status == "Paid") {
return [__("Paid"), "blue", "status,=,Paid"];
} else if (doc.status == "Cancelled") {
return [__("Cancelled"), "red", "status,=,Cancelled"];
}
if (!doc.status || !INDICATORS[doc.status]) return;
return [__(doc.status), INDICATORS[doc.status], `status,=,${doc.status}`];
},
};

View File

@@ -1,18 +1,23 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import re
import unittest
import frappe
from frappe.tests.utils import FrappeTestCase, change_settings
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_terms_template
from erpnext.accounts.doctype.payment_request.payment_request import make_payment_request
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.setup.utils import get_exchange_rate
test_dependencies = ["Currency Exchange", "Journal Entry", "Contact", "Address"]
payment_gateway = {"doctype": "Payment Gateway", "gateway": "_Test Gateway"}
payment_method = [
@@ -32,7 +37,7 @@ payment_method = [
]
class TestPaymentRequest(unittest.TestCase):
class TestPaymentRequest(FrappeTestCase):
def setUp(self):
if not frappe.db.get_value("Payment Gateway", payment_gateway["gateway"], "name"):
frappe.get_doc(payment_gateway).insert(ignore_permissions=True)
@@ -86,6 +91,8 @@ class TestPaymentRequest(unittest.TestCase):
pr = make_payment_request(
dt="Purchase Invoice",
dn=si_usd.name,
party_type="Supplier",
party="_Test Supplier USD",
recipient_id="user@example.com",
mute_email=1,
payment_gateway_account="_Test Gateway - USD",
@@ -93,11 +100,56 @@ class TestPaymentRequest(unittest.TestCase):
return_doc=1,
)
pe = pr.create_payment_entry()
pr.create_payment_entry()
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
def test_multiple_payment_entry_against_purchase_invoice(self):
purchase_invoice = make_purchase_invoice(
customer="_Test Supplier USD",
debit_to="_Test Payable USD - _TC",
currency="USD",
conversion_rate=50,
)
pr = make_payment_request(
dt="Purchase Invoice",
party_type="Supplier",
party="_Test Supplier USD",
dn=purchase_invoice.name,
recipient_id="user@example.com",
mute_email=1,
payment_gateway_account="_Test Gateway - USD",
return_doc=1,
)
pr.grand_total = pr.grand_total / 2
pr.submit()
pr.create_payment_entry()
purchase_invoice.load_from_db()
self.assertEqual(purchase_invoice.status, "Partly Paid")
pr = make_payment_request(
dt="Purchase Invoice",
party_type="Supplier",
party="_Test Supplier USD",
dn=purchase_invoice.name,
recipient_id="user@example.com",
mute_email=1,
payment_gateway_account="_Test Gateway - USD",
return_doc=1,
)
pr.save()
pr.submit()
pr.create_payment_entry()
purchase_invoice.load_from_db()
self.assertEqual(purchase_invoice.status, "Paid")
def test_payment_entry(self):
frappe.db.set_value(
"Company", "_Test Company", "exchange_gain_loss_account", "_Test Exchange Gain/Loss - _TC"
@@ -158,7 +210,7 @@ class TestPaymentRequest(unittest.TestCase):
self.assertTrue(gl_entries)
for i, gle in enumerate(gl_entries):
for _i, gle in enumerate(gl_entries):
self.assertEqual(expected_gle[gle.account][0], gle.account)
self.assertEqual(expected_gle[gle.account][1], gle.debit)
self.assertEqual(expected_gle[gle.account][2], gle.credit)
@@ -213,3 +265,262 @@ class TestPaymentRequest(unittest.TestCase):
# Try to make Payment Request more than SO amount, should give validation
pr2.grand_total = 900
self.assertRaises(frappe.ValidationError, pr2.save)
def test_conversion_on_foreign_currency_accounts(self):
po_doc = create_purchase_order(supplier="_Test Supplier USD", currency="USD", do_not_submit=1)
po_doc.conversion_rate = 80
po_doc.items[0].qty = 1
po_doc.items[0].rate = 10
po_doc.save().submit()
pr = make_payment_request(dt=po_doc.doctype, dn=po_doc.name, recipient_id="nabin@erpnext.com")
pr = frappe.get_doc(pr).save().submit()
pe = pr.create_payment_entry()
self.assertEqual(pe.base_paid_amount, 800)
self.assertEqual(pe.paid_amount, 800)
self.assertEqual(pe.base_received_amount, 800)
self.assertEqual(pe.received_amount, 10)
def test_multiple_payment_if_partially_paid_for_same_currency(self):
so = make_sales_order(currency="INR", qty=1, rate=1000)
pr = make_payment_request(
dt="Sales Order",
dn=so.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
self.assertEqual(pr.grand_total, 1000)
self.assertEqual(pr.outstanding_amount, pr.grand_total)
self.assertEqual(pr.party_account_currency, pr.currency) # INR
so.load_from_db()
# to make partial payment
pe = pr.create_payment_entry(submit=False)
pe.paid_amount = 200
pe.references[0].allocated_amount = 200
pe.submit()
self.assertEqual(pe.references[0].payment_request, pr.name)
so.load_from_db()
pr.load_from_db()
self.assertEqual(pr.status, "Partially Paid")
self.assertEqual(pr.outstanding_amount, 800)
self.assertEqual(pr.grand_total, 1000)
# complete payment
pe = pr.create_payment_entry()
self.assertEqual(pe.paid_amount, 800) # paid amount set from pr's outstanding amount
self.assertEqual(pe.references[0].allocated_amount, 800)
self.assertEqual(pe.references[0].outstanding_amount, 800) # for Orders it is not zero
self.assertEqual(pe.references[0].payment_request, pr.name)
so.load_from_db()
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
self.assertEqual(pr.outstanding_amount, 0)
self.assertEqual(pr.grand_total, 1000)
# creating a more payment Request must not allowed
self.assertRaisesRegex(
frappe.exceptions.ValidationError,
re.compile(r"Payment Request is already created"),
make_payment_request,
dt="Sales Order",
dn=so.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
@change_settings("Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1})
def test_multiple_payment_if_partially_paid_for_multi_currency(self):
pi = make_purchase_invoice(currency="USD", conversion_rate=50, qty=1, rate=100, do_not_save=1)
pi.credit_to = "Creditors - _TC"
pi.submit()
pr = make_payment_request(
dt="Purchase Invoice",
dn=pi.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
# 100 USD -> 5000 INR
self.assertEqual(pr.grand_total, 100)
self.assertEqual(pr.outstanding_amount, 5000)
self.assertEqual(pr.currency, "USD")
self.assertEqual(pr.party_account_currency, "INR")
self.assertEqual(pr.status, "Initiated")
# to make partial payment
pe = pr.create_payment_entry(submit=False)
pe.paid_amount = 2000
pe.references[0].allocated_amount = 2000
pe.submit()
self.assertEqual(pe.references[0].payment_request, pr.name)
pr.load_from_db()
self.assertEqual(pr.status, "Partially Paid")
self.assertEqual(pr.outstanding_amount, 3000)
self.assertEqual(pr.grand_total, 100)
# complete payment
pe = pr.create_payment_entry()
self.assertEqual(pe.paid_amount, 3000) # paid amount set from pr's outstanding amount
self.assertEqual(pe.references[0].allocated_amount, 3000)
self.assertEqual(pe.references[0].outstanding_amount, 0) # for Invoices it will zero
self.assertEqual(pe.references[0].payment_request, pr.name)
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
self.assertEqual(pr.outstanding_amount, 0)
self.assertEqual(pr.grand_total, 100)
# creating a more payment Request must not allowed
self.assertRaisesRegex(
frappe.exceptions.ValidationError,
re.compile(r"Payment Request is already created"),
make_payment_request,
dt="Purchase Invoice",
dn=pi.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
def test_single_payment_with_payment_term_for_same_currency(self):
create_payment_terms_template()
po = create_purchase_order(do_not_save=1, currency="INR", qty=1, rate=20000)
po.payment_terms_template = "Test Receivable Template" # 84.746 and 15.254
po.save()
po.submit()
pr = make_payment_request(
dt="Purchase Order",
dn=po.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
self.assertEqual(pr.grand_total, 20000)
self.assertEqual(pr.outstanding_amount, pr.grand_total)
self.assertEqual(pr.party_account_currency, pr.currency) # INR
self.assertEqual(pr.status, "Initiated")
po.load_from_db()
pe = pr.create_payment_entry()
self.assertEqual(len(pe.references), 2)
self.assertEqual(pe.paid_amount, 20000)
# check 1st payment term
self.assertEqual(pe.references[0].allocated_amount, 16949.2)
self.assertEqual(pe.references[0].payment_request, pr.name)
# check 2nd payment term
self.assertEqual(pe.references[1].allocated_amount, 3050.8)
self.assertEqual(pe.references[1].payment_request, pr.name)
po.load_from_db()
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
self.assertEqual(pr.outstanding_amount, 0)
self.assertEqual(pr.grand_total, 20000)
@change_settings("Accounts Settings", {"allow_multi_currency_invoices_against_single_party_account": 1})
def test_single_payment_with_payment_term_for_multi_currency(self):
create_payment_terms_template()
si = create_sales_invoice(
do_not_save=1, currency="USD", debit_to="Debtors - _TC", qty=1, rate=200, conversion_rate=50
)
si.payment_terms_template = "Test Receivable Template" # 84.746 and 15.254
si.save()
si.submit()
pr = make_payment_request(
dt="Sales Invoice",
dn=si.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
# 200 USD -> 10000 INR
self.assertEqual(pr.grand_total, 200)
self.assertEqual(pr.outstanding_amount, 10000)
self.assertEqual(pr.currency, "USD")
self.assertEqual(pr.party_account_currency, "INR")
pe = pr.create_payment_entry()
self.assertEqual(len(pe.references), 2)
self.assertEqual(pe.paid_amount, 10000)
# check 1st payment term
# convert it via dollar and conversion_rate
self.assertEqual(pe.references[0].allocated_amount, 8474.5) # multi currency conversion
self.assertEqual(pe.references[0].payment_request, pr.name)
# check 2nd payment term
self.assertEqual(pe.references[1].allocated_amount, 1525.5) # multi currency conversion
self.assertEqual(pe.references[1].payment_request, pr.name)
pr.load_from_db()
self.assertEqual(pr.status, "Paid")
self.assertEqual(pr.outstanding_amount, 0)
self.assertEqual(pr.grand_total, 200)
def test_payment_cancel_process(self):
so = make_sales_order(currency="INR", qty=1, rate=1000)
pr = make_payment_request(
dt="Sales Order",
dn=so.name,
mute_email=1,
submit_doc=1,
return_doc=1,
)
self.assertEqual(pr.grand_total, 1000)
self.assertEqual(pr.outstanding_amount, pr.grand_total)
so.load_from_db()
pe = pr.create_payment_entry(submit=False)
pe.paid_amount = 800
pe.references[0].allocated_amount = 800
pe.submit()
self.assertEqual(pe.references[0].payment_request, pr.name)
so.load_from_db()
pr.load_from_db()
self.assertEqual(pr.status, "Partially Paid")
self.assertEqual(pr.outstanding_amount, 200)
self.assertEqual(pr.grand_total, 1000)
# cancelling PE
pe.cancel()
pr.load_from_db()
self.assertEqual(pr.status, "Requested")
self.assertEqual(pr.outstanding_amount, 1000)
self.assertEqual(pr.grand_total, 1000)
so.load_from_db()

View File

@@ -19,9 +19,7 @@ class PaymentTermsTemplate(Document):
total_portion += flt(term.get("invoice_portion", 0))
if flt(total_portion, 2) != 100.00:
frappe.msgprint(
_("Combined invoice portion must equal 100%"), raise_exception=1, indicator="red"
)
frappe.msgprint(_("Combined invoice portion must equal 100%"), raise_exception=1, indicator="red")
def validate_terms(self):
terms = []

View File

@@ -40,19 +40,18 @@ class PeriodClosingVoucher(AccountsController):
)
if gle_count > 5000:
frappe.enqueue(
make_reverse_gl_entries,
process_cancellation,
voucher_type="Period Closing Voucher",
voucher_no=self.name,
queue="long",
enqueue_after_commit=True,
)
frappe.msgprint(
_("The GL Entries will be cancelled in the background, it can take a few minutes."), alert=True
_("The GL Entries will be cancelled in the background, it can take a few minutes."),
alert=True,
)
else:
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
self.delete_closing_entries()
process_cancellation(voucher_type="Period Closing Voucher", voucher_no=self.name)
def validate_future_closing_vouchers(self):
if frappe.db.exists(
@@ -65,12 +64,6 @@ class PeriodClosingVoucher(AccountsController):
)
)
def delete_closing_entries(self):
closing_balance = frappe.qb.DocType("Account Closing Balance")
frappe.qb.from_(closing_balance).delete().where(
closing_balance.period_closing_voucher == self.name
).run()
def validate_account_head(self):
closing_account_type = frappe.get_cached_value("Account", self.closing_account_head, "root_type")
@@ -89,9 +82,7 @@ class PeriodClosingVoucher(AccountsController):
self.posting_date, self.fiscal_year, self.company, label=_("Posting Date"), doc=self
)
self.year_start_date = get_fiscal_year(
self.posting_date, self.fiscal_year, company=self.company
)[1]
self.year_start_date = get_fiscal_year(self.posting_date, self.fiscal_year, company=self.company)[1]
self.check_if_previous_year_closed()
@@ -137,14 +128,7 @@ class PeriodClosingVoucher(AccountsController):
closing_entries = self.get_grouped_gl_entries(get_opening_entries=get_opening_entries)
if len(gl_entries + closing_entries) > 3000:
frappe.enqueue(
process_gl_entries,
gl_entries=gl_entries,
voucher_name=self.name,
timeout=3000,
)
frappe.enqueue(
process_closing_entries,
process_gl_and_closing_entries,
gl_entries=gl_entries,
closing_entries=closing_entries,
voucher_name=self.name,
@@ -158,8 +142,9 @@ class PeriodClosingVoucher(AccountsController):
alert=True,
)
else:
process_gl_entries(gl_entries, self.name)
process_closing_entries(gl_entries, closing_entries, self.name, self.company, self.posting_date)
process_gl_and_closing_entries(
gl_entries, closing_entries, self.name, self.company, self.posting_date
)
def get_grouped_gl_entries(self, get_opening_entries=False):
closing_entries = []
@@ -205,7 +190,9 @@ class PeriodClosingVoucher(AccountsController):
"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,
"credit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) > 0
else 0,
"is_period_closing_voucher_entry": 1,
},
item=acc,
@@ -229,7 +216,9 @@ class PeriodClosingVoucher(AccountsController):
"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,
"credit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) < 0
else 0,
"is_period_closing_voucher_entry": 1,
},
item=acc,
@@ -320,9 +309,10 @@ class PeriodClosingVoucher(AccountsController):
if get_opening_entries:
query = query.where(
gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date)
| gl_entry.is_opening
== "Yes"
( # noqa: UP034
(gl_entry.posting_date.between(self.get("year_start_date"), self.posting_date))
| (gl_entry.is_opening == "Yes")
)
)
else:
query = query.where(
@@ -340,12 +330,16 @@ class PeriodClosingVoucher(AccountsController):
return query.run(as_dict=1)
def process_gl_entries(gl_entries, voucher_name):
def process_gl_and_closing_entries(gl_entries, closing_entries, voucher_name, company, closing_date):
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
make_closing_entries,
)
from erpnext.accounts.general_ledger import make_gl_entries
try:
if gl_entries:
make_gl_entries(gl_entries, merge_entries=False)
make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date)
frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Completed")
except Exception as e:
frappe.db.rollback()
@@ -353,26 +347,21 @@ def process_gl_entries(gl_entries, voucher_name):
frappe.db.set_value("Period Closing Voucher", voucher_name, "gle_processing_status", "Failed")
def process_closing_entries(gl_entries, closing_entries, voucher_name, company, closing_date):
from erpnext.accounts.doctype.account_closing_balance.account_closing_balance import (
make_closing_entries,
)
try:
if gl_entries + closing_entries:
make_closing_entries(gl_entries + closing_entries, voucher_name, company, closing_date)
except Exception as e:
frappe.db.rollback()
frappe.log_error(e)
def make_reverse_gl_entries(voucher_type, voucher_no):
def process_cancellation(voucher_type, voucher_no):
from erpnext.accounts.general_ledger import make_reverse_gl_entries
try:
make_reverse_gl_entries(voucher_type=voucher_type, voucher_no=voucher_no)
delete_closing_entries(voucher_no)
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Completed")
except Exception as e:
frappe.db.rollback()
frappe.log_error(e)
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Failed")
def delete_closing_entries(voucher_no):
closing_balance = frappe.qb.DocType("Account Closing Balance")
frappe.qb.from_(closing_balance).delete().where(
closing_balance.period_closing_voucher == voucher_no
).run()

View File

@@ -80,8 +80,10 @@ frappe.ui.form.on("POS Closing Entry", {
) {
reset_values(frm);
frappe.run_serially([
() => frappe.dom.freeze(__("Loading Invoices! Please Wait...")),
() => frm.trigger("set_opening_amounts"),
() => frm.trigger("get_pos_invoices"),
() => frappe.dom.unfreeze(),
]);
}
},

View File

@@ -33,7 +33,7 @@ class POSClosingEntry(StatusUpdater):
for key, value in pos_occurences.items():
if len(value) > 1:
error_list.append(
_("{} is added multiple times on rows: {}".format(frappe.bold(key), frappe.bold(value)))
_("{0} is added multiple times on rows: {1}").format(frappe.bold(key), frappe.bold(value))
)
if error_list:
@@ -128,9 +128,7 @@ def get_pos_invoices(start, end, pos_profile, user):
as_dict=1,
)
data = list(
filter(lambda d: get_datetime(start) <= get_datetime(d.timestamp) <= get_datetime(end), data)
)
data = list(filter(lambda d: get_datetime(start) <= get_datetime(d.timestamp) <= get_datetime(end), data))
# need to get taxes and payments so can't avoid get_doc
data = [frappe.get_doc("POS Invoice", d.name).as_dict() for d in data]
@@ -201,7 +199,11 @@ def make_closing_entry_from_opening(opening_entry):
else:
payments.append(
frappe._dict(
{"mode_of_payment": p.mode_of_payment, "opening_amount": 0, "expected_amount": p.amount}
{
"mode_of_payment": p.mode_of_payment,
"opening_amount": 0,
"expected_amount": p.amount,
}
)
)

View File

@@ -48,6 +48,7 @@
"shipping_address",
"company_address",
"company_address_display",
"company_contact_person",
"currency_and_price_list",
"currency",
"conversion_rate",
@@ -1557,12 +1558,19 @@
"fieldname": "update_billed_amount_in_delivery_note",
"fieldtype": "Check",
"label": "Update Billed Amount in Delivery Note"
},
{
"fieldname": "company_contact_person",
"fieldtype": "Link",
"label": "Company Contact Person",
"options": "Contact",
"print_hide": 1
}
],
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2024-03-20 16:00:34.268756",
"modified": "2024-11-26 13:10:50.309570",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -27,7 +27,7 @@ from erpnext.stock.doctype.serial_no.serial_no import (
class POSInvoice(SalesInvoice):
def __init__(self, *args, **kwargs):
super(POSInvoice, self).__init__(*args, **kwargs)
super().__init__(*args, **kwargs)
def validate(self):
if not cint(self.is_pos):
@@ -129,7 +129,9 @@ class POSInvoice(SalesInvoice):
)
if paid_amt and pay.amount != paid_amt:
return frappe.throw(_("Payment related to {0} is not completed").format(pay.mode_of_payment))
return frappe.throw(
_("Payment related to {0} is not completed").format(pay.mode_of_payment)
)
def validate_pos_reserved_serial_nos(self, item):
serial_nos = get_serial_nos(item.serial_no)
@@ -164,7 +166,7 @@ class POSInvoice(SalesInvoice):
serial_nos = row.serial_no.split("\n")
if serial_nos:
for key, value in collections.Counter(serial_nos).items():
for _key, value in collections.Counter(serial_nos).items():
if value > 1:
frappe.throw(_("Duplicate Serial No {0} found").format("key"))
@@ -191,9 +193,7 @@ class POSInvoice(SalesInvoice):
frappe.throw(
_(
"Row #{}: Batch No. {} of item {} has less than required stock available, {} more required"
).format(
item.idx, bold_invalid_batch_no, bold_item_name, bold_extra_batch_qty_needed
),
).format(item.idx, bold_invalid_batch_no, bold_item_name, bold_extra_batch_qty_needed),
title=_("Item Unavailable"),
)
@@ -249,7 +249,7 @@ class POSInvoice(SalesInvoice):
available_stock, is_stock_item = get_stock_availability(d.item_code, d.warehouse)
item_code, warehouse, qty = (
item_code, warehouse, _qty = (
frappe.bold(d.item_code),
frappe.bold(d.warehouse),
frappe.bold(d.qty),
@@ -379,7 +379,7 @@ class POSInvoice(SalesInvoice):
if self.is_return and entry.amount > 0:
frappe.throw(_("Row #{0} (Payment Table): Amount must be negative").format(entry.idx))
if self.is_return:
if self.is_return and self.docstatus != 0:
invoice_total = self.rounded_total or self.grand_total
if total_amount_in_payments and total_amount_in_payments < invoice_total:
frappe.throw(_("Total payments amount can't be greater than {}").format(-invoice_total))

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