Compare commits

...

485 Commits

Author SHA1 Message Date
Frappe PR Bot
feaa16d748 chore(release): Bumped to Version 14.58.1
## [14.58.1](https://github.com/frappe/erpnext/compare/v14.58.0...v14.58.1) (2024-01-03)

### Bug Fixes

* typerror on multi select dialog ([43cc7e4](43cc7e4a59))
2024-01-03 15:37:55 +00:00
ruthra kumar
6ca29a93bf Merge pull request #39123 from frappe/mergify/bp/version-14/pr-39116
fix: typerror on multi select dialog (backport #39116)
2024-01-03 21:06:48 +05:30
ruthra kumar
43cc7e4a59 fix: typerror on multi select dialog
(cherry picked from commit 7da9ffa3bd)
2024-01-03 15:26:11 +00:00
Frappe PR Bot
b6a36270b2 chore(release): Bumped to Version 14.58.0
# [14.58.0](https://github.com/frappe/erpnext/compare/v14.57.0...v14.58.0) (2024-01-03)

### Bug Fixes

* Add missing french translations (backport [#38368](https://github.com/frappe/erpnext/issues/38368)) ([#38513](https://github.com/frappe/erpnext/issues/38513)) ([2c90ee2](2c90ee23f9))
* **DX:** capture tracebacks with context (backport [#39060](https://github.com/frappe/erpnext/issues/39060)) ([#39062](https://github.com/frappe/erpnext/issues/39062)) ([fe9acc8](fe9acc898e))
* **Hierarchy Chart:** check if company is set before loading children ([#38985](https://github.com/frappe/erpnext/issues/38985)) ([e4d6df3](e4d6df39ff))
* issue occured when creating supplier with contact details (backport [#38147](https://github.com/frappe/erpnext/issues/38147)) ([#39046](https://github.com/frappe/erpnext/issues/39046)) ([81ef7b4](81ef7b4c00))
* Opening balance in bank reconciliation tool ([#38977](https://github.com/frappe/erpnext/issues/38977)) ([a2cba1b](a2cba1bf23))
* remove bad defaults (backport [#38986](https://github.com/frappe/erpnext/issues/38986)) ([#38987](https://github.com/frappe/erpnext/issues/38987)) ([29d383a](29d383ad8b))
* select options should dynamically load dimensions ([bfc94cf](bfc94cf284))
* take quantity into account when setting asset's gross purchase amt (backport [#39056](https://github.com/frappe/erpnext/issues/39056)) ([#39057](https://github.com/frappe/erpnext/issues/39057)) ([b8dce3e](b8dce3eeac))
* undefined error in Budget Variance and Profitability report ([cad15cd](cad15cdec2))
* use `Stock Qty` while getting `POS Reserved Qty` (backport [#38962](https://github.com/frappe/erpnext/issues/38962)) ([#38982](https://github.com/frappe/erpnext/issues/38982)) ([7ad42ec](7ad42ec957))
* Validate account in Sales/Purchase Taxes and Charges Template ([#39013](https://github.com/frappe/erpnext/issues/39013)) ([c0b5980](c0b598074c))
* work order with multi level, fetch operting cost from sub-assembly (backport [#38992](https://github.com/frappe/erpnext/issues/38992)) ([#39027](https://github.com/frappe/erpnext/issues/39027)) ([88e5c9e](88e5c9e61b))

### Features

* Merge taxes from mapped docs ([#38346](https://github.com/frappe/erpnext/issues/38346)) ([c74e6aa](c74e6aaebb))
* Show Ledger view for Purchase & Sales Register ([#38801](https://github.com/frappe/erpnext/issues/38801)) ([04fb215](04fb215ff5))

### Performance Improvements

* index item_code in bom explosion item (backport [#39085](https://github.com/frappe/erpnext/issues/39085)) ([#39087](https://github.com/frappe/erpnext/issues/39087)) ([558861b](558861b634))
2024-01-03 06:01:14 +00:00
Deepesh Garg
fa442ca788 Merge pull request #39091 from frappe/version-14-hotfix
chore: release v14
2024-01-03 11:29:59 +05:30
mergify[bot]
558861b634 perf: index item_code in bom explosion item (backport #39085) (#39087)
perf: index item_code in bom explosion item (#39085)

(cherry picked from commit 739434b727)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-02 14:43:23 +05:30
mergify[bot]
2c90ee23f9 fix: Add missing french translations (backport #38368) (#38513)
* fix: Add missing french translations (#38368)

fix: Add missing french translation

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
(cherry picked from commit a1e0197a8b)

# Conflicts:
#	erpnext/translations/fr.csv

* chore: resolve merge conflicts

---------

Co-authored-by: noec764 <58433943+noec764@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-01-02 13:51:43 +05:30
ruthra kumar
78771cd72f Merge pull request #39071 from frappe/mergify/bp/version-14-hotfix/pr-39067
fix: undefined error in Budget Variance and Profitability report (backport #39067)
2024-01-01 17:49:03 +05:30
ruthra kumar
bfc94cf284 fix: select options should dynamically load dimensions
(cherry picked from commit 1a9e091d12)
2024-01-01 17:41:15 +05:30
ruthra kumar
cad15cdec2 fix: undefined error in Budget Variance and Profitability report
'Budget' and 'Budget Account' doesn't have support for dynamic
dimension. It only supports hard-coded ones -  Project and Cost Center

(cherry picked from commit 92bc962f60)

# Conflicts:
#	erpnext/accounts/report/profitability_analysis/profitability_analysis.js
2024-01-01 12:08:03 +00:00
ruthra kumar
96dfcd7149 Merge pull request #39068 from frappe/mergify/bp/version-14-hotfix/pr-39023
refactor(perf): replace account subquery with 'in' condition (backport #39023)
2024-01-01 16:29:07 +05:30
ruthra kumar
c7d17d21e8 refactor(perf): replace account subquery with 'in' condition
(cherry picked from commit a517125d64)
2024-01-01 10:13:50 +00:00
mergify[bot]
fe9acc898e fix(DX): capture tracebacks with context (backport #39060) (#39062)
* fix(DX): capture tracebacks with context (#39060)

(cherry picked from commit 510fdf7bf6)

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

* Delete erpnext/manufacturing/doctype/bom_creator/bom_creator.py

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-01-01 15:38:22 +05:30
mergify[bot]
b8dce3eeac fix: take quantity into account when setting asset's gross purchase amt (backport #39056) (#39057)
fix: take quantity into account when setting asset's gross purchase amt (#39056)

fix: take quantity into account when setting asset's gross purchase amount
(cherry picked from commit 0346f47c1d)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2024-01-01 11:27:46 +05:30
mergify[bot]
81ef7b4c00 fix: issue occured when creating supplier with contact details (backport #38147) (#39046)
* fix: issue occured when creating supplier with contact details

(cherry picked from commit 7842c9fba8)

# Conflicts:
#	erpnext/selling/doctype/customer/customer.py

* fix: Suppier name was not taken when creating address from supplier

(cherry picked from commit 545ef3c234)

* chore: fix conflicts

* chore: fix linter issues

---------

Co-authored-by: kunhi <kunhimohamed6@gmail.com>
Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-31 18:06:47 +05:30
mergify[bot]
88e5c9e61b fix: work order with multi level, fetch operting cost from sub-assembly (backport #38992) (#39027)
* fix: work order with multi level, fetch operting cost from sub-assembly (#38992)

(cherry picked from commit 70abedc57a)

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

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-30 11:14:23 +05:30
mergify[bot]
c0b598074c fix: Validate account in Sales/Purchase Taxes and Charges Template (#39013)
fix: Validate account in Sales/Purchase Taxes and Charges Template (#39013)

(cherry picked from commit cd37fd790b)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-29 16:15:45 +05:30
Gursheen Kaur Anand
04fb215ff5 feat: Show Ledger view for Purchase & Sales Register (#38801)
* feat: fetch payments and journals

* refactor: use single qb query for PE and PI

* feat: fetch PE along with SI

* refactor: move repeating code to common controller

* fix: fetch cost center for PE

* feat: fetch JV with PE

* fix: validate party filter for fetching payments

* fix: linting issues

* refactor: use qb to fetch PE JV and Inv

* refactor: move fn to fetch advance taxes to utils & use qb

* fix: filtering through accounting dimensions

* chore: remove debugging print statements

* fix: modify rows and columns for ledger view

* refactor: filter accounting dimensions using qb

* fix: show additional table cols from india compliance api call

* chore: fix typo

* test: purchase register and ledger view

* fix: filter by party in opening row calculation

* fix: exclude cancelled gl entries for opening balance

* chore: change column format for report

* fix: check gl entry status using is_cancelled

* fix: running balance after sorting

* fix: gst itemised registers for india compliance api call

* fix: additional query cols for gst itemised registers

* fix: additional query cols for sales register

* fix: PE in sales register

* fix: tax accounts in sales register

* fix: Sales/Purchase register showing duplicate records

* fix: avoid fetching advance account for party

* refactor: remove unnecessary condition

* fix: remove checking for advance accounts in payments

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-29 13:02:17 +05:30
mergify[bot]
a2cba1bf23 fix: Opening balance in bank reconciliation tool (#38977)
fix: Opening balance in bank reconciliation tool (#38977)

(cherry picked from commit bbee9b5637)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-28 17:53:27 +05:30
mergify[bot]
29d383ad8b fix: remove bad defaults (backport #38986) (#38987)
fix: remove bad defaults (#38986)

Child tables can't have a default.

(cherry picked from commit b71b0d5997)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-28 14:22:23 +05:30
Rucha Mahabal
e4d6df39ff fix(Hierarchy Chart): check if company is set before loading children (#38985)
* fix(Org Chart): check if company is set before loading children

* refactor: avoid assigning undefined values, use empty strings, null instead

* fix: returning to org chart view from employee master does not render chart

- the check for company field is truthy from the employee doctype, so it does not render company field again. Explicitly check for company field on the same page

* fix(Org Chart Mobile): check if company is set before loading children
2023-12-28 12:54:31 +05:30
mergify[bot]
7ad42ec957 fix: use Stock Qty while getting POS Reserved Qty (backport #38962) (#38982)
fix: use `Stock Qty` while getting `POS Reserved Qty`

(cherry picked from commit 7223106417)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-28 11:59:47 +05:30
mergify[bot]
c74e6aaebb feat: Merge taxes from mapped docs (#38346)
* feat: Merge taxes from mapped docs (#38346)

* feat: Merge taxes from mapped docs

* chore: ci failures

(cherry picked from commit 9b1c22250f)

* chore: ci failures

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-12-28 10:03:26 +05:30
VihangT
92d61eb19e fix : correct logic for overlap error (#38798)
* fix : correct logic for overlap error

* fix : 

Updated as per lintels

* fix : 

changes as per linters

* fix : correct logic for overlap error

fixing overlap error logic with taking care of sequential time job cards in overlap job card list

Added Provision if time_logs list is empty
2023-12-27 16:11:14 +05:30
Frappe PR Bot
6e479f918d chore(release): Bumped to Version 14.57.0
# [14.57.0](https://github.com/frappe/erpnext/compare/v14.56.0...v14.57.0) (2023-12-27)

### Bug Fixes

* allow to set rate manually for service item in BOM ([#38880](https://github.com/frappe/erpnext/issues/38880)) ([c2f692a](c2f692a4e4))
* display all item rate stop messages ([226d0e0](226d0e0196))
* do not reset the basic rate for the material receipt stock entry ([#38896](https://github.com/frappe/erpnext/issues/38896)) ([98bfcc4](98bfcc4c75))
* first name error on customer creation ([#38927](https://github.com/frappe/erpnext/issues/38927)) ([28f052d](28f052d586))
* german translations for Lost Quotations ([#38435](https://github.com/frappe/erpnext/issues/38435)) ([81b5e6c](81b5e6c5f1))
* groups for current accounts in German CoAs ([39aa36e](39aa36e44b))
* incorrect price list in customer-wise item price report ([7577706](7577706a9d))
* min order qty optional in production plan (backport [#38956](https://github.com/frappe/erpnext/issues/38956)) ([#38957](https://github.com/frappe/erpnext/issues/38957)) ([f6f2712](f6f2712db0))
* remove rows with zero consumed qty ([f2f4100](f2f410093a))
* reposting not fixing valuation rate for sales return using movin… ([#38895](https://github.com/frappe/erpnext/issues/38895)) ([3a668bb](3a668bbe96))
* reset the incoming rate on changing of the warehouse ([#38909](https://github.com/frappe/erpnext/issues/38909)) ([2770ca1](2770ca1b65))
* skip jvs against bank accounts ([98198d3](98198d35ea))
* **test:** expect account currency when party account is specified. ([30cb218](30cb218638))
* unset discount amount from coupon discounts ([87e8dd0](87e8dd0d63))
* use party account currency when party account is specified ([d9e0d55](d9e0d55b88))
* **ux:** make PR and PI Item rate field readonly based on `Maintain Same Rate` (backport [#38942](https://github.com/frappe/erpnext/issues/38942)) ([#38943](https://github.com/frappe/erpnext/issues/38943)) ([1eee203](1eee203f7f))

### Features

* in_party_currency option for AR/AP reports ([3c717db](3c717db3fd))
* total_asset_cost field (backport [#38879](https://github.com/frappe/erpnext/issues/38879)) ([#38886](https://github.com/frappe/erpnext/issues/38886)) ([8169c7d](8169c7de0d))

### Performance Improvements

* Drop unused/duplicate/sub-optimal indexes (backport [#38884](https://github.com/frappe/erpnext/issues/38884)) ([#38912](https://github.com/frappe/erpnext/issues/38912)) ([b254a72](b254a72d41))
* use estimated rows instead of actual rows (backport [#38830](https://github.com/frappe/erpnext/issues/38830)) ([#38875](https://github.com/frappe/erpnext/issues/38875)) ([4d1ccd9](4d1ccd9e27))
2023-12-27 08:40:26 +00:00
rohitwaghchaure
8e8d0ad9aa Merge pull request #38953 from frappe/version-14-hotfix
chore: release v14
2023-12-27 14:09:17 +05:30
rohitwaghchaure
400c78c600 Merge branch 'version-14' into version-14-hotfix 2023-12-27 10:24:01 +05:30
mergify[bot]
f6f2712db0 fix: min order qty optional in production plan (backport #38956) (#38957)
* fix: min order qty optional in production plan (#38956)

* fix: min order qty optional in production plan

* fix: test cases

(cherry picked from commit b09c9354fb)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/bom.json
#	erpnext/manufacturing/doctype/production_plan/production_plan.py

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-26 21:59:09 +05:30
mergify[bot]
1eee203f7f fix(ux): make PR and PI Item rate field readonly based on Maintain Same Rate (backport #38942) (#38943)
* fix(ux): make PI Item rate field editable

(cherry picked from commit eb5bb9f9a9)

* fix(ux): make PI Item rate field readonly based on `Maintain Same Rate`

(cherry picked from commit cb9114442b)

* fix(ux): make PR Item rate field readonly based on `Maintain Same Rate`

(cherry picked from commit b1ba210332)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-26 14:45:54 +05:30
ruthra kumar
ec337a1c9f Merge pull request #38945 from frappe/mergify/bp/version-14-hotfix/pr-38891
fix: incorrect price list in customer-wise item price report (backport #38891)
2023-12-26 12:16:52 +05:30
ruthra kumar
7577706a9d fix: incorrect price list in customer-wise item price report
(cherry picked from commit 9a00edb031)
2023-12-26 06:17:45 +00:00
mergify[bot]
81b5e6c5f1 fix: german translations for Lost Quotations (#38435)
* fix: german translations for Lost Quotations (#38435)

(cherry picked from commit 5952cfa673)

# Conflicts:
#	erpnext/translations/de.csv

* chore: resolve conflicts

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-12-24 16:24:31 +05:30
ruthra kumar
28f052d586 fix: first name error on customer creation (#38927)
fix: error on customer creation
2023-12-24 16:12:13 +05:30
s-aga-r
2eac618bba Merge pull request #38892 from s-aga-r/FIX-6565
fix: remove rows with zero consumed qty
2023-12-22 15:58:09 +05:30
Deepesh Garg
6f6de13813 Merge pull request #38815 from frappe/mergify/bp/version-14-hotfix/pr-38803
fix: groups for current accounts in German CoAs (#38803)
2023-12-22 08:40:28 +05:30
Deepesh Garg
be1a269f9f Merge pull request #38857 from frappe/revert-38422-mergify/bp/version-14-hotfix/pr-38250
Revert "fix: unset discount amount based on coupon code (backport #38250)"
2023-12-22 08:40:07 +05:30
Deepesh Garg
0d70be56d2 Merge pull request #38370 from pps190/backport/version-14-hotfix/38289
fix: display all item rate stop messages (#38289)
2023-12-22 08:38:19 +05:30
Deepesh Garg
50655821c1 Merge pull request #38770 from frappe/mergify/bp/version-14-hotfix/pr-38767
fix: skip JVs against bank accounts in tax report (#38767)
2023-12-22 08:37:41 +05:30
mergify[bot]
b254a72d41 perf: Drop unused/duplicate/sub-optimal indexes (backport #38884) (#38912)
* perf: Drop unused/duplicate/sub-optimal indexes (#38884)

* ci: enable more checks

* perf: Drop unused/duplicate indexes

(cherry picked from commit 787333896c)

# Conflicts:
#	erpnext/accounts/doctype/gl_entry/gl_entry.json
#	erpnext/patches.txt

* chore: conflicts

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-21 21:40:59 +05:30
rohitwaghchaure
2770ca1b65 fix: reset the incoming rate on changing of the warehouse (#38909) 2023-12-21 18:49:36 +05:30
mergify[bot]
0d7cb1a9be chore: additional_asset_cost field (backport #38904) (backport #38905) (#38908)
chore: additional_asset_cost field (backport #38904) (#38905)

* chore: additional_asset_cost field (#38904)

(cherry picked from commit 283763dfb2)

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

* chore: resolve conflicts in asset.py

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
(cherry picked from commit 3b9feffc00)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-12-21 17:12:01 +05:30
Frappe PR Bot
3abb91b2c4 chore(release): Bumped to Version 14.56.0
# [14.56.0](https://github.com/frappe/erpnext/compare/v14.55.2...v14.56.0) (2023-12-21)

### Features

* total_asset_cost field (backport [#38879](https://github.com/frappe/erpnext/issues/38879)) (backport [#38886](https://github.com/frappe/erpnext/issues/38886)) ([#38907](https://github.com/frappe/erpnext/issues/38907)) ([a63b8df](a63b8df867))
2023-12-21 11:41:51 +00:00
mergify[bot]
a63b8df867 feat: total_asset_cost field (backport #38879) (backport #38886) (#38907)
feat: total_asset_cost field (backport #38879) (#38886)

* feat: total_asset_cost field (#38879)

(cherry picked from commit d370c60a6c)

# Conflicts:
#	erpnext/assets/doctype/asset/asset.json
#	erpnext/assets/doctype/asset/asset.py
#	erpnext/patches.txt

* chore: resolve conflicts in asset.json

* chore: resolve conflicts in asset.py

* chore: resolve conflicts in patches.txt

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
(cherry picked from commit 8169c7de0d)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-12-21 17:10:04 +05:30
mergify[bot]
3b9feffc00 chore: additional_asset_cost field (backport #38904) (#38905)
* chore: additional_asset_cost field (#38904)

(cherry picked from commit 283763dfb2)

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

* chore: resolve conflicts in asset.py

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-12-21 16:56:32 +05:30
Frappe PR Bot
0c13cb829c chore(release): Bumped to Version 14.55.2
## [14.55.2](https://github.com/frappe/erpnext/compare/v14.55.1...v14.55.2) (2023-12-21)

### Bug Fixes

* reposting not fixing valuation rate for sales return using movin… (backport [#38895](https://github.com/frappe/erpnext/issues/38895)) ([#38900](https://github.com/frappe/erpnext/issues/38900)) ([8aba707](8aba707b6a))
2023-12-21 10:05:58 +00:00
mergify[bot]
8aba707b6a fix: reposting not fixing valuation rate for sales return using movin… (backport #38895) (#38900)
fix: reposting not fixing valuation rate for sales return using movin… (#38895)

fix: reposting not fixing valuation rate for sales return using moving average method
(cherry picked from commit 3a668bbe96)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-21 15:34:49 +05:30
rohitwaghchaure
98bfcc4c75 fix: do not reset the basic rate for the material receipt stock entry (#38896) 2023-12-21 14:13:55 +05:30
rohitwaghchaure
3a668bbe96 fix: reposting not fixing valuation rate for sales return using movin… (#38895)
fix: reposting not fixing valuation rate for sales return using moving average method
2023-12-21 14:13:34 +05:30
s-aga-r
f2f410093a fix: remove rows with zero consumed qty 2023-12-21 11:03:18 +05:30
mergify[bot]
8169c7de0d feat: total_asset_cost field (backport #38879) (#38886)
* feat: total_asset_cost field (#38879)

(cherry picked from commit d370c60a6c)

# Conflicts:
#	erpnext/assets/doctype/asset/asset.json
#	erpnext/assets/doctype/asset/asset.py
#	erpnext/patches.txt

* chore: resolve conflicts in asset.json

* chore: resolve conflicts in asset.py

* chore: resolve conflicts in patches.txt

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-12-20 22:57:37 +05:30
Frappe PR Bot
eefac19cc8 chore(release): Bumped to Version 14.55.1
## [14.55.1](https://github.com/frappe/erpnext/compare/v14.55.0...v14.55.1) (2023-12-20)

### Bug Fixes

* allow to set rate manually for service item in BOM (backport [#38880](https://github.com/frappe/erpnext/issues/38880)) ([#38881](https://github.com/frappe/erpnext/issues/38881)) ([afc0491](afc049154d))
2023-12-20 13:06:21 +00:00
mergify[bot]
afc049154d fix: allow to set rate manually for service item in BOM (backport #38880) (#38881)
fix: allow to set rate manually for service item in BOM (#38880)

(cherry picked from commit c2f692a4e4)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-20 18:34:31 +05:30
mergify[bot]
4d1ccd9e27 perf: use estimated rows instead of actual rows (backport #38830) (#38875)
* perf: use estimated rows instead of actual rows (#38830)

(cherry picked from commit 9983283f95)

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

* chore: conflicts

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-20 18:17:41 +05:30
Deepesh Garg
c48c8b8ddb Merge pull request #38858 from GursheenK/unset-discount-amt-coupon-code
fix: unset discount amount for removed coupons
2023-12-20 18:17:20 +05:30
rohitwaghchaure
c2f692a4e4 fix: allow to set rate manually for service item in BOM (#38880) 2023-12-20 17:53:48 +05:30
ruthra kumar
d94b5a318d Merge pull request #38872 from frappe/mergify/bp/version-14-hotfix/pr-38838
fix: use party account currency when party account is specified (backport #38838)
2023-12-20 13:09:17 +05:30
Devin Slauenwhite
30cb218638 fix(test): expect account currency when party account is specified.
(cherry picked from commit a09241e3c7)
2023-12-20 07:05:27 +00:00
Devin Slauenwhite
d9e0d55b88 fix: use party account currency when party account is specified
(cherry picked from commit c7b961ffa2)
2023-12-20 07:05:26 +00:00
ruthra kumar
1e9b4e2403 Merge pull request #38800 from pps190/backport/version-14-hotfix/37746
feat: in_party_currency option for AR/AP reports (backport #37746)
2023-12-20 12:25:35 +05:30
Frappe PR Bot
8657ba374a chore(release): Bumped to Version 14.55.0
# [14.55.0](https://github.com/frappe/erpnext/compare/v14.54.2...v14.55.0) (2023-12-20)

### Bug Fixes

* close PO on SCO close (backport [#38667](https://github.com/frappe/erpnext/issues/38667)) ([#38680](https://github.com/frappe/erpnext/issues/38680)) ([22b442d](22b442d593))
* **customer:** contact creation for companies ([#38055](https://github.com/frappe/erpnext/issues/38055)) ([ed9b38b](ed9b38bc8d))
* **customer:** quick form and integration fixes ([#37386](https://github.com/frappe/erpnext/issues/37386)) ([6ed7c66](6ed7c6610a))
* error while filtering on name on reconciliation tool ([30b6321](30b6321fd5))
* fetch exc rate of multi currency journals ([bf585de](bf585de558))
* fetch item_tax_template values if fields with fetch_from exisit ([24ae45c](24ae45ce84))
* get customers for leaderboard ([9dfe342](9dfe342838))
* get items for leaderboard ([812b301](812b301aab))
* get sales partner for leaderboard ([c63f873](c63f873a6f))
* get sales person for leaderboard ([df93447](df93447d30))
* get suppliers for leaderboard ([7477ff3](7477ff3b5c))
* if not budget then don't validate ([#38861](https://github.com/frappe/erpnext/issues/38861)) ([d375164](d375164100))
* incoming rate for sales return with Moving Average valuation method ([#38849](https://github.com/frappe/erpnext/issues/38849)) ([7fdac62](7fdac62393))
* incorrect limit ([#38818](https://github.com/frappe/erpnext/issues/38818)) ([e18dc5c](e18dc5cea3))
* Init internal child table values ([d593f81](d593f81a16))
* item variant with manufacturer ([#38845](https://github.com/frappe/erpnext/issues/38845)) ([e0c8ff1](e0c8ff10da))
* not able to cancel SCR with Batch ([#38817](https://github.com/frappe/erpnext/issues/38817)) ([fb5090f](fb5090fd3f))
* not able to make inter-company po from so ([#38826](https://github.com/frappe/erpnext/issues/38826)) ([23042df](23042dfc3c))
* on closed unreserved the production plan qty ([#38848](https://github.com/frappe/erpnext/issues/38848)) ([2184e8e](2184e8ef58))
* Reset SLA on issue doesn't work (backport [#38789](https://github.com/frappe/erpnext/issues/38789)) ([#38790](https://github.com/frappe/erpnext/issues/38790)) ([942f34a](942f34a734))
* supplier removed on selection of item (backport [#38712](https://github.com/frappe/erpnext/issues/38712)) ([#38732](https://github.com/frappe/erpnext/issues/38732)) ([dda95ea](dda95ea892))
* timezone aware SLA banner (backport [#38745](https://github.com/frappe/erpnext/issues/38745)) ([#38746](https://github.com/frappe/erpnext/issues/38746)) ([73d525e](73d525e84d))
* **ux:** don't override Item Name and Description in MR (backport [#38720](https://github.com/frappe/erpnext/issues/38720)) ([#38762](https://github.com/frappe/erpnext/issues/38762)) ([f7bfbd8](f7bfbd82dd))
* validation error on reconciling PE to Journals as Invoice ([9836205](9836205725))
* wrong currency in Stock Balance report (backport [#38778](https://github.com/frappe/erpnext/issues/38778)) ([#38779](https://github.com/frappe/erpnext/issues/38779)) ([e05b23c](e05b23c388))
* wrong paid and cn amount on pos invoice ([77da0da](77da0da945))

### Features

* **RFQ:** special properties in print preview (backport [#38725](https://github.com/frappe/erpnext/issues/38725)) ([#38726](https://github.com/frappe/erpnext/issues/38726)) ([2290750](229075048b))
* set lead name from email ([1469ca7](1469ca7d0b))

### Performance Improvements

* index `return_against` on delivery note (backport [#38827](https://github.com/frappe/erpnext/issues/38827)) ([#38831](https://github.com/frappe/erpnext/issues/38831)) ([4114760](4114760efd))
2023-12-20 04:46:08 +00:00
Deepesh Garg
3a8b7e9b96 Merge pull request #38852 from frappe/version-14-hotfix
chore: release v14
2023-12-20 10:14:59 +05:30
mergify[bot]
22b442d593 fix: close PO on SCO close (backport #38667) (#38680)
fix: close PO on SCO close

(cherry picked from commit b023e5d6b3)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-20 09:14:54 +05:30
mergify[bot]
f7bfbd82dd fix(ux): don't override Item Name and Description in MR (backport #38720) (#38762)
fix(ux): don't override Item Name and Description in MR

(cherry picked from commit 726ac6bda1)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-20 09:14:03 +05:30
rohitwaghchaure
d375164100 fix: if not budget then don't validate (#38861) 2023-12-19 18:19:20 +05:30
rohitwaghchaure
7fdac62393 fix: incoming rate for sales return with Moving Average valuation method (#38849) 2023-12-19 18:01:50 +05:30
rohitwaghchaure
2184e8ef58 fix: on closed unreserved the production plan qty (#38848) 2023-12-19 17:20:41 +05:30
Gursheen Anand
87e8dd0d63 fix: unset discount amount from coupon discounts 2023-12-19 15:56:59 +05:30
rohitwaghchaure
857843bc29 chore: fix test case (#38856) 2023-12-19 15:54:29 +05:30
Gursheen Kaur Anand
37a18299d0 Revert "fix: unset discount amount based on coupon code (backport #38250)" 2023-12-19 15:35:35 +05:30
rohitwaghchaure
e0c8ff10da fix: item variant with manufacturer (#38845) 2023-12-19 12:45:08 +05:30
ruthra kumar
61b02ec75c Merge pull request #38843 from frappe/mergify/bp/version-14-hotfix/pr-38797
fix: wrong paid and cn amount on pos invoice (backport #38797)
2023-12-19 11:33:25 +05:30
Dany Robert
939b7f7cbf test: partial payment for pos invoice
(cherry picked from commit 8772628912)
2023-12-19 05:33:10 +00:00
Dany Robert
77da0da945 fix: wrong paid and cn amount on pos invoice
(cherry picked from commit 5cb5e09dbb)
2023-12-19 05:33:09 +00:00
Devin Slauenwhite
226d0e0196 fix: display all item rate stop messages 2023-12-18 14:14:29 -05:00
mergify[bot]
4114760efd perf: index return_against on delivery note (backport #38827) (#38831)
* perf: index `return_against` on delivery note (#38827)

There's a multi-column index but that's useful IFF all parts of column
are part of query.

return against on it's own is VERY unique because it's a primary key, we
don't need a multi-column index here.

(cherry picked from commit 8d79365e0d)

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

* chore: conflict

---------

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-18 18:10:54 +05:30
rohitwaghchaure
23042dfc3c fix: not able to make inter-company po from so (#38826) 2023-12-18 17:44:17 +05:30
ruthra kumar
9216a852d4 Merge pull request #38824 from frappe/mergify/bp/version-14-hotfix/pr-38820
refactor: ignore ERR journals in Statment of Accounts (backport #38820)
2023-12-18 16:24:57 +05:30
ruthra kumar
6478c80359 refactor: ignore ERR journals in Statment of Accounts
(cherry picked from commit 39ef75e2d0)
2023-12-18 15:59:59 +05:30
rohitwaghchaure
e18dc5cea3 fix: incorrect limit (#38818) 2023-12-18 15:59:56 +05:30
rohitwaghchaure
fb5090fd3f fix: not able to cancel SCR with Batch (#38817) 2023-12-18 14:11:36 +05:30
barredterra
39aa36e44b fix: groups for current accounts in German CoAs
(cherry picked from commit 259f313af7)
2023-12-17 18:24:10 +00:00
Deepesh Garg
20a764a4a3 Merge pull request #38809 from vorasmit/fetch-item-taxes-v14
fix: fetch item_tax_template values if fields with fetch_from exisit (#38284)
2023-12-17 18:51:22 +05:30
Smit Vora
24ae45ce84 fix: fetch item_tax_template values if fields with fetch_from exisit 2023-12-17 14:03:37 +05:30
Deepesh Garg
a14e7f0e84 Merge pull request #38751 from frappe/mergify/bp/version-14-hotfix/pr-38505
feat: set lead name from email (#38505)
2023-12-16 22:29:43 +05:30
Devin Slauenwhite
7eee573fcb fixup! feat: in_party_currency option for AR/AP reports
fix: merge conflict typo
2023-12-16 16:29:01 +00:00
Richard Case
0894022695 chore: update tests 2023-12-16 16:15:00 +00:00
Richard Case
3c717db3fd feat: in_party_currency option for AR/AP reports 2023-12-16 16:14:44 +00:00
mergify[bot]
942f34a734 fix: Reset SLA on issue doesn't work (backport #38789) (#38790)
fix: Reset SLA on issue doesn't work (#38789)

This was broken since last refactor where it was spun off to work with
all types of doctypes but client side code was never adapted.

(cherry picked from commit fa1c7b663c)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-15 22:02:29 +05:30
Raffael Meyer
4821919695 Merge branch 'version-14-hotfix' into mergify/bp/version-14-hotfix/pr-38505 2023-12-15 15:15:37 +01:00
Deepesh Garg
34549b62bd Merge pull request #38782 from frappe/mergify/bp/version-14-hotfix/pr-38691
fix: Init internal child table values (#38691)
2023-12-15 18:48:10 +05:30
Deepesh Garg
d593f81a16 fix: Init internal child table values
(cherry picked from commit 2588970d55)
2023-12-15 12:45:51 +00:00
mergify[bot]
e05b23c388 fix: wrong currency in Stock Balance report (backport #38778) (#38779)
fix: wrong currency in Stock Balance report

(cherry picked from commit 5a83a16e60)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-15 15:32:50 +05:30
ruthra kumar
d4c131b153 Merge pull request #38774 from frappe/mergify/bp/version-14-hotfix/pr-38766
fix: validation error on reconciling PE to Journals as Invoice (backport #38766)
2023-12-15 14:41:43 +05:30
ruthra kumar
9836205725 fix: validation error on reconciling PE to Journals as Invoice
With the same exchange rate on Journal Entry and Payment Entry,
reconcilition should not post exc gain/loss journal and should not
throw validation error

(cherry picked from commit 5eeb650dfd)
2023-12-15 13:20:38 +05:30
Gursheen Anand
98198d35ea fix: skip jvs against bank accounts
(cherry picked from commit f7b2380ec1)
2023-12-15 07:29:14 +00:00
Deepesh Garg
12cd7a7083 Merge pull request #38674 from frappe/mergify/bp/version-14-hotfix/pr-38672
fix: get data for leaderboard (#38672)
2023-12-15 10:15:41 +05:30
Deepesh Garg
e539152c6b Merge pull request #38753 from barredterra/contact-from-customer-creation
fix: address and contact from customer creation (backport #38055, #37386, #38060)
2023-12-15 10:14:58 +05:30
David Arnold
6ed7c6610a fix(customer): quick form and integration fixes (#37386) 2023-12-14 16:50:20 +01:00
barredterra
d6d717c315 test: parse full name 2023-12-14 16:47:46 +01:00
barredterra
935e23449f refactor: parse full name 2023-12-14 16:47:36 +01:00
David Arnold
ed9b38bc8d fix(customer): contact creation for companies (#38055) 2023-12-14 16:47:15 +01:00
Raffael Meyer
2c52f2ce13 chore: resolve conflicts 2023-12-14 13:51:47 +01:00
barredterra
1469ca7d0b feat: set lead name from email
(cherry picked from commit ceeb724acc)

# Conflicts:
#	erpnext/crm/doctype/lead/lead.json
2023-12-14 12:49:40 +00:00
mergify[bot]
73d525e84d fix: timezone aware SLA banner (backport #38745) (#38746)
fix: timezone aware SLA banner (#38745)

(cherry picked from commit eaf86a6461)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-14 15:59:19 +05:30
ruthra kumar
f6c611d026 Merge pull request #38744 from ruthra-kumar/filter_error_on_reconciliation_tool
fix: error while filtering on name on reconciliation tool
2023-12-14 15:10:12 +05:30
ruthra kumar
30b6321fd5 fix: error while filtering on name on reconciliation tool 2023-12-14 14:28:20 +05:30
Frappe PR Bot
20a26c3dd4 chore(release): Bumped to Version 14.54.2
## [14.54.2](https://github.com/frappe/erpnext/compare/v14.54.1...v14.54.2) (2023-12-14)

### Bug Fixes

* fetch exc rate of multi currency journals ([cdef0bd](cdef0bd503))
2023-12-14 06:20:30 +00:00
ruthra kumar
d975eccaab Merge pull request #38741 from frappe/mergify/bp/version-14/pr-38717
fix: fetch exc rate of multi currency journals on reconciliation (backport #38717)
2023-12-14 11:49:20 +05:30
ruthra kumar
cdef0bd503 fix: fetch exc rate of multi currency journals
(cherry picked from commit 1b3ba25220)
2023-12-14 06:00:23 +00:00
ruthra kumar
a714114cd9 Merge pull request #38736 from frappe/mergify/bp/version-14-hotfix/pr-38717
fix: fetch exc rate of multi currency journals on reconciliation (backport #38717)
2023-12-14 09:59:44 +05:30
ruthra kumar
bf585de558 fix: fetch exc rate of multi currency journals
(cherry picked from commit 1b3ba25220)
2023-12-14 04:06:43 +00:00
Frappe PR Bot
b7fd24074d chore(release): Bumped to Version 14.54.1
## [14.54.1](https://github.com/frappe/erpnext/compare/v14.54.0...v14.54.1) (2023-12-13)

### Bug Fixes

* supplier removed on selection of item (backport [#38712](https://github.com/frappe/erpnext/issues/38712)) (backport [#38732](https://github.com/frappe/erpnext/issues/38732)) ([#38735](https://github.com/frappe/erpnext/issues/38735)) ([d53a9f6](d53a9f6530))
2023-12-13 19:09:56 +00:00
mergify[bot]
d53a9f6530 fix: supplier removed on selection of item (backport #38712) (backport #38732) (#38735)
fix: supplier removed on selection of item (backport #38712) (#38732)

fix: supplier removed on selection of item (#38712)

(cherry picked from commit db24e24882)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-12-14 00:38:47 +05:30
mergify[bot]
dda95ea892 fix: supplier removed on selection of item (backport #38712) (#38732)
fix: supplier removed on selection of item (#38712)

(cherry picked from commit db24e24882)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-13 19:05:52 +00:00
mergify[bot]
4908d03a88 Revert "fix(ux): don't update qty blindly" (backport #38728) (backport #38729) (#38733)
Revert "fix(ux): don't update qty blindly" (backport #38728) (#38729)

Revert "fix(ux): don't update qty blindly" (#38728)

(cherry picked from commit 6851c5042f)

Co-authored-by: Ankush Menat <ankush@frappe.io>
(cherry picked from commit 0d49dd3648)

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-12-14 00:30:36 +05:30
mergify[bot]
229075048b feat(RFQ): special properties in print preview (backport #38725) (#38726)
feat: RFQ print preview

(cherry picked from commit 27f05145ae)

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2023-12-14 00:10:58 +05:30
mergify[bot]
0d49dd3648 Revert "fix(ux): don't update qty blindly" (backport #38728) (#38729)
Revert "fix(ux): don't update qty blindly" (#38728)

(cherry picked from commit 6851c5042f)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-12-13 23:16:26 +05:30
Frappe PR Bot
214861d68f chore(release): Bumped to Version 14.54.0
# [14.54.0](https://github.com/frappe/erpnext/compare/v14.53.0...v14.54.0) (2023-12-12)

### Bug Fixes

* 1st row depr. sch. value of asset put to less than 180 days acc. to I.T. S. 32 ([#38697](https://github.com/frappe/erpnext/issues/38697)) ([753a1b5](753a1b511d))
* calc monthly_repayment_amount correctly in regenerate_repayment_schedule ([#38636](https://github.com/frappe/erpnext/issues/38636)) ([008400d](008400d287))
* format only if searched text contain link value text ([b28deaa](b28deaae2c))
* limit end date to current date ([cbe15e1](cbe15e159a))
* typo in unittest ([#38673](https://github.com/frappe/erpnext/issues/38673)) ([c87a3c7](c87a3c7793))
* **ux:** don't update qty blindly (backport [#38608](https://github.com/frappe/erpnext/issues/38608)) ([#38638](https://github.com/frappe/erpnext/issues/38638)) ([29cd474](29cd474f44))

### Features

* add employee number to client user bootinfo (backport [#38477](https://github.com/frappe/erpnext/issues/38477)) ([#38602](https://github.com/frappe/erpnext/issues/38602)) ([c2a137f](c2a137f0fb))

### Reverts

* Revert "refactor: bank transaction (backport #38182)" (#38653) ([7813efa](7813efad35)), closes [#38182](https://github.com/frappe/erpnext/issues/38182) [#38653](https://github.com/frappe/erpnext/issues/38653) [#38182](https://github.com/frappe/erpnext/issues/38182)
2023-12-12 16:12:27 +00:00
Deepesh Garg
e7b96209cd Merge pull request #38689 from frappe/version-14-hotfix
chore: release v14
2023-12-12 21:40:16 +05:30
Anand Baburajan
753a1b511d fix: 1st row depr. sch. value of asset put to less than 180 days acc. to I.T. S. 32 (#38697)
fix: 1st row value of asset put to less than 180 days acc. to IT S. 32
2023-12-12 20:53:44 +05:30
ruthra kumar
6715dd6167 Merge pull request #38677 from frappe/mergify/bp/version-14-hotfix/pr-38673
fix: typo in unittest (backport #38673)
2023-12-12 17:35:16 +05:30
ruthra kumar
a061798a6f Merge pull request #38686 from frappe/mergify/bp/version-14-hotfix/pr-38685
refactor: add `get_list` for virtual child doctypes (backport #38685)
2023-12-12 15:24:56 +05:30
ruthra kumar
fa79a7cdab refactor: add get_list for virtual child doctypes
(cherry picked from commit 15c90551b6)
2023-12-12 14:51:41 +05:30
ruthra kumar
6884aac2a0 Merge pull request #38683 from frappe/mergify/bp/version-14-hotfix/pr-38679
refactor(test): repost utility deletion flag test (backport #38679)
2023-12-12 13:33:17 +05:30
ruthra kumar
e61a12b4cb refactor(test): update repost settings before test case
(cherry picked from commit acb6e8e120)
2023-12-12 07:16:49 +00:00
ruthra kumar
4542a12787 refactor: increase limit and remove explicit call to start_repost
(cherry picked from commit ccff588563)
2023-12-12 07:16:49 +00:00
ruthra kumar
f0408c89ce refactor: remove explicit commit on repost
(cherry picked from commit a97b3db749)
2023-12-12 07:16:48 +00:00
ruthra kumar
7c080bd60c refactor(test): repost utility deletion flag test
(cherry picked from commit cc15f695b4)
2023-12-12 07:16:48 +00:00
Raffael Meyer
c87a3c7793 fix: typo in unittest (#38673)
(cherry picked from commit 6ad298adfc)
2023-12-12 04:26:10 +00:00
barredterra
038a30feb0 chore: deprecate unused method
(cherry picked from commit 956c3c50a0)
2023-12-12 04:24:39 +00:00
barredterra
c63f873a6f fix: get sales partner for leaderboard
(cherry picked from commit 40c1acc961)
2023-12-12 04:24:39 +00:00
barredterra
df93447d30 fix: get sales person for leaderboard
(cherry picked from commit 7babfd4ac4)
2023-12-12 04:24:39 +00:00
barredterra
7477ff3b5c fix: get suppliers for leaderboard
(cherry picked from commit 65df4b6aa8)
2023-12-12 04:24:38 +00:00
barredterra
812b301aab fix: get items for leaderboard
(cherry picked from commit 2721ee3a8d)
2023-12-12 04:24:38 +00:00
barredterra
9dfe342838 fix: get customers for leaderboard
(cherry picked from commit 137b5a6108)
2023-12-12 04:24:38 +00:00
Deepesh Garg
7813efad35 Revert "refactor: bank transaction (backport #38182)" (#38653)
Revert "refactor: bank transaction (#38182)"

This reverts commit a4b5fc8100.
2023-12-10 16:29:27 +05:30
mergify[bot]
29cd474f44 fix(ux): don't update qty blindly (backport #38608) (#38638)
fix(ux): don't update qty blindly

(cherry picked from commit 0156339f34)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-08 17:59:46 +05:30
Anand Baburajan
008400d287 fix: calc monthly_repayment_amount correctly in regenerate_repayment_schedule (#38636) 2023-12-08 16:34:29 +05:30
Shariq Ansari
4b9d9c0df4 Merge pull request #38626 from frappe/mergify/bp/version-14-hotfix/pr-38623
fix: format only if searched text contain link value text (backport #38623)
2023-12-07 20:51:16 +05:30
Shariq Ansari
b28deaae2c fix: format only if searched text contain link value text
(cherry picked from commit 08ed3cd313)
2023-12-07 15:17:48 +00:00
Ankush Menat
4e6b8ead8f chore: remove unused cache=True
(cherry picked from commit 6a47a2ceaf)
2023-12-06 20:55:35 +05:30
mergify[bot]
c2a137f0fb feat: add employee number to client user bootinfo (backport #38477) (#38602)
feat: add employee number to client user bootinfo (#38477)

(cherry picked from commit 525f656cc1)

Co-authored-by: Richard Case <110036763+casesolved-co-uk@users.noreply.github.com>
2023-12-06 20:55:06 +05:30
Deepesh Garg
f6fcb7ee26 Merge pull request #38571 from frappe/mergify/bp/version-14-hotfix/pr-38556
fix(minor): financial statements period end date (#38556)
2023-12-06 13:45:45 +05:30
Frappe PR Bot
973d06d96f chore(release): Bumped to Version 14.53.0
# [14.53.0](https://github.com/frappe/erpnext/compare/v14.52.1...v14.53.0) (2023-12-05)

### Bug Fixes

* `OperationalError` while selecting Serial No in `Warranty Claim` (backport [#38394](https://github.com/frappe/erpnext/issues/38394)) ([#38413](https://github.com/frappe/erpnext/issues/38413)) ([49296cd](49296cd5cb))
* better overlap logic for job card (backport [#38432](https://github.com/frappe/erpnext/issues/38432)) ([#38521](https://github.com/frappe/erpnext/issues/38521)) ([6db63c9](6db63c971e))
* consider the `Valuation Method` while picking incorrect SLE (backport [#38592](https://github.com/frappe/erpnext/issues/38592)) ([#38594](https://github.com/frappe/erpnext/issues/38594)) ([01b2a1f](01b2a1ffeb))
* debit credit mismatch in multi-currecy asset purchase receipt ([#38342](https://github.com/frappe/erpnext/issues/38342)) ([fd6a23c](fd6a23cf41))
* don't consider cancelled entries ([#38401](https://github.com/frappe/erpnext/issues/38401)) ([9345334](9345334196))
* don't show non-stock items in Stock Analytics report (backport [#38543](https://github.com/frappe/erpnext/issues/38543)) ([#38544](https://github.com/frappe/erpnext/issues/38544)) ([2e333e6](2e333e6802))
* don't update previous doc on rate change (backport [#38493](https://github.com/frappe/erpnext/issues/38493)) ([#38523](https://github.com/frappe/erpnext/issues/38523)) ([b88c7d6](b88c7d63de))
* exclude `invoice_doctypes` from party advance ([1042d4c](1042d4cfeb))
* exploded items in Subcontracting Receipt (backport [#38441](https://github.com/frappe/erpnext/issues/38441)) ([#38444](https://github.com/frappe/erpnext/issues/38444)) ([2908d96](2908d966b6))
* get dynamic link with parenttype contact ([12d3cda](12d3cda2d9))
* incorrect customer outstanding amount ([#38475](https://github.com/frappe/erpnext/issues/38475)) ([c07723d](c07723d49d))
* incorrect material request quantity in Production Plan (backport [#38566](https://github.com/frappe/erpnext/issues/38566)) ([#38578](https://github.com/frappe/erpnext/issues/38578)) ([70965ef](70965efd94))
* incorrect ordered qty for Subcontracting Order ([#38415](https://github.com/frappe/erpnext/issues/38415)) ([8e37087](8e370876cc))
* incorrect requested quantity for the subcontracting order (backport [#38455](https://github.com/frappe/erpnext/issues/38455)) ([#38471](https://github.com/frappe/erpnext/issues/38471)) ([497049b](497049b3fd))
* item group filter in sales person wise report ([eee9062](eee9062814))
* make create button translatable ([#38165](https://github.com/frappe/erpnext/issues/38165)) ([c71b31e](c71b31e3b8))
* no fstring in translation ([#38381](https://github.com/frappe/erpnext/issues/38381)) ([cec2574](cec25740ea))
* **pe:** show split alert only on splitting ([8d6d74c](8d6d74c237))
* **regional:** use net figures for sales calc ([#38260](https://github.com/frappe/erpnext/issues/38260)) ([d337533](d337533907))
* remove hardcoded, implicit rounding loss allowance ([419943a](419943a9d9))
* set cwip account before asset tests ([ecde1d5](ecde1d58b5))
* show item name as title instead of item group in BOM (backport [#38478](https://github.com/frappe/erpnext/issues/38478)) ([#38480](https://github.com/frappe/erpnext/issues/38480)) ([0df52d2](0df52d2c4f))
* SO ordered qty on PO item removal ([#38378](https://github.com/frappe/erpnext/issues/38378)) ([b7fe163](b7fe163de5))
* sql error while filtering on finance book in GL ([25ec1fc](25ec1fce61))
* unset discount amount based on coupon code ([7fa97fa](7fa97fa7b5))
* use `docstatus` instead of `status` (backport [#38439](https://github.com/frappe/erpnext/issues/38439)) ([#38442](https://github.com/frappe/erpnext/issues/38442)) ([2dc4b02](2dc4b02fc8))
* use predefined onload property `load_after_mapping` (backport [#38209](https://github.com/frappe/erpnext/issues/38209)) ([#38518](https://github.com/frappe/erpnext/issues/38518)) ([9f23b7e](9f23b7e46f))
* **ux:** make valuation field read only when it can't be modified (backport [#38450](https://github.com/frappe/erpnext/issues/38450)) ([#38463](https://github.com/frappe/erpnext/issues/38463)) ([bec7fb5](bec7fb5493))
* validate finance_books table length in asset ([#38584](https://github.com/frappe/erpnext/issues/38584)) ([14b908f](14b908f8ab))

### Features

* `Company` filter in `Stock Ledger Variance` report (backport [#38553](https://github.com/frappe/erpnext/issues/38553)) ([#38573](https://github.com/frappe/erpnext/issues/38573)) ([6c89f35](6c89f351f4))
* shift depreciation for assets [v14] [backport of [#38327](https://github.com/frappe/erpnext/issues/38327)] ([#38404](https://github.com/frappe/erpnext/issues/38404)) ([d8c3935](d8c3935e64))
2023-12-05 17:17:12 +00:00
Deepesh Garg
37bf57cf75 Merge pull request #38589 from frappe/version-14-hotfix
chore: release v14
2023-12-05 22:45:16 +05:30
Deepesh Garg
8d4c38f6b9 Merge branch 'version-14' into version-14-hotfix 2023-12-05 22:01:50 +05:30
mergify[bot]
01b2a1ffeb fix: consider the Valuation Method while picking incorrect SLE (backport #38592) (#38594)
* fix: incorrect SLE for `Moving Average` valuation method

(cherry picked from commit 8beec58670)

* feat: add `Valuation Method` column in `Stock Ledger Variance` report

(cherry picked from commit 16c297c2ec)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-05 18:13:59 +05:30
ruthra kumar
b858d1ceeb Merge pull request #38585 from frappe/mergify/bp/version-14-hotfix/pr-38580
fix: sql error while filtering on finance book in GL (backport #38580)
2023-12-05 15:07:07 +05:30
Sherin KR
14b908f8ab fix: validate finance_books table length in asset (#38584) 2023-12-05 14:44:59 +05:30
ruthra kumar
25ec1fce61 fix: sql error while filtering on finance book in GL
(cherry picked from commit b1d9f3132d)
2023-12-05 09:11:39 +00:00
mergify[bot]
70965efd94 fix: incorrect material request quantity in Production Plan (backport #38566) (#38578)
fix: incorrect material request quantity in Production Plan (#38566)

(cherry picked from commit aaa9036eca)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-05 14:24:54 +05:30
Karol Walczysko
9f43e9e668 Fix: Asset JS fieldname depreciation_schedule to schedules in make_schedules_editable function. (#38583)
Fix fieldname depreciation_schedule to schedules

Renames the depreciation_schedule fieldname to schedules in the make_schedules_editable function.
2023-12-05 14:22:23 +05:30
ruthra kumar
47ef075759 Merge pull request #38576 from frappe/mergify/bp/version-14-hotfix/pr-38570
refactor: ignore unreconcile doc on PI cancel/delete (backport #38570)
2023-12-05 13:52:22 +05:30
ruthra kumar
4544727654 refactor: ingore on JE cancel as well
(cherry picked from commit 1a5d56977e)
2023-12-05 13:32:10 +05:30
mergify[bot]
6c89f351f4 feat: Company filter in Stock Ledger Variance report (backport #38553) (#38573)
feat: `Company` filter in `Stock Ledger Variance` report

(cherry picked from commit fb3421fcce)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-05 12:33:14 +05:30
ruthra kumar
35c06fabc5 refactor: ignore unreconcile doc on PI cancel/delete
(cherry picked from commit 4ca84eadb6)
2023-12-05 06:34:13 +00:00
Gursheen Anand
cbe15e159a fix: limit end date to current date
(cherry picked from commit ab6e92aae1)
2023-12-05 05:54:12 +00:00
Shariq Ansari
3411814ee3 Merge pull request #38563 from frappe/mergify/bp/version-14-hotfix/pr-38562
fix: get dynamic link with parenttype contact (backport #38562)
2023-12-04 19:22:28 +05:30
Shariq Ansari
12d3cda2d9 fix: get dynamic link with parenttype contact
(cherry picked from commit 3d7ad71b22)
2023-12-04 13:51:13 +00:00
ruthra kumar
efc6a8a044 Merge pull request #38546 from frappe/mergify/bp/version-14-hotfix/pr-38283
chore: move reconciliation cleanup patch to pre-model sync (backport #38283)
2023-12-04 14:33:44 +05:30
ruthra kumar
0d913a6401 Merge pull request #38549 from frappe/mergify/bp/version-14-hotfix/pr-38475
fix: incorrect customer outstanding amount (backport #38475)
2023-12-04 13:58:16 +05:30
ruthra kumar
2e3a860a46 chore: resolve conflict 2023-12-04 13:43:41 +05:30
NIYAZ RAZAK
c07723d49d fix: incorrect customer outstanding amount (#38475)
* fix: incorrect customer outstanding amount

* chore: resolve linting error

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

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
(cherry picked from commit 3df1d75bdd)
2023-12-04 08:10:42 +00:00
ruthra kumar
7551ba3851 chore: move reconciliation cleanup patch to pre-model
(cherry picked from commit f258ab5e98)

# Conflicts:
#	erpnext/patches.txt
2023-12-04 07:33:38 +00:00
ruthra kumar
67f149ee06 Merge pull request #38541 from frappe/mergify/bp/version-14-hotfix/pr-38148
refactor: convert Payment Reconciliation to virtual doctype (backport #38148)
2023-12-04 13:01:49 +05:30
ruthra kumar
d27e588672 chore: resolve conflicts 2023-12-04 12:21:19 +05:30
mergify[bot]
2e333e6802 fix: don't show non-stock items in Stock Analytics report (backport #38543) (#38544)
* fix(ux): stock-item filter for Item Code field

(cherry picked from commit ccdcb7dfcc)

* fix: don't show non-stock items in Stock Analytics report

(cherry picked from commit 01aadbef85)

* fix: `linter`

(cherry picked from commit 15fff84bb5)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-04 12:18:31 +05:30
ruthra kumar
59773acdd2 chore: clear singles table and reconciliation related tables
(cherry picked from commit f31002636b)

# Conflicts:
#	erpnext/patches.txt
2023-12-04 06:31:05 +00:00
ruthra kumar
454d789232 chore: remove reconciliation defaults from patch
(cherry picked from commit b5dd0c8630)

# Conflicts:
#	erpnext/patches.txt
2023-12-04 06:31:04 +00:00
ruthra kumar
c349c89ae3 refactor: virtual doctype methods
(cherry picked from commit 9c7b19e0b7)
2023-12-04 06:31:04 +00:00
ruthra kumar
36dc7bd55e refactor: convert payment reconciliation tool to virtual doctype
(cherry picked from commit 3a51a3f37e)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
2023-12-04 06:31:03 +00:00
ruthra kumar
5a8bf7bf7d Merge pull request #38539 from frappe/mergify/bp/version-14-hotfix/pr-38220
fix: exclude `invoice_doctypes` from party advance (backport #38220)
2023-12-04 11:19:24 +05:30
Dany Robert
1042d4cfeb fix: exclude invoice_doctypes from party advance
(cherry picked from commit f34ffc2062)
2023-12-04 05:31:28 +00:00
mergify[bot]
9f23b7e46f fix: use predefined onload property load_after_mapping (backport #38209) (#38518)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
fix: use predefined onload property `load_after_mapping` (#38209)
2023-12-04 09:52:16 +05:30
mergify[bot]
b7fe163de5 fix: SO ordered qty on PO item removal (#38378)
* fix: SO ordered qty on PO item removal (#38378)

* fix: update ordered_qty for SO when PO items removed

* refactor: use cached value

---------

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
(cherry picked from commit 9087e1443e)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.py

* chore: resolve conflicts

---------

Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
2023-12-04 09:35:51 +05:30
ruthra kumar
8c9f4c8700 Merge pull request #38527 from frappe/mergify/bp/version-14-hotfix/pr-38525
fix: multiple minor fixes in report and Exchange Rate Revaluation (backport #38525)
2023-12-03 17:04:10 +05:30
ruthra kumar
419943a9d9 fix: remove hardcoded, implicit rounding loss allowance
(cherry picked from commit 64266c4d38)
2023-12-03 11:14:13 +00:00
ruthra kumar
eee9062814 fix: item group filter in sales person wise report
(cherry picked from commit f4d418ea6d)
2023-12-03 11:14:12 +00:00
mergify[bot]
6db63c971e fix: better overlap logic for job card (backport #38432) (#38521)
* fix: better overlap logic for job card (#38432)

(cherry picked from commit 74eab91042)

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

* chore: fix conflicts

* chore: fixed existing_time_logs not defined

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-12-03 15:15:30 +05:30
mergify[bot]
b88c7d63de fix: don't update previous doc on rate change (backport #38493) (#38523)
fix: don't update previous doc on rate change

(cherry picked from commit 68f5dd3e7b)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-12-03 14:02:59 +05:30
mergify[bot]
9345334196 fix: don't consider cancelled entries (#38401)
* fix: don't consider cancelled entries

(cherry picked from commit adfcdb3b65)

* refactor: get outstanding journal entry using query builder

(cherry picked from commit ff27cccff4)

---------

Co-authored-by: Devin Slauenwhite <devin.slauenwhite@gmail.com>
2023-12-02 20:06:48 +05:30
Deepesh Garg
ae285f3417 Merge pull request #38422 from frappe/mergify/bp/version-14-hotfix/pr-38250
fix: unset discount amount based on coupon code (#38250)
2023-12-02 19:42:24 +05:30
mergify[bot]
b813964ee3 chore: changed sort_order to DESC for customer (backport #38498) (#38500)
chore: changed sort_order to DESC for customer (#38498)

(cherry picked from commit 6bc40373f2)

Co-authored-by: Sherin KR <sherinkrply@gmail.com>
2023-12-01 19:09:20 +05:30
ruthra kumar
3f311fcc1e Merge pull request #38485 from frappe/mergify/bp/version-14-hotfix/pr-38440
fix(pe): show split alert only on splitting (backport #38440)
2023-12-01 13:25:47 +05:30
Dany Robert
8d6d74c237 fix(pe): show split alert only on splitting
(cherry picked from commit 96b13c59c1)
2023-12-01 07:10:29 +00:00
mergify[bot]
0df52d2c4f fix: show item name as title instead of item group in BOM (backport #38478) (#38480)
fix: show item name as title instead of item group in BOM (#38478)

Item fields in BOM used to show Item Group when Items were set to show title as link fields. Now they show Item Name instead

(cherry picked from commit 3a66aefd2c)

Co-authored-by: Gughan Ravikumar <gughanrk@gmail.com>
2023-12-01 11:32:49 +05:30
mergify[bot]
497049b3fd fix: incorrect requested quantity for the subcontracting order (backport #38455) (#38471)
* fix: incorrect requested quantity for the subcontracting order

(cherry picked from commit 691e3bb24f)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.py
#	erpnext/subcontracting/doctype/subcontracting_order/subcontracting_order.py
#	erpnext/subcontracting/doctype/subcontracting_order_item/subcontracting_order_item.json
#	erpnext/subcontracting/doctype/subcontracting_order_service_item/subcontracting_order_service_item.json

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2023-11-30 20:53:52 +05:30
mergify[bot]
bec7fb5493 fix(ux): make valuation field read only when it can't be modified (backport #38450) (#38463)
* fix(ux): make `basic_rate` field read-only based on purpose

(cherry picked from commit abc7d30024)

* fix(ux): make PR `rate` field read-only having PO ref

(cherry picked from commit ae294ee470)

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

* fix(ux): make PI `rate` field read-only having PR ref

(cherry picked from commit 3d4156cc7d)

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-30 17:32:58 +05:30
Frappe PR Bot
7b6f25cb9e chore(release): Bumped to Version 14.52.1
## [14.52.1](https://github.com/frappe/erpnext/compare/v14.52.0...v14.52.1) (2023-11-30)

### Bug Fixes

* use flt on outstanding on AR/AP summary report ([161b0da](161b0da29a))
2023-11-30 11:36:02 +00:00
ruthra kumar
865288976c Merge pull request #38459 from frappe/mergify/bp/version-14/pr-38457
fix: use flt on outstanding on AR/AP summary report (backport #38457)
2023-11-30 17:04:42 +05:30
ruthra kumar
00347cdc8e Merge pull request #38460 from frappe/mergify/bp/version-14-hotfix/pr-38457
refactor: use flt on outstanding on AR/AP summary report (backport #38457)
2023-11-30 16:52:15 +05:30
ruthra kumar
161b0da29a fix: use flt on outstanding on AR/AP summary report
(cherry picked from commit e4bdd3a28d)
2023-11-30 16:43:58 +05:30
ruthra kumar
b7556f9b30 refactor: use flt on outstanding on AR/AP summary report
(cherry picked from commit e4bdd3a28d)
2023-11-30 16:28:13 +05:30
Gursheen Kaur Anand
2b570ed68c Merge branch 'version-14-hotfix' into mergify/bp/version-14-hotfix/pr-38250 2023-11-30 14:15:12 +05:30
ruthra kumar
d82a123cf8 Merge pull request #38447 from frappe/mergify/bp/version-14-hotfix/pr-38446
refactor: pass on filter to up front outstanding query as well (backport #38446)
2023-11-30 13:18:43 +05:30
ruthra kumar
e8ea6022f0 refactor: pass on filter to upfront outstanding query as well
(cherry picked from commit cfd3230c75)
2023-11-30 07:26:29 +00:00
mergify[bot]
2908d966b6 fix: exploded items in Subcontracting Receipt (backport #38441) (#38444)
* fix: exploded items in Subcontracting Receipt

(cherry picked from commit 62b4a263f8)

# Conflicts:
#	erpnext/subcontracting/doctype/subcontracting_receipt_item/subcontracting_receipt_item.json

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-30 12:15:52 +05:30
mergify[bot]
2dc4b02fc8 fix: use docstatus instead of status (backport #38439) (#38442)
fix: use `docstatus` instead of `status`

(cherry picked from commit 1423b38d50)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-30 12:11:53 +05:30
Deepesh Garg
f9f65a53fb Merge pull request #38430 from frappe/mergify/bp/version-14-hotfix/pr-38429
fix(minor): set capital WIP account before asset tests (#38429)
2023-11-30 08:14:58 +05:30
Gursheen Anand
ecde1d58b5 fix: set cwip account before asset tests
(cherry picked from commit ef8e4191cd)
2023-11-29 13:21:46 +00:00
Gursheen Anand
7fa97fa7b5 fix: unset discount amount based on coupon code
(cherry picked from commit 6518582ed3)

# Conflicts:
#	erpnext/public/js/utils/sales_common.js
2023-11-29 10:25:18 +00:00
rohitwaghchaure
72db68dd39 Merge pull request #38410 from frappe/mergify/bp/version-14-hotfix/pr-38165
fix: make create button translatable (backport #38165)
2023-11-29 13:04:34 +05:30
rohitwaghchaure
d0224cecac Merge pull request #38418 from frappe/mergify/bp/version-14-hotfix/pr-38415
fix: incorrect ordered qty for Subcontracting Order (backport #38415)
2023-11-29 13:03:04 +05:30
mergify[bot]
49296cd5cb fix: OperationalError while selecting Serial No in Warranty Claim (backport #38394) (#38413)
* refactor: use arrow function

(cherry picked from commit 1763824e5f)

* refactor: use DocType `Fetch From` instead of `frm.add_fetch`

(cherry picked from commit 01044ca8e9)

# Conflicts:
#	erpnext/support/doctype/warranty_claim/warranty_claim.json

* refactor: use `frm.set_query` to add filters

(cherry picked from commit 640dfab827)

* refactor: don't use `cur_frm`

(cherry picked from commit 9fadf5f426)

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-29 12:27:03 +05:30
s-aga-r
55e4951445 chore: conflicts 2023-11-29 12:25:16 +05:30
rohitwaghchaure
8e370876cc fix: incorrect ordered qty for Subcontracting Order (#38415)
(cherry picked from commit fddf341f44)

# Conflicts:
#	erpnext/controllers/tests/test_subcontracting_controller.py
2023-11-29 06:52:34 +00:00
Patrick Eissler
c71b31e3b8 fix: make create button translatable (#38165)
* fix: make all create buttons translatable

* style: use double quotes

---------

Co-authored-by: PatrickDenis-stack <77415730+PatrickDenis-stack@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
(cherry picked from commit 8e4b591ea2)
2023-11-29 04:53:26 +00:00
Deepesh Garg
44b11750d3 chore: v14 patch release (#38408)
* feat: shift depreciation for assets [v14] [backport of #38327] (#38404)

feat: shift depreciation for assets

* fix: no fstring in translation (#38381)

fix: no fstring in translation (#38381)

(cherry picked from commit 8f00481c5f)

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

* fix: debit credit mismatch in multi-currecy asset purchase receipt (#38342)

fix: debit credit mismatch in multi-currecy asset purchase receipt (#38342)

* fix: Debit credit mimatch in multicurrecy asset purchase receipt

* test: multi currency purchase receipt

* chore: update init files

* test: roolback

(cherry picked from commit add238c892)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>

* fix(regional): use net figures for sales calc (#38260)

fix(regional): use net figures for sales calc (#38260)

(cherry picked from commit 663bb8726c)

Co-authored-by: Dany Robert <danyrt@wahni.com>

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Dany Robert <danyrt@wahni.com>
2023-11-29 10:20:53 +05:30
mergify[bot]
d337533907 fix(regional): use net figures for sales calc (#38260)
fix(regional): use net figures for sales calc (#38260)

(cherry picked from commit 663bb8726c)

Co-authored-by: Dany Robert <danyrt@wahni.com>
2023-11-29 09:09:08 +05:30
mergify[bot]
fd6a23cf41 fix: debit credit mismatch in multi-currecy asset purchase receipt (#38342)
fix: debit credit mismatch in multi-currecy asset purchase receipt (#38342)

* fix: Debit credit mimatch in multicurrecy asset purchase receipt

* test: multi currency purchase receipt

* chore: update init files

* test: roolback

(cherry picked from commit add238c892)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-11-29 09:07:42 +05:30
mergify[bot]
cec25740ea fix: no fstring in translation (#38381)
fix: no fstring in translation (#38381)

(cherry picked from commit 8f00481c5f)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-11-29 09:06:04 +05:30
Frappe PR Bot
9170ffc371 chore(release): Bumped to Version 14.52.0
# [14.52.0](https://github.com/frappe/erpnext/compare/v14.51.0...v14.52.0) (2023-11-29)

### Features

* shift depreciation for assets [v14] [backport of [#38327](https://github.com/frappe/erpnext/issues/38327)] ([#38404](https://github.com/frappe/erpnext/issues/38404)) ([53d083a](53d083a121))
2023-11-29 00:48:28 +00:00
Anand Baburajan
6c805fff15 Merge pull request #38405 from frappe/mergify/bp/version-14/pr-38404
feat: shift depreciation for assets [v14] [backport of #38327] (backport #38404)
2023-11-29 06:16:47 +05:30
Anand Baburajan
53d083a121 feat: shift depreciation for assets [v14] [backport of #38327] (#38404)
feat: shift depreciation for assets
(cherry picked from commit d8c3935e64)
2023-11-29 00:46:14 +00:00
Anand Baburajan
d8c3935e64 feat: shift depreciation for assets [v14] [backport of #38327] (#38404)
feat: shift depreciation for assets
2023-11-29 06:15:22 +05:30
Frappe PR Bot
47d37aa628 chore(release): Bumped to Version 14.51.0
# [14.51.0](https://github.com/frappe/erpnext/compare/v14.50.0...v14.51.0) (2023-11-28)

### Bug Fixes

* Alert message and make sure invoice due dates are different for effective test ([0813f02](0813f02ca5))
* allow on submit for child table fields ([d72fbe9](d72fbe9125))
* annual income and expenses in digest ([7dce68b](7dce68bdcc))
* check reposting settings before allowing editable si ([f777d24](f777d24679))
* condition in other bundle utils ([e96ef73](e96ef7338e))
* create contact if existing customer doesn't have contact ([bb2aa90](bb2aa904b2))
* do not set repost flag without validating voucher ([3ad6d08](3ad6d0890a))
* filter bundle items based on disabled check ([8a3a068](8a3a0688ba))
* fiscal year using future date ([b0aa4ef](b0aa4efd3d))
* has_product_bundle util to only check for enabled bundles ([fd19ac5](fd19ac55e3))
* job card overlap validation (backport [#38345](https://github.com/frappe/erpnext/issues/38345)) ([#38347](https://github.com/frappe/erpnext/issues/38347)) ([9cf8955](9cf8955d24))
* Merge conflicts ([e7183e3](e7183e3ea9))
* Negative Qty and Rates in SO/PO ([#38253](https://github.com/frappe/erpnext/issues/38253)) ([50f3b01](50f3b01eb7))
* Payment Reco Issue and chart of account importer ([730a3bb](730a3bb7ce))
* Re-add no.of rows split in alert message ([fb19e7f](fb19e7f15e))
* **regional:** item wise tax calc issue ([0448d56](0448d56a4f))
* Server Error while creating Product Bundle (backport [#38377](https://github.com/frappe/erpnext/issues/38377)) ([#38379](https://github.com/frappe/erpnext/issues/38379)) ([ca6a788](ca6a78882c))
* skip disabled bundles for non-report utils ([445e9c9](445e9c9041))
* skip fixed assets in parent ([5dcd806](5dcd806176))
* stock availability not showing ([#38382](https://github.com/frappe/erpnext/issues/38382)) ([3929cc3](3929cc30ca))
* validation for existing bundles ([ae960e7](ae960e735a))

### Features

* add disabled field in product bundle ([8d5efc9](8d5efc901d))
* new Report "Lost Quotations" ([#38309](https://github.com/frappe/erpnext/issues/38309)) ([1773e31](1773e31499))
2023-11-28 16:24:55 +00:00
rohitwaghchaure
6260241c55 Merge pull request #38384 from frappe/version-14-hotfix
chore: release v14
2023-11-28 21:53:33 +05:30
Shariq Ansari
6871331ff3 Merge pull request #38399 from frappe/mergify/bp/version-14-hotfix/pr-38398
fix(CRM): create contact if existing customer doesn't have contact (backport #38398)
2023-11-28 20:45:08 +05:30
Shariq Ansari
bb2aa904b2 fix: create contact if existing customer doesn't have contact
(cherry picked from commit 23b0b8ba36)
2023-11-28 14:19:59 +00:00
mergify[bot]
e490bd7785 refactor(Translations): prisoner exchange with HRMS (backport #37376) (#37403)
* refactor: migrate translations to HRMS

* chore: resolve conflicts

* style: remove whitespace

To make the linter happy

---------

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2023-11-28 17:50:28 +05:30
mergify[bot]
ca6a78882c fix: Server Error while creating Product Bundle (backport #38377) (#38379)
* fix: product bundle search input

(cherry picked from commit 729fc738af)

* fix: don't select all fields

(cherry picked from commit 8c3713b649)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-28 15:26:36 +05:30
Raffael Meyer
321ac4c5f0 style: remove whitespace (#38388)
To make the linter happy
2023-11-28 15:22:35 +05:30
rohitwaghchaure
3929cc30ca fix: stock availability not showing (#38382)
fix: stock availability now showing
2023-11-28 15:16:35 +05:30
mergify[bot]
25f67923ea chore: fix flaky test case (backport #38369) (#38372)
chore: fix flaky test case (#38369)

(cherry picked from commit ad3634be7c)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-28 08:36:46 +05:30
ruthra kumar
5dc7faba0c Merge pull request #38358 from frappe/mergify/bp/version-14-hotfix/pr-38354
refactor: handle rounding loss on AR/AP reports (backport #38354)
2023-11-27 12:16:27 +05:30
ruthra kumar
2aa9171027 refactor: handle rounding loss on AR/AP reports
(cherry picked from commit 592ce45da7)
2023-11-27 06:22:44 +00:00
mergify[bot]
730a3bb7ce fix: Payment Reco Issue and chart of account importer
fix: Payment Reco Issue and chart of account importer
2023-11-27 10:30:46 +05:30
ruthra kumar
e9a2b002d8 Merge pull request #38355 from frappe/mergify/bp/version-14-hotfix/pr-38081
fix: check reposting ledger settings before setting repost flag (backport #38081)
2023-11-27 09:28:59 +05:30
ruthra kumar
faf025454f chore: resolve conflict 2023-11-27 09:08:23 +05:30
Marica
50f3b01eb7 fix: Negative Qty and Rates in SO/PO (#38253)
* fix: Don't allow negative qty in SO/PO

* fix: Type casting for safe comparisons

* fix: Grammar in error message

* fix: Negative rates should be allowed via Update Items in SO/PO

* fix: Use `non_negative` property in docfield & emove code validation
2023-11-27 09:06:27 +05:30
Gursheen Anand
f777d24679 fix: check reposting settings before allowing editable si
(cherry picked from commit 894ae1fe0f)
2023-11-27 03:35:38 +00:00
Gursheen Anand
d72fbe9125 fix: allow on submit for child table fields
(cherry picked from commit 5fae2f6d57)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
2023-11-27 03:35:37 +00:00
Gursheen Anand
3ad6d0890a fix: do not set repost flag without validating voucher
(cherry picked from commit ad5edbb1de)
2023-11-27 03:35:37 +00:00
Gursheen Anand
776c884403 refactor: validate reposting settings for editables inv
(cherry picked from commit 780b827adc)
2023-11-27 03:35:37 +00:00
mergify[bot]
a4b5fc8100 refactor: bank transaction (#38182)
refactor: bank transaction (#38182)

(cherry picked from commit 5426b93387)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2023-11-26 18:58:04 +05:30
Deepesh Garg
b0547b5619 Merge pull request #38074 from frappe/mergify/bp/version-14-hotfix/pr-37859
fix: `split_invoices_based_on_payment_terms` (#37859)
2023-11-26 18:15:11 +05:30
mergify[bot]
9cf8955d24 fix: job card overlap validation (backport #38345) (#38347)
* fix: job card overlap validation (#38345)

(cherry picked from commit d8245cef72)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-26 17:44:02 +05:30
Deepesh Garg
f7c820ffad Merge pull request #38331 from frappe/mergify/bp/version-14-hotfix/pr-38309
feat: new Report "Lost Quotations" (#38309)
2023-11-25 17:36:27 +05:30
Raffael Meyer
1773e31499 feat: new Report "Lost Quotations" (#38309)
(cherry picked from commit 477d9fa87e)
2023-11-24 21:27:50 +00:00
Deepesh Garg
466d0849e8 Merge pull request #38313 from frappe/mergify/bp/version-14-hotfix/pr-36797
fix(regional): item wise tax calc issue (#36797)
2023-11-24 16:31:03 +05:30
Deepesh Garg
28b6afcb10 Merge pull request #38315 from frappe/mergify/bp/version-14-hotfix/pr-38269
fix: skip fixed assets in product bundle (#38269)
2023-11-24 16:30:05 +05:30
Deepesh Garg
bdde30a456 Merge pull request #38324 from frappe/mergify/bp/version-14-hotfix/pr-38273
fix: annual income and expenses in email digest (#38273)
2023-11-24 16:29:16 +05:30
Gursheen Kaur Anand
aea169d4d4 chore: resolve conflicts 2023-11-24 15:30:19 +05:30
Gursheen Anand
b0aa4efd3d fix: fiscal year using future date
(cherry picked from commit 728cc9f725)
2023-11-24 09:51:29 +00:00
Gursheen Anand
7dce68bdcc fix: annual income and expenses in digest
(cherry picked from commit 52305e3000)

# Conflicts:
#	erpnext/accounts/utils.py
2023-11-24 09:51:29 +00:00
Frappe PR Bot
436ba6f244 chore(release): Bumped to Version 14.50.0
# [14.50.0](https://github.com/frappe/erpnext/compare/v14.49.0...v14.50.0) (2023-11-24)

### Bug Fixes

* don't depreciate non-depreciable assets on scrapping [v14] ([#38294](https://github.com/frappe/erpnext/issues/38294)) ([5261aba](5261aba81f))
* partial cancel of gle and ple (backport [#35609](https://github.com/frappe/erpnext/issues/35609)) ([80bc235](80bc235d6e))
* patch - Duplicate entry quality inspection parameter (backport [#38262](https://github.com/frappe/erpnext/issues/38262)) ([#38263](https://github.com/frappe/erpnext/issues/38263)) ([756f08b](756f08b9ba))
* Supplier `Primary Contact` (backport [#38268](https://github.com/frappe/erpnext/issues/38268)) ([#38285](https://github.com/frappe/erpnext/issues/38285)) ([f170cb9](f170cb9214))

### Features

* add Bank Transaction to connections in Journal and Payment Entry ([#38297](https://github.com/frappe/erpnext/issues/38297)) ([06c6da5](06c6da5c0d))

### Performance Improvements

* optimize total_purchase_cost update ([a88d322](a88d322e4f))
2023-11-24 08:47:31 +00:00
ruthra kumar
79ded4bf19 Merge pull request #38320 from ruthra-kumar/version-14
chore: release v14
2023-11-24 14:16:16 +05:30
ruthra kumar
5af23e760c Merge branch 'version-14-hotfix' into version-14 2023-11-24 13:26:25 +05:30
ruthra kumar
7601861f21 Merge pull request #38318 from frappe/mergify/bp/version-14-hotfix/pr-38298
perf: optimize update_purchase_cost method  (backport #38298)
2023-11-24 12:20:57 +05:30
ruthra kumar
1d1af26f7a chore: resolve conflict 2023-11-24 11:54:55 +05:30
ruthra kumar
47093bebd3 refactor: update project costing based on frequency
(cherry picked from commit dd016e6ced)
2023-11-24 06:20:04 +00:00
ruthra kumar
205d971253 refactor: make update_project_cost optional through Buying Settings
(cherry picked from commit 0fe6dcd742)
2023-11-24 06:20:04 +00:00
ruthra kumar
49a787b1a8 refactor: provide UI button to recalculate when needed
(cherry picked from commit bcbe6c4a53)

# Conflicts:
#	erpnext/projects/doctype/project/project.py
2023-11-24 06:20:04 +00:00
ruthra kumar
a88d322e4f perf: optimize total_purchase_cost update
(cherry picked from commit aa17110bde)
2023-11-24 06:20:02 +00:00
Deepesh Garg
dfdaad0111 Merge pull request #38300 from frappe/mergify/bp/version-14-hotfix/pr-38297
feat: add Bank Transaction to connections in Journal and Payment Entry (#38297)
2023-11-24 10:06:59 +05:30
ruthra kumar
d80e8c6b15 Merge pull request #38311 from frappe/mergify/bp/version-14-hotfix/pr-38296
chore: index to speed up basic submit/cancel functions on purchase invoice (backport #38296)
2023-11-24 10:04:59 +05:30
Gursheen Anand
d7d5317b0e chore: linting issues
(cherry picked from commit 1657337887)
2023-11-24 04:30:38 +00:00
Gursheen Anand
445e9c9041 fix: skip disabled bundles for non-report utils
(cherry picked from commit 362f377f61)
2023-11-24 04:30:38 +00:00
Gursheen Anand
e96ef7338e fix: condition in other bundle utils
(cherry picked from commit 8bdb61cb87)
2023-11-24 04:30:38 +00:00
Gursheen Anand
ae960e735a fix: validation for existing bundles
(cherry picked from commit 67f43d37df)
2023-11-24 04:30:38 +00:00
Gursheen Anand
fd19ac55e3 fix: has_product_bundle util to only check for enabled bundles
(cherry picked from commit 3543f86c63)
2023-11-24 04:30:38 +00:00
Gursheen Anand
8a3a0688ba fix: filter bundle items based on disabled check
(cherry picked from commit 874774fe6c)
2023-11-24 04:30:37 +00:00
Gursheen Anand
8d5efc901d feat: add disabled field in product bundle
(cherry picked from commit ee76af7681)
2023-11-24 04:30:37 +00:00
Gursheen Anand
5dcd806176 fix: skip fixed assets in parent
(cherry picked from commit f9713eeb56)
2023-11-24 04:30:36 +00:00
Dany Robert
0448d56a4f fix(regional): item wise tax calc issue
(cherry picked from commit 89ddf3272e)
2023-11-24 04:28:23 +00:00
ruthra kumar
f74132b0be chore: speed up Purchase Invoice cancellation
(cherry picked from commit 1efff268b0)
2023-11-24 04:16:22 +00:00
ruthra kumar
6353deacf0 chore: index to speed up queries on JE child table reference
(cherry picked from commit 24fcd67f8b)
2023-11-24 04:16:21 +00:00
mergify[bot]
756f08b9ba fix: patch - Duplicate entry quality inspection parameter (backport #38262) (#38263)
fix: patch - Duplicate entry quality inspection parameter (#38262)

(cherry picked from commit 0ca7527f7a)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-23 22:39:14 +05:30
Raffael Meyer
2293696ab4 chore: resolve conflicts 2023-11-23 15:10:29 +01:00
Raffael Meyer
06c6da5c0d feat: add Bank Transaction to connections in Journal and Payment Entry (#38297)
* feat(Payment Entry): Bank Transaction connection

* feat(Journal Entry): Bank Transaction connection

(cherry picked from commit 3be345e605)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.json
2023-11-23 13:03:38 +00:00
Anand Baburajan
5261aba81f fix: don't depreciate non-depreciable assets on scrapping [v14] (#38294)
fix: don't depreciate non-depreciable assets on scrapping
2023-11-23 14:15:40 +05:30
mergify[bot]
f170cb9214 fix: Supplier Primary Contact (backport #38268) (#38285)
fix: Supplier `Primary Contact`

(cherry picked from commit 627165dc7c)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-23 11:45:57 +05:30
ruthra kumar
8055773425 Merge pull request #38281 from frappe/mergify/bp/version-14-hotfix/pr-38258
refactor: rename 'Unreconcile Payments' doctype to singular 'Unreconcile Payment' (backport #38258)
2023-11-23 11:09:11 +05:30
ruthra kumar
82fa58d4e3 chore: update new unreconcile doctype name in JS and PY files
(cherry picked from commit 74f9e34182)
2023-11-23 05:09:23 +00:00
ruthra kumar
57c6d616e6 chore: rename 'unreconcile payments' to 'unreconcile payment'
(cherry picked from commit 9006c9b747)
2023-11-23 05:09:23 +00:00
ruthra kumar
639512a7c2 Merge pull request #38279 from frappe/mergify/bp/version-14-hotfix/pr-38257
refactor: optmize outstanding amount query (backport #38257)
2023-11-23 10:16:11 +05:30
ruthra kumar
ac13e7362c refactor: optimize outstanding vouchers query
(cherry picked from commit 8b04c1d4f6)
2023-11-23 04:12:42 +00:00
Marica
1e7dfd3071 Merge branch 'version-14-hotfix' into mergify/bp/version-14-hotfix/pr-37859 2023-11-22 20:51:30 +05:30
marination
e7183e3ea9 fix: Merge conflicts 2023-11-22 16:16:37 +01:00
ruthra kumar
c4e57040b7 Merge pull request #38205 from vorasmit/partial-cancel
fix: partial cancel of gle and ple (backport #35609)
2023-11-22 10:27:05 +05:30
Smit Vora
c1a7d614a2 test: partial cancel for gl entries reversal 2023-11-22 10:07:38 +05:30
Frappe PR Bot
7392f9c662 chore(release): Bumped to Version 14.49.0
# [14.49.0](https://github.com/frappe/erpnext/compare/v14.48.1...v14.49.0) (2023-11-22)

### Bug Fixes

* add revaluation journal filter in Payable report ([d0698b3](d0698b32bb))
* attributes were mandatory for manufacturers ([430980a](430980a836))
* duplicate field in `Closing Stock Balance` ([#38105](https://github.com/frappe/erpnext/issues/38105)) ([1f16c47](1f16c47a2c))
* incorrect incoming rate for serial and batch items in standalone debit note ([#38121](https://github.com/frappe/erpnext/issues/38121)) ([9a34518](9a34518e54))
* pass check permission in render_address ([1ccd5e4](1ccd5e4ff5))
* payment entry rounding error ([49735bc](49735bc120))
* remove ESS role when not mapped to employee (backport [#37867](https://github.com/frappe/erpnext/issues/37867)) ([#38132](https://github.com/frappe/erpnext/issues/38132)) ([bc01007](bc01007c16))
* round `unreconciled_amount` before asserting ([392ee2e](392ee2e0fd))
* set asset's valuation_rate according to asset quantity (backport [#38254](https://github.com/frappe/erpnext/issues/38254)) ([#38255](https://github.com/frappe/erpnext/issues/38255)) ([00def82](00def82843))
* set default asset quantity as 1 [v14] ([#38224](https://github.com/frappe/erpnext/issues/38224)) ([3daf6f8](3daf6f822a))
* show party values when naming by is not naming series ([dd76695](dd76695d3a))
* Supplier Quotation fields ([#37963](https://github.com/frappe/erpnext/issues/37963)) ([883eaee](883eaee014))
* test case for rounded total with cash disc ([9b5185a](9b5185adc9))
* **Timesheet:** reset billing hours equal to hours if they exceed actual hours (backport [#38134](https://github.com/frappe/erpnext/issues/38134)) ([#38152](https://github.com/frappe/erpnext/issues/38152)) ([c7c751e](c7c751ecd0))
* **Timesheet:** warn user if billing hours > actual hours instead of resetting  (backport [#38239](https://github.com/frappe/erpnext/issues/38239)) ([#38240](https://github.com/frappe/erpnext/issues/38240)) ([e08f114](e08f1145c9))
* update modified timestamp ([2849e0d](2849e0daed))
* valuation rate in report Item Prices ([#38161](https://github.com/frappe/erpnext/issues/38161)) ([a70696e](a70696ea77))
* wrong round off and rounded total ([296433a](296433a1dd))

### Features

* add `Supplier Delivery Note` field in SCR (backport [#38127](https://github.com/frappe/erpnext/issues/38127)) ([#38155](https://github.com/frappe/erpnext/issues/38155)) ([8d4a19c](8d4a19cecf))
* Add accounting dimensions to Supplier Quotation ([51e33e1](51e33e1556))
* virtual parent doctype ([8dbf2ce](8dbf2ced79))
2023-11-22 04:16:31 +00:00
Deepesh Garg
aa6ef76043 Merge pull request #38247 from frappe/version-14-hotfix
chore: release v14
2023-11-22 09:43:45 +05:30
Deepesh Garg
f6f5ff0be9 Merge branch 'version-14' into version-14-hotfix 2023-11-22 00:28:38 +05:30
mergify[bot]
00def82843 fix: set asset's valuation_rate according to asset quantity (backport #38254) (#38255)
fix: set asset's valuation_rate according to asset quantity (#38254)

(cherry picked from commit e2bb4e2baa)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-11-21 22:53:31 +05:30
mergify[bot]
e08f1145c9 fix(Timesheet): warn user if billing hours > actual hours instead of resetting (backport #38239) (#38240)
fix(Timesheet): warn user if billing hours > actual hours instead of resetting  (#38239)

* revert: "fix(Timesheet): reset billing hours equal to hours if they exceed actual hours"

This reverts commit 0ec8034507.

* fix: warn user if billing hours > actual hours

(cherry picked from commit ac91030b31)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2023-11-21 13:41:08 +05:30
ruthra kumar
ddf82cf433 Merge pull request #38235 from frappe/mergify/bp/version-14-hotfix/pr-38234
test: prevent rounding loss based validation error (backport #38234)
2023-11-21 12:30:34 +05:30
ruthra kumar
59a5e132fe test: prevent rounding loss based validation error
(cherry picked from commit 56e991b7f4)
2023-11-21 06:41:36 +00:00
ruthra kumar
7fc7105c48 Merge pull request #38217 from rtdany10/payment-reco-rounding-issue
fix: round `unreconciled_amount` before asserting
2023-11-21 11:33:42 +05:30
Anand Baburajan
3daf6f822a fix: set default asset quantity as 1 [v14] (#38224)
fix: set default asset quantity as 1
2023-11-20 22:27:25 +05:30
ruthra kumar
d7278477d6 Merge pull request #38213 from frappe/mergify/bp/version-14-hotfix/pr-38210
refactor: extend billed amount update flag to POS Invoice as well (backport #38210)
2023-11-20 15:02:44 +05:30
ruthra kumar
d0571530eb Merge pull request #38215 from frappe/mergify/bp/version-14-hotfix/pr-38212
refactor: update scheduled job for bulk transaction (backport #38212)
2023-11-20 14:49:10 +05:30
Dany Robert
392ee2e0fd fix: round unreconciled_amount before asserting 2023-11-20 14:36:58 +05:30
ruthra kumar
562a55122b refactor: update scheduled job for bulk transaction
(cherry picked from commit fb06ad7330)
2023-11-20 08:51:08 +00:00
ruthra kumar
b226adeb2f Merge pull request #38150 from frappe/mergify/bp/version-14-hotfix/pr-38038
refactor: supercharge Bulk actions (backport #38038)
2023-11-20 14:16:27 +05:30
ruthra kumar
12f027b3f4 chore: resolve conflict 2023-11-20 14:15:33 +05:30
ruthra kumar
9f8aa7c59d refactor: add flag to POS Invoice
(cherry picked from commit 83a13e22b7)

# Conflicts:
#	erpnext/accounts/doctype/pos_invoice/pos_invoice.json
2023-11-20 08:36:52 +00:00
ruthra kumar
40f904391e refactor: set default for 'update_billed_amount_in_delivery_note'
(cherry picked from commit ee0c64215d)
2023-11-20 08:36:51 +00:00
ruthra kumar
bfb85527dc Merge pull request #38196 from frappe/mergify/bp/version-14-hotfix/pr-38159
refactor: provision to truncate `remarks` in General Ledger and Accounts Receivable/Payable reports (backport #38159)
2023-11-20 13:30:39 +05:30
ruthra kumar
b868e2bd5b chore: resolve conflicts 2023-11-20 12:33:51 +05:30
Sagar Vora
b7e74b479f Merge pull request #38198 from frappe/mergify/bp/version-14-hotfix/pr-37963
fix: Supplier Quotation fields (backport #37963)
2023-11-20 11:46:25 +05:30
Sagar Vora
7c92ecdc9d chore: resolve conflicts 2023-11-20 11:39:15 +05:30
Smit Vora
80bc235d6e fix: partial cancel of gle and ple (backport #35609) 2023-11-20 10:56:56 +05:30
Vishakh Desai
883eaee014 fix: Supplier Quotation fields (#37963)
(cherry picked from commit c2bda2c705)

# Conflicts:
#	erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
2023-11-20 04:42:39 +00:00
ruthra kumar
ae319760a0 refactor: add substring logic in ar/ap report
(cherry picked from commit a9bf906545)
2023-11-20 04:38:04 +00:00
ruthra kumar
4e2d0aa892 refactor: provision to set remarks length in accounts settings
(cherry picked from commit 97090ff367)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
2023-11-20 04:38:04 +00:00
Deepesh Garg
5afb8b59c9 Merge pull request #38190 from frappe/mergify/bp/version-14-hotfix/pr-38171
fix: wrong round off and rounded total (#38171)
2023-11-19 19:44:04 +05:30
Deepesh Garg
8136657dfc Merge pull request #38146 from GursheenK/show-party-values-when-naming-series-unset
fix(minor): show party values when naming by is not naming series
2023-11-19 19:23:57 +05:30
Dany Robert
9b5185adc9 fix: test case for rounded total with cash disc
(cherry picked from commit cc60c328fe)
2023-11-19 13:49:06 +00:00
Dany Robert
296433a1dd fix: wrong round off and rounded total
(cherry picked from commit 3a487bd33a)
2023-11-19 13:49:05 +00:00
Deepesh Garg
5033f189f9 Merge pull request #38172 from frappe/mergify/bp/version-14-hotfix/pr-38142
feat: Add accounting dimensions to Supplier Quotation (#38142)
2023-11-19 19:10:39 +05:30
Deepesh Garg
d85185db2e Merge pull request #38175 from frappe/mergify/bp/version-14-hotfix/pr-38163
fix: attributes were mandatory for manufacturers (#38163)
2023-11-19 19:08:46 +05:30
Deepesh Garg
76b6e0407d Merge pull request #38179 from frappe/mergify/bp/version-14-hotfix/pr-38161
fix: valuation rate in report Item Prices (#38161)
2023-11-19 18:47:40 +05:30
Deepesh Garg
2fdc575441 Merge pull request #38181 from pps190/fix-pe-precision-bp
fix: payment entry rounding error (#38177)
2023-11-19 18:47:01 +05:30
Deepesh Garg
7b9afa43ff chore: resolve conflicts 2023-11-19 18:34:47 +05:30
Devin Slauenwhite
49735bc120 fix: payment entry rounding error 2023-11-18 15:09:44 +00:00
Patrick Eissler
a70696ea77 fix: valuation rate in report Item Prices (#38161)
Co-authored-by: PatrickDenis-stack <77415730+PatrickDenis-stack@users.noreply.github.com>
(cherry picked from commit 32f622ef80)
2023-11-18 14:55:12 +00:00
barredterra
2849e0daed fix: update modified timestamp
Was missing in 434c2a1815
2023-11-18 15:44:36 +01:00
Deepesh Garg
da27c0fb2d chore: resolve conflicts 2023-11-18 20:10:28 +05:30
PatrickDenis-stack
430980a836 fix: attributes were mandatory for manufacturers
(cherry picked from commit 434c2a1815)
2023-11-18 14:38:57 +00:00
Deepesh Garg
51e33e1556 feat: Add accounting dimensions to Supplier Quotation
(cherry picked from commit 089da459f7)

# Conflicts:
#	erpnext/buying/doctype/supplier_quotation/supplier_quotation.json
#	erpnext/patches.txt
2023-11-18 14:11:16 +00:00
mergify[bot]
8d4a19cecf feat: add Supplier Delivery Note field in SCR (backport #38127) (#38155)
* feat: add `Supplier Delivery Note` field in SCR

(cherry picked from commit da80e4dbce)

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

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-18 18:53:55 +05:30
s-aga-r
9a34518e54 fix: incorrect incoming rate for serial and batch items in standalone debit note (#38121) 2023-11-18 18:48:25 +05:30
Sagar Vora
39841f9edd Merge pull request #38168 from frappe/mergify/bp/version-14-hotfix/pr-38167
fix: pass check permission in `render_address` (backport #38167)
2023-11-18 17:39:38 +05:30
Vishakh Desai
1ccd5e4ff5 fix: pass check permission in render_address
(cherry picked from commit 45299fe4b3)
2023-11-18 12:08:24 +00:00
Gursheen Kaur Anand
05d514ca8e Merge branch 'version-14-hotfix' into show-party-values-when-naming-series-unset 2023-11-17 20:36:11 +05:30
mergify[bot]
c7c751ecd0 fix(Timesheet): reset billing hours equal to hours if they exceed actual hours (backport #38134) (#38152)
fix(Timesheet): reset billing hours equal to hours if they exceed actual hours (#38134)

(cherry picked from commit 20c6e9fca2)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2023-11-17 18:28:10 +05:30
ruthra kumar
fa1f623801 refactor: raise exception on invalid date
(cherry picked from commit a393a6b76c)
2023-11-17 10:56:24 +00:00
ruthra kumar
8dbe753a25 refactor: update traceback on retry
(cherry picked from commit a52a1b49af)
2023-11-17 10:56:24 +00:00
ruthra kumar
a060000b70 refactor: support list view filters
(cherry picked from commit 93295bf25b)
2023-11-17 10:56:24 +00:00
ruthra kumar
b615cfc540 chore: resolve linting issue
(cherry picked from commit 73639db910)
2023-11-17 10:56:24 +00:00
ruthra kumar
32b6eed691 refactor: rollback for retries and UI alerts
(cherry picked from commit c320288690)
2023-11-17 10:56:23 +00:00
ruthra kumar
ad03008a1a refactor: barebones retry functionality
(cherry picked from commit 0aa1636d04)
2023-11-17 10:56:23 +00:00
ruthra kumar
2ec1a2f862 chore: show retried in list view
(cherry picked from commit 194d70f8a0)
2023-11-17 10:56:23 +00:00
ruthra kumar
f5f48f7480 refactor: add basic functionalities
(cherry picked from commit af35590549)
2023-11-17 10:56:23 +00:00
ruthra kumar
8dbf2ced79 feat: virtual parent doctype
(cherry picked from commit a248b13cc3)
2023-11-17 10:56:22 +00:00
ruthra kumar
b951dbfced chore: make from_doctype readonly
(cherry picked from commit b0dfc936a1)
2023-11-17 10:56:22 +00:00
ruthra kumar
863a200989 chore: add indexes
(cherry picked from commit 73090fa130)
2023-11-17 10:56:22 +00:00
ruthra kumar
8dafe103bd chore: add list view filters
(cherry picked from commit ade09bc709)
2023-11-17 10:56:22 +00:00
ruthra kumar
eda9800c93 refactor: simplify logging logic bulk_transaction
(cherry picked from commit ebd74a4e5b)
2023-11-17 10:56:22 +00:00
ruthra kumar
6d983b5f45 chore: rearrange fields
(cherry picked from commit c4f8f3613f)
2023-11-17 10:56:21 +00:00
ruthra kumar
65614497ed chore: convert child to normal table
(cherry picked from commit e5a8ad54e2)
2023-11-17 10:56:21 +00:00
ruthra kumar
785bec98d3 chore: remove 'Bulk Transaction Log' doctype
(cherry picked from commit 815c616f18)
2023-11-17 10:56:21 +00:00
Gursheen Kaur Anand
6b08aa2198 Merge branch 'version-14-hotfix' into show-party-values-when-naming-series-unset 2023-11-17 14:21:52 +05:30
Gursheen Anand
dd76695d3a fix: show party values when naming by is not naming series 2023-11-17 12:50:08 +05:30
Frappe PR Bot
236a064cd3 chore(release): Bumped to Version 14.48.1
## [14.48.1](https://github.com/frappe/erpnext/compare/v14.48.0...v14.48.1) (2023-11-17)

### Bug Fixes

* add revaluation journal filter in Payable report ([4eb37cc](4eb37cce26))
2023-11-17 04:38:02 +00:00
ruthra kumar
dd685e50df Merge pull request #38140 from frappe/mergify/bp/version-14/pr-38119
fix: add revaluation journal filter in Payable report (backport #38119)
2023-11-17 10:06:30 +05:30
ruthra kumar
85853295c4 Merge pull request #38138 from frappe/mergify/bp/version-14-hotfix/pr-38119
fix: add revaluation journal filter in Payable report (backport #38119)
2023-11-17 10:04:51 +05:30
ruthra kumar
4eb37cce26 fix: add revaluation journal filter in Payable report
(cherry picked from commit 134201794a)
2023-11-17 10:03:24 +05:30
ruthra kumar
d0698b32bb fix: add revaluation journal filter in Payable report
(cherry picked from commit 134201794a)
2023-11-17 10:02:13 +05:30
mergify[bot]
bc01007c16 fix: remove ESS role when not mapped to employee (backport #37867) (#38132)
fix: remove ESS role when not mapped to employee (#37867)

* fix: remove ESS role when not mapped to employee

* fix: emp role removal on unlinking

* fix: test case for user employee role mapping

* fix: mapped employee and user on creation

(cherry picked from commit 56b8d1b927)

Co-authored-by: Dany Robert <danyrt@wahni.com>
2023-11-16 20:27:53 +05:30
Anand Baburajan
fb2ca3e172 Merge pull request #38114 from frappe/mergify/bp/version-14/pr-38112
chore: change read only condition of asset quantity field (backport #38111) (backport #38112)
2023-11-15 18:03:01 +05:30
mergify[bot]
7d66cb2195 chore: change read only condition of asset quantity field (backport #38111) (#38112)
chore: change read only condition of asset quantity field (#38111)

chore: change read only condition of asset quantity
(cherry picked from commit 6e0362dee8)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
(cherry picked from commit 58cb4303ee)
2023-11-15 12:32:19 +00:00
mergify[bot]
58cb4303ee chore: change read only condition of asset quantity field (backport #38111) (#38112)
chore: change read only condition of asset quantity field (#38111)

chore: change read only condition of asset quantity
(cherry picked from commit 6e0362dee8)

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-11-15 18:01:28 +05:30
Deepesh Garg
56c70d300b Merge pull request #38106 from frappe/mergify/bp/version-14-hotfix/pr-38105
fix: duplicate field (#38105)
2023-11-15 13:29:35 +05:30
Arjun
1f16c47a2c fix: duplicate field in Closing Stock Balance (#38105)
(cherry picked from commit 908b21f7fd)
2023-11-15 07:06:34 +00:00
Anand Baburajan
7b14e9d5f6 Merge pull request #38100 from frappe/mergify/bp/version-14/pr-38098
chore: refetch item images on transaction save (backport #38095) (backport #38098)
2023-11-14 20:15:28 +05:30
mergify[bot]
966adfc081 chore: refetch item images on transaction save (backport #38095) (#38098)
* chore: refetch item images on transaction save (#38095)

chore: re fetch item images on transaction save
(cherry picked from commit e93a19ffb5)

# Conflicts:
#	erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
#	erpnext/selling/doctype/quotation_item/quotation_item.json

* chore: fix conflict in pos_invoice_item.json

* chore: fix conflict in sales_invoice_item.json

* chore: fix conflict in quotation_item.json

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
(cherry picked from commit d1a8202624)
2023-11-14 14:43:12 +00:00
mergify[bot]
d1a8202624 chore: refetch item images on transaction save (backport #38095) (#38098)
* chore: refetch item images on transaction save (#38095)

chore: re fetch item images on transaction save
(cherry picked from commit e93a19ffb5)

# Conflicts:
#	erpnext/accounts/doctype/pos_invoice_item/pos_invoice_item.json
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
#	erpnext/selling/doctype/quotation_item/quotation_item.json

* chore: fix conflict in pos_invoice_item.json

* chore: fix conflict in sales_invoice_item.json

* chore: fix conflict in quotation_item.json

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-11-14 20:11:23 +05:30
Frappe PR Bot
7a2df24129 chore(release): Bumped to Version 14.48.0
# [14.48.0](https://github.com/frappe/erpnext/compare/v14.47.4...v14.48.0) (2023-11-14)

### Bug Fixes

* asset depreciation ledger (backport [#37991](https://github.com/frappe/erpnext/issues/37991)) ([#37992](https://github.com/frappe/erpnext/issues/37992)) ([043dc1b](043dc1b14b))
* close `Credit Limit Crossed` dialog (backport [#38052](https://github.com/frappe/erpnext/issues/38052)) ([#38058](https://github.com/frappe/erpnext/issues/38058)) ([6979c3e](6979c3e490))
* COA Importer app related issues ([#37238](https://github.com/frappe/erpnext/issues/37238)) ([57ce73d](57ce73d540))
* german translations of Accounts Settings ([b75aae9](b75aae99ca))
* indentation issue in the Production Plan Summary report (backport [#38019](https://github.com/frappe/erpnext/issues/38019)) ([#38068](https://github.com/frappe/erpnext/issues/38068)) ([c552884](c5528844fd))
* make adjustment entry using stock reconciliation (backport [#37995](https://github.com/frappe/erpnext/issues/37995)) ([#38008](https://github.com/frappe/erpnext/issues/38008)) ([984703c](984703c3c9))
* make item field read-only in batch (backport [#38010](https://github.com/frappe/erpnext/issues/38010)) ([#38033](https://github.com/frappe/erpnext/issues/38033)) ([424ebd1](424ebd154a))
* minor change added to test_case ([6b34568](6b34568128))
* minor issue ([0eab723](0eab723243))
* new logic for handling revaluation journals ([9c0d80c](9c0d80cef4))
* pick serial nos from selected batch only ([#37988](https://github.com/frappe/erpnext/issues/37988)) ([db29180](db29180eec))
* sales order not assigned to territory orders ([#37905](https://github.com/frappe/erpnext/issues/37905)) ([#38024](https://github.com/frappe/erpnext/issues/38024)) ([620f4f2](620f4f2c10))
* Set right party name in bank transaction ([21b430a](21b430a575))
* **translations:** suggestions from review ([4d2169e](4d2169e48e))
* Use `process.extract` to get the corresponding party doc name of the result ([b0a184e](b0a184e937))

### Features

* **accounts_receivable:** test_case added for multi-select customer group ([cf0d936](cf0d936195))
* multi-select customer group in AR Report ([935286f](935286ff94))
2023-11-14 12:57:28 +00:00
Deepesh Garg
ecb116aa99 Merge pull request #38086 from frappe/version-14-hotfix
chore: release v14
2023-11-14 18:25:20 +05:30
mergify[bot]
8446e87cc2 chore: delete comments and unlink attachments on company transactions deletion (backport #38077) (#38078)
* chore: delete comments and unlink attachments on company transactions deletion

(cherry picked from commit 2f9e96e324)

* fix: unrelated transation date typo

(cherry picked from commit b097bb20d9)

---------

Co-authored-by: anandbaburajan <anandbaburajan@gmail.com>
2023-11-13 19:20:52 +05:30
marination
fb19e7f15e fix: Re-add no.of rows split in alert message
(cherry picked from commit 1fc5844025)
2023-11-13 10:46:39 +00:00
marination
c840f30a20 style: Remove spaces introduced via merge conflict
(cherry picked from commit 4b4b176fcf)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/test_payment_entry.py
2023-11-13 10:46:39 +00:00
marination
0813f02ca5 fix: Alert message and make sure invoice due dates are different for effective test
- Make invoice due dates are different so that the invoice with the earliest due date is allocated first in the test
- Translate voucher type, simplify alert message. The invoice could be "split" into 1 row, no. of rows in the message seems unnecessary.

(cherry picked from commit 56ac3424d2)
2023-11-13 10:46:38 +00:00
marination
a7e2867526 test: get_outstanding_reference_documents (triggered via UI)
(cherry picked from commit 162c0497d1)
2023-11-13 10:46:38 +00:00
marination
077f3928cf refactor: split_invoices_based_on_payment_terms
- Invoices were in the wrong order due to the logic. The invoices with payment terms were added first and the rest after.
- Overly long function with unnecessary loops (reduced to one main loop) and complexity
- The split row as per payment terms was not ordered. So the second installment was allocated first

(cherry picked from commit 6bd56d2d5f)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.py
2023-11-13 10:46:38 +00:00
mergify[bot]
c5528844fd fix: indentation issue in the Production Plan Summary report (backport #38019) (#38068)
fix: indentation issue in the Production Plan Summary report (#38019)

fix: Production Plan Summary report
(cherry picked from commit 4a111f7362)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-13 14:03:45 +05:30
ruthra kumar
55885e84ab Merge pull request #38066 from frappe/mergify/bp/version-14/pr-38064
refactor: add revaluation journal checkbox in AR/AP summary reports (backport #38064)
2023-11-13 12:15:34 +05:30
ruthra kumar
2faf2ce468 Merge pull request #38065 from frappe/mergify/bp/version-14-hotfix/pr-38064
refactor: add revaluation journal checkbox in AR/AP summary reports (backport #38064)
2023-11-13 12:15:27 +05:30
ruthra kumar
7ab18fc434 refactor: add revaluation journal checkbox in AR/AP summary reports
(cherry picked from commit 95edd82638)
2023-11-13 06:39:03 +00:00
ruthra kumar
a104a4bca6 refactor: add revaluation journal checkbox in AR/AP summary reports
(cherry picked from commit 95edd82638)
2023-11-13 06:38:38 +00:00
mergify[bot]
6979c3e490 fix: close Credit Limit Crossed dialog (backport #38052) (#38058)
fix: close `Credit Limit Crossed` dialog (#38052)

(cherry picked from commit 94faa44697)

Co-authored-by: Arjun <arjun99c@gmail.com>
2023-11-12 18:07:31 +05:30
mergify[bot]
57ce73d540 fix: COA Importer app related issues (#37238)
fix: COA Importer app related issues (#37238)

* fix: COA Importer app related issues

* fix: Clear all account links fields befor import

* fix: Attribute error

(cherry picked from commit 8634abc021)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-11-12 17:40:56 +05:30
mergify[bot]
424ebd154a fix: make item field read-only in batch (backport #38010) (#38033)
* fix: make item field read-only in batch

(cherry picked from commit 779260fb49)

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

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-11 10:51:36 +05:30
Frappe PR Bot
7c7dc5328e chore(release): Bumped to Version 14.47.4
## [14.47.4](https://github.com/frappe/erpnext/compare/v14.47.3...v14.47.4) (2023-11-10)

### Bug Fixes

* new logic for handling revaluation journals ([010ccf8](010ccf80f5))
2023-11-10 07:46:10 +00:00
ruthra kumar
cb655226de Merge pull request #38037 from frappe/mergify/bp/version-14/pr-38004
fix: handling of exchange rate journals in AR/AP (backport #38004)
2023-11-10 13:14:45 +05:30
ruthra kumar
010ccf80f5 fix: new logic for handling revaluation journals
(cherry picked from commit 1d8fcd66e6)
2023-11-10 12:05:46 +05:30
ruthra kumar
13ea910fa6 Merge pull request #38035 from frappe/mergify/bp/version-14-hotfix/pr-38004
fix: handling of exchange rate journals in AR/AP (backport #38004)
2023-11-10 11:59:03 +05:30
ruthra kumar
9c0d80cef4 fix: new logic for handling revaluation journals
(cherry picked from commit 1d8fcd66e6)
2023-11-10 11:17:46 +05:30
mergify[bot]
620f4f2c10 fix: sales order not assigned to territory orders (#37905) (#38024)
fix: sales order not assigned to territory orders (#37905)

filtered sales order are not assigned to 'territory_orders' which results in 0 order amount and 0 billing amount in the output

(cherry picked from commit 45b4bfc947)

Co-authored-by: jabir-elat <44110258+jabir-elat@users.noreply.github.com>
2023-11-09 21:52:43 +05:30
ruthra kumar
89695022c7 Merge pull request #38021 from frappe/mergify/bp/version-14/pr-37860
refactor: ignore disabled account while selecting Income Accounts (backport #37860)
2023-11-09 17:28:14 +05:30
Frappe PR Bot
50627733b4 chore(release): Bumped to Version 14.47.3
## [14.47.3](https://github.com/frappe/erpnext/compare/v14.47.2...v14.47.3) (2023-11-09)

### Bug Fixes

* make adjustment entry using stock reconciliation (backport [#37995](https://github.com/frappe/erpnext/issues/37995)) (backport [#38008](https://github.com/frappe/erpnext/issues/38008)) ([#38018](https://github.com/frappe/erpnext/issues/38018)) ([7942ad4](7942ad488e))
2023-11-09 11:24:29 +00:00
mergify[bot]
7942ad488e fix: make adjustment entry using stock reconciliation (backport #37995) (backport #38008) (#38018)
fix: make adjustment entry using stock reconciliation (backport #37995) (#38008)

* fix: make adjustment entry using stock reconciliation (#37995)

fix: do adjustment entry using stock reconciliation
(cherry picked from commit a8216b9727)

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

* chore: fix conflicts

* fix: conflicts

* chore: fix conflicts

---------

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2023-11-09 16:53:14 +05:30
ruthra kumar
c3d7348c73 refactor: ignore disabled account while selecting Income Accounts
(cherry picked from commit 6e3e094c95)
2023-11-09 11:14:38 +00:00
Deepesh Garg
ad178db28f Merge pull request #38012 from frappe/mergify/bp/version-14-hotfix/pr-37716
feat: multi-select customer group in AR Report (backport #37716)
2023-11-09 14:05:59 +05:30
mergify[bot]
984703c3c9 fix: make adjustment entry using stock reconciliation (backport #37995) (#38008)
* fix: make adjustment entry using stock reconciliation (#37995)

fix: do adjustment entry using stock reconciliation
(cherry picked from commit a8216b9727)

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

* chore: fix conflicts

* fix: conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-09 13:40:14 +05:30
vishal
6b34568128 fix: minor change added to test_case
(cherry picked from commit 30402033bc)
2023-11-09 07:35:16 +00:00
vishal
cf0d936195 feat(accounts_receivable): test_case added for multi-select customer group
(cherry picked from commit de445b32f5)
2023-11-09 07:35:16 +00:00
vishal
0eab723243 fix: minor issue
(cherry picked from commit b60c57a97d)
2023-11-09 07:35:15 +00:00
vishal
935286ff94 feat: multi-select customer group in AR Report
(cherry picked from commit 8903c1bc6f)
2023-11-09 07:35:15 +00:00
Frappe PR Bot
9a2674ea29 chore(release): Bumped to Version 14.47.2
## [14.47.2](https://github.com/frappe/erpnext/compare/v14.47.1...v14.47.2) (2023-11-09)

### Bug Fixes

* pick serial nos from selected batch only (backport [#37988](https://github.com/frappe/erpnext/issues/37988)) ([#38011](https://github.com/frappe/erpnext/issues/38011)) ([0405aae](0405aae4a0))
2023-11-09 07:28:50 +00:00
mergify[bot]
0405aae4a0 fix: pick serial nos from selected batch only (backport #37988) (#38011)
fix: pick serial nos from selected batch only (#37988)

* fix: pick current serial nos from selected batch only

* test: add test case for current qty and current serial nos

(cherry picked from commit db29180eec)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-09 12:57:03 +05:30
s-aga-r
db29180eec fix: pick serial nos from selected batch only (#37988)
* fix: pick current serial nos from selected batch only

* test: add test case for current qty and current serial nos
2023-11-09 12:30:22 +05:30
ruthra kumar
b5bed65d9e Merge pull request #38001 from frappe/mergify/bp/version-14-hotfix/pr-37860
refactor: ignore disabled account while selecting Income Accounts (backport #37860)
2023-11-09 10:41:13 +05:30
ruthra kumar
3f7f5bd8f0 refactor: ignore disabled account while selecting Income Accounts
(cherry picked from commit 6e3e094c95)
2023-11-09 04:45:53 +00:00
Frappe PR Bot
3f433b1b8b chore(release): Bumped to Version 14.47.1
## [14.47.1](https://github.com/frappe/erpnext/compare/v14.47.0...v14.47.1) (2023-11-08)

### Bug Fixes

* asset depreciation ledger (backport [#37991](https://github.com/frappe/erpnext/issues/37991)) ([#37992](https://github.com/frappe/erpnext/issues/37992)) ([0ac78a9](0ac78a96a9))
2023-11-08 18:40:20 +00:00
Anand Baburajan
0532f72cb1 Merge pull request #37996 from frappe/mergify/bp/version-14/pr-37992
fix: asset depreciation ledger (backport #37991) (backport #37992)
2023-11-09 00:09:05 +05:30
mergify[bot]
0ac78a96a9 fix: asset depreciation ledger (backport #37991) (#37992)
* fix: asset depreciation ledger (#37991)

* fix: include opening acc depr while calculating asset depr ledger report

* chore: include opening acc depr properly in acc depr amt

* chore: add cost_center in asset depr ledger report

* fix: handle finance books properly in asset depr ledger report

* chore: rename 'include default book entries' to 'include default FB entries'

(cherry picked from commit 9a171db97f)

# Conflicts:
#	erpnext/accounts/report/balance_sheet/balance_sheet.js
#	erpnext/accounts/report/cash_flow/cash_flow.js
#	erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
#	erpnext/accounts/report/trial_balance/trial_balance.js
#	erpnext/translations/pl.csv
#	erpnext/translations/tr.csv

* chore: fix conflict in balance_sheet.js

* chore: fix conflict in cash_flow.js

* chore: fix conflict in consolidated_financial_statement.js

* chore: fix conflict in trial_balance.js

* chore: fix conflict in tr.csv

* chore: fix conflict in pl.csv

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
(cherry picked from commit 043dc1b14b)
2023-11-08 18:07:42 +00:00
mergify[bot]
043dc1b14b fix: asset depreciation ledger (backport #37991) (#37992)
* fix: asset depreciation ledger (#37991)

* fix: include opening acc depr while calculating asset depr ledger report

* chore: include opening acc depr properly in acc depr amt

* chore: add cost_center in asset depr ledger report

* fix: handle finance books properly in asset depr ledger report

* chore: rename 'include default book entries' to 'include default FB entries'

(cherry picked from commit 9a171db97f)

# Conflicts:
#	erpnext/accounts/report/balance_sheet/balance_sheet.js
#	erpnext/accounts/report/cash_flow/cash_flow.js
#	erpnext/accounts/report/consolidated_financial_statement/consolidated_financial_statement.js
#	erpnext/accounts/report/trial_balance/trial_balance.js
#	erpnext/translations/pl.csv
#	erpnext/translations/tr.csv

* chore: fix conflict in balance_sheet.js

* chore: fix conflict in cash_flow.js

* chore: fix conflict in consolidated_financial_statement.js

* chore: fix conflict in trial_balance.js

* chore: fix conflict in tr.csv

* chore: fix conflict in pl.csv

---------

Co-authored-by: Anand Baburajan <anandbaburajan@gmail.com>
2023-11-08 23:36:17 +05:30
Deepesh Garg
c5a6b17c15 Merge pull request #37825 from frappe/mergify/bp/version-14-hotfix/pr-37278
fix: german translations of Accounts Settings (backport #37278)
2023-11-08 18:44:11 +05:30
Deepesh Garg
16c3f3bcbd Merge pull request #37913 from frappe/mergify/bp/version-14-hotfix/pr-37299
fix: Set right party name in bank transaction (backport #37299)
2023-11-08 12:28:10 +05:30
Frappe PR Bot
4d804951c6 chore(release): Bumped to Version 14.47.0
# [14.47.0](https://github.com/frappe/erpnext/compare/v14.46.7...v14.47.0) (2023-11-08)

### Bug Fixes

* `TypeError` in PR for non-stock item ([ef4471f](ef4471f8c0))
* add missing disbursement account in update_old_loans patch ([ad64065](ad64065ec6))
* add translation wrapper (backport [#37911](https://github.com/frappe/erpnext/issues/37911)) ([#37946](https://github.com/frappe/erpnext/issues/37946)) ([c53d281](c53d281b9e))
* don't reset rate if greater than zero in standalone debit note (backport [#37935](https://github.com/frappe/erpnext/issues/37935)) ([#37940](https://github.com/frappe/erpnext/issues/37940)) ([64658fc](64658fc790))
* fetch asset received but not billed account only when needed ([7df4009](7df4009dd3))
* gov compliance for tax withholding report ([#37590](https://github.com/frappe/erpnext/issues/37590)) ([273cc35](273cc35b91))
* In-Transit Warehouse company filter (backport [#37796](https://github.com/frappe/erpnext/issues/37796)) ([#37797](https://github.com/frappe/erpnext/issues/37797)) ([0b1da08](0b1da08d78))
* link between parent and child procedure (backport [#37903](https://github.com/frappe/erpnext/issues/37903)) ([#37943](https://github.com/frappe/erpnext/issues/37943)) ([24da29a](24da29a817))
* list index out of range ([#37880](https://github.com/frappe/erpnext/issues/37880)) ([05fed9e](05fed9e352))
* make `Material Request Item` required if `Material Request` is set in PO (backport [#37928](https://github.com/frappe/erpnext/issues/37928)) ([#37936](https://github.com/frappe/erpnext/issues/37936)) ([c870120](c87012046d))
* permission error while creating Supplier Quotation from Portal (backport [#37864](https://github.com/frappe/erpnext/issues/37864)) ([#37870](https://github.com/frappe/erpnext/issues/37870)) ([1a3dae0](1a3dae0f9a))
* **plaid:** Do not sync pending transactions ([ffdc11b](ffdc11bbf6))
* POS change amount gl entry with no amount ([#37799](https://github.com/frappe/erpnext/issues/37799)) ([5e1a89b](5e1a89b3f9))
* Quality Inspection Parameter migration - DuplicateEntryError due to case sensitivity (backport [#37499](https://github.com/frappe/erpnext/issues/37499)) ([#37916](https://github.com/frappe/erpnext/issues/37916)) ([eb3630b](eb3630bcf8))
* remove voucher type and no for Item and Warehouse based reposting (backport [#37849](https://github.com/frappe/erpnext/issues/37849)) ([#37850](https://github.com/frappe/erpnext/issues/37850)) ([e19cade](e19cade12d))
* standard submit perm in repost ledger for editable invoices (backport [#37826](https://github.com/frappe/erpnext/issues/37826)) ([#37854](https://github.com/frappe/erpnext/issues/37854)) ([69b569d](69b569df46))
* status for over delivery or billing ([d8e7430](d8e743013f))
* type error on new payment entry ([38184f7](38184f77c7))
* typo in AR report ([3d72ec7](3d72ec7ca4))
* validate so item with qtn ([4a225b0](4a225b069b))

### Features

* reserved production plan sub assembly items (backport [#37884](https://github.com/frappe/erpnext/issues/37884)) ([#37926](https://github.com/frappe/erpnext/issues/37926)) ([4de97a4](4de97a4fcb))
* settings page for repost ([09cde5d](09cde5da08))
* **Stock Balance:** add filters from route (backport [#37836](https://github.com/frappe/erpnext/issues/37836)) ([#37839](https://github.com/frappe/erpnext/issues/37839)) ([e8a706a](e8a706a5ea))

### Performance Improvements

* Add index to supplier invoice field (backport [#37861](https://github.com/frappe/erpnext/issues/37861)) ([#37862](https://github.com/frappe/erpnext/issues/37862)) ([2c93f81](2c93f81d59))
* index return against for purchase invoice (backport [#37881](https://github.com/frappe/erpnext/issues/37881)) ([#37882](https://github.com/frappe/erpnext/issues/37882)) ([fed25fa](fed25fac76))
2023-11-08 06:19:10 +00:00
Deepesh Garg
c5ddb4153a Merge pull request #37965 from frappe/version-14-hotfix
chore: release v14
2023-11-08 11:47:53 +05:30
ruthra kumar
b0ed3c2f0a Merge pull request #37977 from ruthra-kumar/add_voucher_detail_no_to_payment_ledger
refactor: Add voucher_detail_no to payment ledger
2023-11-08 11:23:15 +05:30
ruthra kumar
3f8d58c9c6 refactor: add voucher_detail_no to PLE doctype 2023-11-08 10:53:16 +05:30
ruthra kumar
8a3139f6f5 Merge pull request #37901 from frappe/mergify/bp/version-14-hotfix/pr-37887
chore: performance optimization on payment ledger entry doctype (backport #37887)
2023-11-08 10:48:30 +05:30
ruthra kumar
0b601d8cae chore: performance optimization on payment ledger entry doctype
(cherry picked from commit f14d1eb871)
2023-11-08 10:23:52 +05:30
ruthra kumar
9be71e45b9 Merge pull request #37975 from frappe/mergify/bp/version-14-hotfix/pr-37971
refactor: optimize bulk transaction for speed (backport #37971)
2023-11-08 07:08:42 +05:30
ruthra kumar
e58604a90f refactor: optimize for speed
(cherry picked from commit 416bd400bb)
2023-11-08 01:03:28 +00:00
mergify[bot]
e895bb3a63 chore: typo in Stock Entry enqueue msg (backport #37970) (#37972)
chore: typo in `Stock Entry` enqueue msg

(cherry picked from commit ee60fa940c)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-07 15:57:20 +00:00
ruthra kumar
38a5e6f10b Merge pull request #37967 from frappe/mergify/bp/version-14-hotfix/pr-37954
refactor: expand repost to `Expense Claim` and make it configurable (backport #37954)
2023-11-07 16:24:44 +05:30
ruthra kumar
8f0cf1b7dc chore: resolve conflict 2023-11-07 15:56:35 +05:30
ruthra kumar
3da2597703 refactor: update permissions for repost settings
(cherry picked from commit 10b9570429)
2023-11-07 10:14:36 +00:00
ruthra kumar
82bf726b83 refactor(test): repost test case for purchase invoice
(cherry picked from commit 11c8d9fcf1)
2023-11-07 10:14:35 +00:00
ruthra kumar
7d4dc67b61 refactor: select distinct types
(cherry picked from commit 61705047b0)
2023-11-07 10:14:33 +00:00
ruthra kumar
35f5498913 refactor(test): update repost settings for test cases
(cherry picked from commit ac79b8483f)
2023-11-07 10:14:32 +00:00
ruthra kumar
ed557274d2 refactor: support for expense claim repost
(cherry picked from commit b651b36fff)
2023-11-07 10:14:30 +00:00
ruthra kumar
18e6931d78 refactor: configurable repost settings
(cherry picked from commit 5a068410c6)
2023-11-07 10:14:29 +00:00
ruthra kumar
560a45b343 chore: patch to update default repost settings value
(cherry picked from commit ebb186c8df)

# Conflicts:
#	erpnext/patches.txt
2023-11-07 10:14:28 +00:00
ruthra kumar
09cde5da08 feat: settings page for repost
(cherry picked from commit d582a73795)
2023-11-07 10:14:21 +00:00
ruthra kumar
503c0f33bb Merge pull request #37957 from frappe/mergify/bp/version-14-hotfix/pr-37956
fix: type error on new payment entry (backport #37956)
2023-11-07 12:47:10 +05:30
ruthra kumar
38184f77c7 fix: type error on new payment entry
(cherry picked from commit adff287160)
2023-11-07 12:40:16 +05:30
Frappe PR Bot
449b641560 chore(release): Bumped to Version 14.46.7
## [14.46.7](https://github.com/frappe/erpnext/compare/v14.46.6...v14.46.7) (2023-11-06)

### Bug Fixes

* typo in AR report ([d54e756](d54e756453))
2023-11-06 15:33:32 +00:00
ruthra kumar
3cc5e5591d Merge pull request #37951 from frappe/mergify/bp/version-14/pr-37948
fix: typo in AR report (backport #37948)
2023-11-06 21:00:23 +05:30
ruthra kumar
bc5e01e846 Merge pull request #37949 from frappe/mergify/bp/version-14-hotfix/pr-37948
fix: typo in AR report (backport #37948)
2023-11-06 20:55:22 +05:30
ruthra kumar
d54e756453 fix: typo in AR report
(cherry picked from commit 67e74d03ed)
2023-11-06 15:00:11 +00:00
ruthra kumar
3d72ec7ca4 fix: typo in AR report
(cherry picked from commit 67e74d03ed)
2023-11-06 14:56:44 +00:00
mergify[bot]
c53d281b9e fix: add translation wrapper (backport #37911) (#37946)
fix: add translation wrapper

(cherry picked from commit 8722318081)

Co-authored-by: hyaray <hyaray@vip.qq.com>
2023-11-06 19:52:11 +05:30
mergify[bot]
24da29a817 fix: link between parent and child procedure (backport #37903) (#37943)
* fix: link between parent and child procedure

(cherry picked from commit 05f24ede96)

* chore: add missing filters for `Parent Procedure`

(cherry picked from commit 8fbd4cea5b)

* test: add test case for Quality Procedure`

(cherry picked from commit 30c6b83a10)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-06 19:28:19 +05:30
mergify[bot]
64658fc790 fix: don't reset rate if greater than zero in standalone debit note (backport #37935) (#37940)
* fix: don't reset rate if greater than zero in standalone debit note

(cherry picked from commit 5cce522ecd)

* fix(test): `test_gl_entries_for_standalone_debit_note`

(cherry picked from commit f9fc6c9c9d)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-06 19:27:28 +05:30
mergify[bot]
c87012046d fix: make Material Request Item required if Material Request is set in PO (backport #37928) (#37936)
fix: make `Material Request Item` required if `Material Request` is set in PO

(cherry picked from commit a9d91189b0)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-06 17:26:37 +05:30
mergify[bot]
4de97a4fcb feat: reserved production plan sub assembly items (backport #37884) (#37926)
feat: reserved production plan sub assembly items (#37884)

(cherry picked from commit 34d3eb88b3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2023-11-06 11:40:21 +05:30
ruthra kumar
932d1e7c62 Merge pull request #37924 from frappe/mergify/bp/version-14-hotfix/pr-37879
refactor: flag to toggle billed amy update in DN for Credit Note (backport #37879)
2023-11-06 11:24:08 +05:30
ruthra kumar
71ad448281 refactor(test): enable billed amt update on Sales Return(Cr Note)
(cherry picked from commit 0c5bdbdcf3)
2023-11-06 09:40:32 +05:30
ruthra kumar
6eb867a1e4 refactor: flag to toggle billed amy update in DN for Credit Note
(cherry picked from commit a3191f1c8c)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
2023-11-06 03:11:20 +00:00
mergify[bot]
5e1a89b3f9 fix: POS change amount gl entry with no amount (#37799)
fix: POS change amount gl entry with no amount (#37799)

(cherry picked from commit 2b02ef0066)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-11-05 17:56:19 +05:30
viralkansodiya15
05fed9e352 fix: list index out of range (#37880)
* fix: list index out of range

* fix: changes in error message

* fix: change error message and date comparision

* fix: change a return a value when disposal date is equal to available for use date

* fix: changes to fix linter test failing
2023-11-05 11:54:39 +05:30
mergify[bot]
eb3630bcf8 fix: Quality Inspection Parameter migration - DuplicateEntryError due to case sensitivity (backport #37499) (#37916)
fix: Quality Inspection Parameter migration - DuplicateEntryError due to case sensitivity (#37499)

* fix: account for case-insensitive database primary key for parameter names

* chore: linting

(cherry picked from commit b099590b2c)

Co-authored-by: Richard Case <110036763+casesolved-co-uk@users.noreply.github.com>
2023-11-05 06:16:23 +00:00
ruthra kumar
c2001bec15 Merge pull request #37915 from ruthra-kumar/prevent_precision_based_validation_error_reconciliation
refactor: avoid precision based validation error on reconciliation
2023-11-05 05:58:32 +05:30
ruthra kumar
be925d2d33 refactor: avoid precision based validation error on reconciliation 2023-11-05 05:22:09 +05:30
marination
b0a184e937 fix: Use process.extract to get the corresponding party doc name of the result
- rapidfuzz accepts an iterable or a dict. dict input gives the dict key and value in the result

(cherry picked from commit e0a03789ae)
2023-11-04 15:48:18 +00:00
marination
21b430a575 fix: Set right party name in bank transaction
- If party name and docname are different, set the docname in Bank Transaction

(cherry picked from commit ff1dc72d74)
2023-11-04 15:48:18 +00:00
Anand Baburajan
65dfef021a chore: rename depreciation_amount_based_on_num_days_in_month to daily_prorata_based [v14] (#37898)
chore: rename depreciation_amount_based_on_num_days_in_month to daily_prorata_based
2023-11-03 20:18:20 +00:00
Anand Baburajan
86c6ae6275 chore: rename daily_depreciation in asset to depreciation_amount_based_on_num_days_in_month [v14] (#37895)
chore: rename daily_depreciation to depreciation_amount_based_on_num_days_in_month
2023-11-03 23:26:34 +05:30
mergify[bot]
fed25fac76 perf: index return against for purchase invoice (backport #37881) (#37882)
perf: index return against for purchase invoice (#37881)

(cherry picked from commit 469ae2c7f1)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2023-11-03 21:59:46 +05:30
Anand Baburajan
6b5cffc77a Merge pull request #37889 from anandbaburajan/update_old_loans_disb_account
fix: add missing disbursement account in update_old_loans patch
2023-11-03 21:45:33 +05:30
anandbaburajan
ad64065ec6 fix: add missing disbursement account in update_old_loans patch 2023-11-03 20:57:52 +05:30
mergify[bot]
1a3dae0f9a fix: permission error while creating Supplier Quotation from Portal (backport #37864) (#37870)
* fix: permission error while creating Supplier Quotation from Portal

(cherry picked from commit e019d43d0b)

# Conflicts:
#	erpnext/controllers/buying_controller.py

* chore: `conflicts`

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-03 16:24:36 +05:30
ruthra kumar
15308c9aac Merge pull request #37875 from frappe/mergify/bp/version-14-hotfix/pr-37852
refactor: better ledger comparision report (backport #37852)
2023-11-03 13:25:22 +05:30
ruthra kumar
09ba6c1266 Merge pull request #37873 from frappe/mergify/bp/version-14-hotfix/pr-37869
refactor: 'group only by voucher' flag in AR/AP report (backport #37869)
2023-11-03 13:25:04 +05:30
ruthra kumar
afa6ed9e22 refactor(test): for ledger comparision report
(cherry picked from commit 639f427d6d)
2023-11-03 07:22:59 +00:00
ruthra kumar
3d2ff7eea3 refactor: better output on gl and pl comparison report
(cherry picked from commit 539f0251d9)
2023-11-03 07:22:58 +00:00
ruthra kumar
ee5898a773 refactor: group only by voucher flag in AR/AP report
(cherry picked from commit 23beb46d15)
2023-11-03 07:00:25 +00:00
mergify[bot]
2c93f81d59 perf: Add index to supplier invoice field (backport #37861) (#37862)
fix: Add index to supplier invoice field (#37861)

* fix: Add index to supplier invoice field

* chore: remove unintetional changes

(cherry picked from commit c37e374fdd)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2023-11-03 11:52:07 +05:30
mergify[bot]
e19cade12d fix: remove voucher type and no for Item and Warehouse based reposting (backport #37849) (#37850)
* fix: remove voucher type and no for Item and Warehouse based reposting

(cherry picked from commit 0104897d69)

* chore: fix test cases

---------

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2023-11-02 15:15:53 +05:30
mergify[bot]
273cc35b91 fix: gov compliance for tax withholding report (#37590)
* refactor: avoid relying only on against in tds docs query

(cherry picked from commit 705dadae8e)

* chore: change column order

(cherry picked from commit 7ecc0d5a04)

* fix: sort by section code

(cherry picked from commit 4471ad581e)

* feat: proprietorship & partnership options in entity type

(cherry picked from commit ed2457bddf)

# Conflicts:
#	erpnext/buying/doctype/supplier/supplier.json
#	erpnext/selling/doctype/customer/customer.json

* chore: linting issues

(cherry picked from commit 75441017c6)

* feat: add cols for supplier inv details

(cherry picked from commit 6d5ccde864)

* chore: resolve conflicts

* chore: resolve conflicts

* chore: linting issues

---------

Co-authored-by: Gursheen Anand <gursheen@frappe.io>
Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
2023-11-02 14:34:23 +05:30
mergify[bot]
69b569df46 fix: standard submit perm in repost ledger for editable invoices (backport #37826) (#37854)
fix: standard submit perm in repost ledger for editable invoices (#37826)

* fix: ignore perm while reposting ledger

* fix: use flag in save

* fix: remove unnecessary save

(cherry picked from commit 1b808e1d7c)

Co-authored-by: Gursheen Kaur Anand <40693548+GursheenK@users.noreply.github.com>
2023-11-02 14:33:33 +05:30
rohitwaghchaure
a07d58bd0e Merge pull request #37841 from frappe/mergify/bp/version-14-hotfix/pr-37819
fix: `TypeError` in PR for non-stock item (backport #37819)
2023-11-02 13:34:23 +05:30
ruthra kumar
50fdc9dda0 Merge pull request #37846 from frappe/mergify/copy/version-14-hotfix/pr-37845
chore: add std permissions for Process Payment Reconciilation log (copy #37845)
2023-11-02 12:10:27 +05:30
ruthra kumar
9b0a46853f chore: std permissions for Process Payment Reconciilation log
(cherry picked from commit a9fceeb00f)
2023-11-02 06:10:54 +00:00
ruthra kumar
64d7590bd0 Merge pull request #37843 from frappe/mergify/bp/version-14-hotfix/pr-37838
refactor: pass limits to JE and PE queries in reconciliation tool (backport #37838)
2023-11-02 11:08:51 +05:30
mergify[bot]
e8a706a5ea feat(Stock Balance): add filters from route (backport #37836) (#37839)
feat(Stock Balance): add filters from route

(cherry picked from commit 38e5e4a893)

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2023-11-02 10:46:42 +05:30
ruthra kumar
289236d065 refactor: pass limits to JE and PE queries in reconciliation tool
(cherry picked from commit 54e8ce1ac5)
2023-11-02 05:13:08 +00:00
s-aga-r
ef4471f8c0 fix: TypeError in PR for non-stock item
(cherry picked from commit 028b3e2fbf)
2023-11-02 05:10:19 +00:00
ruthra kumar
e616a0bb63 Merge pull request #37833 from frappe/mergify/bp/version-14-hotfix/pr-37832
refactor: checkbox to toggle remarks in General Ledger (backport #37832)
2023-11-02 08:06:40 +05:30
ruthra kumar
174b76f6ff refactor: checkbox to toggle remarks in General Ledger
(cherry picked from commit 8fa677b8e8)
2023-11-02 07:28:42 +05:30
mergify[bot]
875d7f8b72 refactor: update fields label and remove unused fields from BIN (backport #37827) (#37829)
* refactor: rearrange fields and update label

(cherry picked from commit ec1a7869f8)

* refactor: remove unused fields `fcfs_rate` and `ma_rate` from Bin

(cherry picked from commit f0a1f4ac7c)

---------

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2023-11-01 16:41:33 +05:30
Raffael Meyer
2c1fdecc91 chore: resolve merge conflicts 2023-11-01 11:54:29 +01:00
barredterra
4d2169e48e fix(translations): suggestions from review
(cherry picked from commit 115f024260)
2023-11-01 09:43:41 +00:00
barredterra
b75aae99ca fix: german translations of Accounts Settings
(cherry picked from commit b3486b43c4)

# Conflicts:
#	erpnext/translations/de.csv
2023-11-01 09:43:40 +00:00
Deepesh Garg
f502ec2268 Merge pull request #37821 from frappe/mergify/bp/version-14-hotfix/pr-37635
fix: validate sales order item with quotation (backport #37635)
2023-11-01 15:13:26 +05:30
Deepesh Garg
0196d7ac23 Merge pull request #37717 from frappe/mergify/bp/version-14-hotfix/pr-37690
fix(plaid): Do not sync pending transactions (#37690)
2023-11-01 14:12:33 +05:30
Deepesh Garg
357697702b chore: resolve conflicts 2023-11-01 14:11:36 +05:30
Gursheen Anand
4a225b069b fix: validate so item with qtn
(cherry picked from commit 17ebc1ea80)
2023-11-01 08:34:50 +00:00
Deepesh Garg
28c9458482 Merge pull request #37815 from frappe/mergify/bp/version-14-hotfix/pr-37680
fix: status when over delivery or billing in SO (#37680)
2023-11-01 14:03:59 +05:30
Gursheen Anand
d8e743013f fix: status for over delivery or billing
(cherry picked from commit d69b0d76dd)
2023-11-01 07:00:14 +00:00
Deepesh Garg
555cc62e50 Merge pull request #37812 from frappe/mergify/bp/version-14-hotfix/pr-37737
fix: fetch asset received but not billed account only when needed (backport #37737)
2023-11-01 12:10:04 +05:30
Deepesh Garg
7df4009dd3 fix: fetch asset received but not billed account only when needed
(cherry picked from commit 3a8736374c)
2023-11-01 04:49:59 +00:00
ruthra kumar
08a9a9d188 Merge pull request #37806 from frappe/mergify/bp/version-14-hotfix/pr-37795
chore: update default limit values in reconciliation tool (backport #37795)
2023-10-31 20:37:40 +05:30
ruthra kumar
e98be384f9 Merge pull request #37804 from frappe/mergify/bp/version-14-hotfix/pr-37793
refactor: pull remarks only if needed on AR/AP report (backport #37793)
2023-10-31 20:37:06 +05:30
ruthra kumar
fdf2977ce2 chore: update default limit values in reconciliation tool
(cherry picked from commit 1fd888175f)
2023-10-31 14:22:29 +00:00
ruthra kumar
3276f39740 refactor: pull remarks only if needed on AR/AP report
(cherry picked from commit eb73017798)
2023-10-31 14:21:52 +00:00
mergify[bot]
0b1da08d78 fix: In-Transit Warehouse company filter (backport #37796) (#37797)
fix: In-Transit Warehouse company filter (#37796)

(cherry picked from commit daf2ec063c)

Co-authored-by: hyaray <hyaray@vip.qq.com>
2023-10-31 18:53:37 +05:30
Deepesh Garg
ffdc11bbf6 fix(plaid): Do not sync pending transactions
(cherry picked from commit 46ea868559)

# Conflicts:
#	erpnext/erpnext_integrations/doctype/plaid_settings/plaid_settings.py
2023-10-27 06:08:46 +00:00
358 changed files with 7379 additions and 54215 deletions

View File

@@ -5,7 +5,7 @@ fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.0.1
rev: v4.3.0
hooks:
- id: trailing-whitespace
files: "erpnext.*"
@@ -15,6 +15,10 @@ repos:
args: ['--branch', 'develop']
- id: check-merge-conflict
- id: check-ast
- id: check-json
- id: check-toml
- id: check-yaml
- id: debug-statements
- repo: https://github.com/PyCQA/flake8
rev: 5.0.4

View File

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

View File

@@ -53,8 +53,13 @@
},
"II. Forderungen und sonstige Vermögensgegenstände": {
"is_group": 1,
"Ford. a. Lieferungen und Leistungen": {
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
"account_number": "1400",
"account_type": "Receivable",
"is_group": 1
},
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
"account_number": "1410",
"account_type": "Receivable"
},
"Durchlaufende Posten": {
@@ -180,8 +185,13 @@
},
"IV. Verbindlichkeiten aus Lieferungen und Leistungen": {
"is_group": 1,
"Verbindlichkeiten aus Lieferungen u. Leistungen": {
"Verbindlichkeiten aus Lieferungen und Leistungen mit Kontokorrent": {
"account_number": "1600",
"account_type": "Payable",
"is_group": 1
},
"Verbindlichkeiten aus Lieferungen und Leistungen ohne Kontokorrent": {
"account_number": "1610",
"account_type": "Payable"
}
},

View File

@@ -407,13 +407,10 @@
"Bewertungskorrektur zu Forderungen aus Lieferungen und Leistungen": {
"account_number": "9960"
},
"Debitoren": {
"is_group": 1,
"account_number": "10000"
},
"Forderungen aus Lieferungen und Leistungen": {
"Forderungen aus Lieferungen und Leistungen mit Kontokorrent": {
"account_number": "1200",
"account_type": "Receivable"
"account_type": "Receivable",
"is_group": 1
},
"Forderungen aus Lieferungen und Leistungen ohne Kontokorrent": {
"account_number": "1210"
@@ -1138,18 +1135,15 @@
"Bewertungskorrektur zu Verb. aus Lieferungen und Leistungen": {
"account_number": "9964"
},
"Kreditoren": {
"account_number": "70000",
"Verb. aus Lieferungen und Leistungen mit Kontokorrent": {
"account_number": "3300",
"account_type": "Payable",
"is_group": 1,
"Wareneingangs-­Verrechnungskonto" : {
"Wareneingangs-Verrechnungskonto" : {
"account_number": "70001",
"account_type": "Stock Received But Not Billed"
}
},
"Verb. aus Lieferungen und Leistungen": {
"account_number": "3300",
"account_type": "Payable"
},
"Verb. aus Lieferungen und Leistungen ohne Kontokorrent": {
"account_number": "3310"
},

View File

@@ -68,7 +68,12 @@
"enable_party_matching",
"enable_fuzzy_matching",
"tab_break_dpet",
"show_balance_in_coa"
"show_balance_in_coa",
"reports_tab",
"remarks_section",
"general_ledger_remarks_length",
"column_break_lvjk",
"receivable_payable_remarks_length"
],
"fields": [
{
@@ -429,6 +434,34 @@
"fieldname": "show_balance_in_coa",
"fieldtype": "Check",
"label": "Show Balances in Chart Of Accounts"
},
{
"fieldname": "reports_tab",
"fieldtype": "Tab Break",
"label": "Reports"
},
{
"default": "0",
"description": "Truncates 'Remarks' column to set character length",
"fieldname": "general_ledger_remarks_length",
"fieldtype": "Int",
"label": "General Ledger"
},
{
"default": "0",
"description": "Truncates 'Remarks' column to set character length",
"fieldname": "receivable_payable_remarks_length",
"fieldtype": "Int",
"label": "Accounts Receivable/Payable"
},
{
"fieldname": "column_break_lvjk",
"fieldtype": "Column Break"
},
{
"fieldname": "remarks_section",
"fieldtype": "Section Break",
"label": "Remarks Column Length"
}
],
"icon": "icon-cog",
@@ -436,7 +469,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-07-27 15:05:34.000264",
"modified": "2023-11-20 09:37:47.650347",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -137,7 +137,7 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
"erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.get_account_balance",
args: {
bank_account: frm.doc.bank_account,
till_date: frm.doc.bank_statement_from_date,
till_date: frappe.datetime.add_days(frm.doc.bank_statement_from_date, -1)
},
callback: (response) => {
frm.set_value("account_opening_balance", response.message);

View File

@@ -112,7 +112,8 @@ class AutoMatchbyPartyNameDescription:
for party in parties:
filters = {"status": "Active"} if party == "Employee" else {"disabled": 0}
names = frappe.get_all(party, filters=filters, pluck=party.lower() + "_name")
field = party.lower() + "_name"
names = frappe.get_all(party, filters=filters, fields=[f"{field} as party_name", "name"])
for field in ["bank_party_name", "description"]:
if not self.get(field):
@@ -131,7 +132,11 @@ class AutoMatchbyPartyNameDescription:
def fuzzy_search_and_return_result(self, party, names, field) -> Union[Tuple, None]:
skip = False
result = process.extract(query=self.get(field), choices=names, scorer=fuzz.token_set_ratio)
result = process.extract(
query=self.get(field),
choices={row.get("name"): row.get("party_name") for row in names},
scorer=fuzz.token_set_ratio,
)
party_name, skip = self.process_fuzzy_result(result)
if not party_name:
@@ -149,14 +154,14 @@ class AutoMatchbyPartyNameDescription:
Returns: Result, Skip (whether or not to discontinue matching)
"""
PARTY, SCORE, CUTOFF = 0, 1, 80
SCORE, PARTY_ID, CUTOFF = 1, 2, 80
if not result or not len(result):
return None, False
first_result = result[0]
if len(result) == 1:
return (first_result[PARTY] if first_result[SCORE] > CUTOFF else None), True
return (first_result[PARTY_ID] if first_result[SCORE] > CUTOFF else None), True
second_result = result[1]
if first_result[SCORE] > CUTOFF:
@@ -165,7 +170,7 @@ class AutoMatchbyPartyNameDescription:
if first_result[SCORE] == second_result[SCORE]:
return None, True
return first_result[PARTY], True
return first_result[PARTY_ID], True
else:
return None, False

View File

@@ -89,7 +89,6 @@ class BankTransaction(StatusUpdater):
- 0 > a: Error: already over-allocated
- clear means: set the latest transaction date as clearance date
"""
gl_bank_account = frappe.db.get_value("Bank Account", self.bank_account, "account")
remaining_amount = self.unallocated_amount
for payment_entry in self.payment_entries:
if payment_entry.allocated_amount == 0.0:

View File

@@ -1,457 +1,152 @@
{
"allow_copy": 0,
"allow_events_in_timeline": 0,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"actions": [],
"autoname": "naming_series:",
"beta": 0,
"creation": "2018-06-18 16:51:49.994750",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"naming_series",
"user",
"date",
"from_time",
"time",
"expense",
"custody",
"returns",
"outstanding_amount",
"payments",
"net_amount",
"amended_from"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "POS-CLO-",
"fieldname": "naming_series",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 1,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Series",
"length": 0,
"no_copy": 0,
"options": "POS-CLO-",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "user",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "User",
"length": 0,
"no_copy": 0,
"options": "User",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "Today",
"fieldname": "date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "from_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "From Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 1,
"label": "To Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "expense",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Expense",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Expense"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "custody",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Custody",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"label": "Custody"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "returns",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Returns",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "2",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"unique": 0
"precision": "2"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.00",
"fieldname": "outstanding_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Outstanding Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "0.0",
"fieldname": "payments",
"fieldtype": "Table",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Payments",
"length": 0,
"no_copy": 0,
"options": "Cashier Closing Payments",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"options": "Cashier Closing Payments"
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "net_amount",
"fieldtype": "Float",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 1,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Net Amount",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_in_quick_entry": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "amended_from",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Amended From",
"length": 0,
"no_copy": 1,
"options": "Cashier Closing",
"permlevel": 0,
"print_hide": 1,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"read_only": 1
}
],
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 1,
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2019-02-19 08:35:24.157327",
"links": [],
"modified": "2023-12-28 13:15:46.858427",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Cashier Closing",
"name_case": "",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"set_user_permissions": 0,
"share": 1,
"submit": 1,
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0,
"track_views": 0
}
"states": [],
"track_changes": 1
}

View File

@@ -53,10 +53,18 @@ frappe.ui.form.on('Chart of Accounts Importer', {
of Accounts. Please enter the account names and add more rows as per your requirement.`);
}
}
}
},
{
label : "Company",
fieldname: "company",
fieldtype: "Link",
reqd: 1,
hidden: 1,
default: frm.doc.company,
},
],
primary_action: function() {
var data = d.get_values();
let data = d.get_values();
if (!data.template_type) {
frappe.throw(__('Please select <b>Template Type</b> to download template'));
@@ -66,7 +74,8 @@ frappe.ui.form.on('Chart of Accounts Importer', {
'/api/method/erpnext.accounts.doctype.chart_of_accounts_importer.chart_of_accounts_importer.download_template',
{
file_type: data.file_type,
template_type: data.template_type
template_type: data.template_type,
company: data.company
}
);

View File

@@ -8,6 +8,7 @@ from functools import reduce
import frappe
from frappe import _
from frappe.desk.form.linked_with import get_linked_fields
from frappe.model.document import Document
from frappe.utils import cint, cstr
from frappe.utils.csvutils import UnicodeWriter
@@ -112,7 +113,7 @@ def generate_data_from_csv(file_doc, as_dict=False):
if as_dict:
data.append({frappe.scrub(header): row[index] for index, header in enumerate(headers)})
else:
if not row[1]:
if not row[1] and len(row) > 1:
row[1] = row[0]
row[3] = row[2]
data.append(row)
@@ -294,10 +295,8 @@ def build_response_as_excel(writer):
@frappe.whitelist()
def download_template(file_type, template_type):
data = frappe._dict(frappe.local.form_dict)
writer = get_template(template_type)
def download_template(file_type, template_type, company):
writer = get_template(template_type, company)
if file_type == "CSV":
# download csv file
@@ -308,8 +307,7 @@ def download_template(file_type, template_type):
build_response_as_excel(writer)
def get_template(template_type):
def get_template(template_type, company):
fields = [
"Account Name",
"Parent Account",
@@ -335,34 +333,17 @@ def get_template(template_type):
["", "", "", "", 0, account_type.get("account_type"), account_type.get("root_type")]
)
else:
writer = get_sample_template(writer)
writer = get_sample_template(writer, company)
return writer
def get_sample_template(writer):
template = [
["Application Of Funds(Assets)", "", "", "", 1, "", "Asset"],
["Sources Of Funds(Liabilities)", "", "", "", 1, "", "Liability"],
["Equity", "", "", "", 1, "", "Equity"],
["Expenses", "", "", "", 1, "", "Expense"],
["Income", "", "", "", 1, "", "Income"],
["Bank Accounts", "Application Of Funds(Assets)", "", "", 1, "Bank", "Asset"],
["Cash In Hand", "Application Of Funds(Assets)", "", "", 1, "Cash", "Asset"],
["Stock Assets", "Application Of Funds(Assets)", "", "", 1, "Stock", "Asset"],
["Cost Of Goods Sold", "Expenses", "", "", 0, "Cost of Goods Sold", "Expense"],
["Asset Depreciation", "Expenses", "", "", 0, "Depreciation", "Expense"],
["Fixed Assets", "Application Of Funds(Assets)", "", "", 0, "Fixed Asset", "Asset"],
["Accounts Payable", "Sources Of Funds(Liabilities)", "", "", 0, "Payable", "Liability"],
["Accounts Receivable", "Application Of Funds(Assets)", "", "", 1, "Receivable", "Asset"],
["Stock Expenses", "Expenses", "", "", 0, "Stock Adjustment", "Expense"],
["Sample Bank", "Bank Accounts", "", "", 0, "Bank", "Asset"],
["Cash", "Cash In Hand", "", "", 0, "Cash", "Asset"],
["Stores", "Stock Assets", "", "", 0, "Stock", "Asset"],
]
for row in template:
writer.writerow(row)
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:
for row in f:
row = row.strip().split(",") + [currency]
writer.writerow(row)
return writer
@@ -453,14 +434,11 @@ def get_mandatory_account_types():
def unset_existing_data(company):
linked = frappe.db.sql(
'''select fieldname from tabDocField
where fieldtype="Link" and options="Account" and parent="Company"''',
as_dict=True,
)
# remove accounts data from company
update_values = {d.fieldname: "" for d in linked}
fieldnames = get_linked_fields("Account").get("Company", {}).get("fieldname", [])
linked = [{"fieldname": name} for name in fieldnames]
update_values = {d.get("fieldname"): "" for d in linked}
frappe.db.set_value("Company", company, update_values, update_values)
# remove accounts data from various doctypes

View File

@@ -0,0 +1,17 @@
Application Of Funds(Assets),,,,1,,Asset
Sources Of Funds(Liabilities),,,,1,,Liability
Equity,,,,1,,Equity
Expenses,,,,1,Expense Account,Expense
Income,,,,1,Income Account,Income
Bank Accounts,Application Of Funds(Assets),,,1,Bank,Asset
Cash In Hand,Application Of Funds(Assets),,,1,Cash,Asset
Stock Assets,Application Of Funds(Assets),,,1,Stock,Asset
Cost Of Goods Sold,Expenses,,,0,Cost of Goods Sold,Expense
Asset Depreciation,Expenses,,,0,Depreciation,Expense
Fixed Assets,Application Of Funds(Assets),,,0,Fixed Asset,Asset
Accounts Payable,Sources Of Funds(Liabilities),,,0,Payable,Liability
Accounts Receivable,Application Of Funds(Assets),,,1,Receivable,Asset
Stock Expenses,Expenses,,,0,Stock Adjustment,Expense
Sample Bank,Bank Accounts,,,0,Bank,Asset
Cash,Cash In Hand,,,0,Cash,Asset
Stores,Stock Assets,,,0,Stock,Asset
1 Application Of Funds(Assets) 1 Asset
2 Sources Of Funds(Liabilities) 1 Liability
3 Equity 1 Equity
4 Expenses 1 Expense Account Expense
5 Income 1 Income Account Income
6 Bank Accounts Application Of Funds(Assets) 1 Bank Asset
7 Cash In Hand Application Of Funds(Assets) 1 Cash Asset
8 Stock Assets Application Of Funds(Assets) 1 Stock Asset
9 Cost Of Goods Sold Expenses 0 Cost of Goods Sold Expense
10 Asset Depreciation Expenses 0 Depreciation Expense
11 Fixed Assets Application Of Funds(Assets) 0 Fixed Asset Asset
12 Accounts Payable Sources Of Funds(Liabilities) 0 Payable Liability
13 Accounts Receivable Application Of Funds(Assets) 1 Receivable Asset
14 Stock Expenses Expenses 0 Stock Adjustment Expense
15 Sample Bank Bank Accounts 0 Bank Asset
16 Cash Cash In Hand 0 Cash Asset
17 Stores Stock Assets 0 Stock Asset

View File

@@ -192,7 +192,7 @@ class ExchangeRateRevaluation(Document):
# round off balance based on currency precision
# and consider debit-credit difference allowance
currency_precision = get_currency_precision()
rounding_loss_allowance = float(rounding_loss_allowance) or 0.05
rounding_loss_allowance = float(rounding_loss_allowance)
for acc in account_details:
acc.balance_in_account_currency = flt(acc.balance_in_account_currency, currency_precision)
if abs(acc.balance_in_account_currency) <= rounding_loss_allowance:

View File

@@ -138,8 +138,7 @@
"label": "Against Voucher Type",
"oldfieldname": "against_voucher_type",
"oldfieldtype": "Data",
"options": "DocType",
"search_index": 1
"options": "DocType"
},
{
"fieldname": "against_voucher",
@@ -158,8 +157,7 @@
"label": "Voucher Type",
"oldfieldname": "voucher_type",
"oldfieldtype": "Select",
"options": "DocType",
"search_index": 1
"options": "DocType"
},
{
"fieldname": "voucher_no",
@@ -291,4 +289,4 @@
"search_fields": "voucher_no,account,posting_date,against_voucher",
"sort_field": "modified",
"sort_order": "DESC"
}
}

View File

@@ -8,7 +8,7 @@ frappe.provide("erpnext.journal_entry");
frappe.ui.form.on("Journal Entry", {
setup: function(frm) {
frm.add_fetch("bank_account", "account", "account");
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger', 'Asset', 'Asset Movement', 'Repost Accounting Ledger'];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', "Repost Payment Ledger", 'Asset', 'Asset Movement', "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
},
refresh: function(frm) {
@@ -51,7 +51,7 @@ frappe.ui.form.on("Journal Entry", {
}, __('Make'));
}
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
},
before_save: function(frm) {
if ((frm.doc.docstatus == 0) && (!frm.doc.is_system_generated)) {

View File

@@ -548,8 +548,16 @@
"icon": "fa fa-file-text",
"idx": 176,
"is_submittable": 1,
"links": [],
"modified": "2023-08-10 14:32:22.366895",
"links": [
{
"is_child_table": 1,
"link_doctype": "Bank Transaction Payments",
"link_fieldname": "payment_entry",
"parent_doctype": "Bank Transaction",
"table_fieldname": "payment_entries"
}
],
"modified": "2023-11-23 12:11:04.128015",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -98,6 +98,8 @@ class JournalEntry(AccountsController):
"Repost Payment Ledger Items",
"Repost Accounting Ledger",
"Repost Accounting Ledger Items",
"Unreconcile Payment",
"Unreconcile Payment Entries",
)
self.make_gl_entries(1)
self.update_advance_paid()
@@ -496,7 +498,7 @@ class JournalEntry(AccountsController):
).format(d.reference_name, d.account)
)
else:
dr_or_cr = "debit" if d.credit > 0 else "credit"
dr_or_cr = "debit" if flt(d.credit) > 0 else "credit"
valid = False
for jvd in against_entries:
if flt(jvd[dr_or_cr]) > 0:

View File

@@ -81,7 +81,6 @@
},
{
"account": "Sales - _TC",
"cost_center": "_Test Cost Center - _TC",
"credit_in_account_currency": 400.0,
"debit_in_account_currency": 0.0,
"doctype": "Journal Entry Account",

View File

@@ -203,7 +203,8 @@
"fieldtype": "Select",
"label": "Reference Type",
"no_copy": 1,
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry"
"options": "\nSales Invoice\nPurchase Invoice\nJournal Entry\nSales Order\nPurchase Order\nExpense Claim\nAsset\nLoan\nPayroll Entry\nEmployee Advance\nExchange Rate Revaluation\nInvoice Discounting\nFees\nFull and Final Statement\nPayment Entry",
"search_index": 1
},
{
"fieldname": "reference_name",
@@ -211,7 +212,8 @@
"in_list_view": 1,
"label": "Reference Name",
"no_copy": 1,
"options": "reference_type"
"options": "reference_type",
"search_index": 1
},
{
"depends_on": "eval:doc.reference_type&&!in_list(doc.reference_type, ['Expense Claim', 'Asset', 'Employee Loan', 'Employee Advance'])",
@@ -278,13 +280,14 @@
"fieldtype": "Data",
"hidden": 1,
"label": "Reference Detail No",
"no_copy": 1
"no_copy": 1,
"search_index": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-06-16 14:11:13.507807",
"modified": "2023-11-23 11:44:25.841187",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",

View File

@@ -7,7 +7,7 @@ cur_frm.cscript.tax_table = "Advance Taxes and Charges";
frappe.ui.form.on('Payment Entry', {
onload: function(frm) {
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payments', 'Unreconcile Payment Entries'];
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice', 'Journal Entry', 'Repost Payment Ledger','Repost Accounting Ledger', 'Unreconcile Payment', 'Unreconcile Payment Entries'];
if(frm.doc.__islocal) {
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
@@ -152,13 +152,13 @@ frappe.ui.form.on('Payment Entry', {
frm.events.hide_unhide_fields(frm);
frm.events.set_dynamic_labels(frm);
frm.events.show_general_ledger(frm);
if(frm.doc.references.find((elem) => {return elem.exchange_gain_loss != 0})) {
if((frm.doc.references) && (frm.doc.references.find((elem) => {return elem.exchange_gain_loss != 0}))) {
frm.add_custom_button(__("View Exchange Gain/Loss Journals"), function() {
frappe.set_route("List", "Journal Entry", {"voucher_type": "Exchange Gain Or Loss", "reference_name": frm.doc.name});
}, __('Actions'));
}
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(frm);
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(frm);
},
validate_company: (frm) => {
@@ -829,7 +829,6 @@ frappe.ui.form.on('Payment Entry', {
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") ||
@@ -844,6 +843,7 @@ frappe.ui.form.on('Payment Entry', {
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(

View File

@@ -739,8 +739,16 @@
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-06-19 11:38:04.387219",
"links": [
{
"is_child_table": 1,
"link_doctype": "Bank Transaction Payments",
"link_fieldname": "payment_entry",
"parent_doctype": "Bank Transaction",
"table_fieldname": "payment_entries"
}
],
"modified": "2023-11-23 12:07:20.887885",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",
@@ -786,4 +794,4 @@
"states": [],
"title_field": "title",
"track_changes": 1
}
}

View File

@@ -9,6 +9,8 @@ import frappe
from frappe import ValidationError, _, qb, scrub, throw
from frappe.utils import cint, comma_or, flt, getdate, nowdate
from frappe.utils.data import comma_and, fmt_money
from pypika import Case
from pypika.functions import Coalesce, Sum
import erpnext
from erpnext.accounts.doctype.bank_account.bank_account import (
@@ -107,7 +109,7 @@ class PaymentEntry(AccountsController):
"Repost Payment Ledger Items",
"Repost Accounting Ledger",
"Repost Accounting Ledger Items",
"Unreconcile Payments",
"Unreconcile Payment",
"Unreconcile Payment Entries",
)
super(PaymentEntry, self).on_cancel()
@@ -913,8 +915,11 @@ class PaymentEntry(AccountsController):
):
return
total_negative_outstanding = sum(
abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
total_negative_outstanding = flt(
sum(
abs(flt(d.outstanding_amount)) for d in self.get("references") if flt(d.outstanding_amount) < 0
),
self.references[0].precision("outstanding_amount") if self.references else None,
)
paid_amount = self.paid_amount if self.payment_type == "Receive" else self.received_amount
@@ -1549,13 +1554,43 @@ def get_outstanding_reference_documents(args):
return data
def split_invoices_based_on_payment_terms(outstanding_invoices, company):
invoice_ref_based_on_payment_terms = {}
def split_invoices_based_on_payment_terms(outstanding_invoices, company) -> list:
"""Split a list of invoices based on their payment terms."""
exc_rates = get_currency_data(outstanding_invoices, company)
outstanding_invoices_after_split = []
for entry in outstanding_invoices:
if entry.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
if payment_term_template := frappe.db.get_value(
entry.voucher_type, entry.voucher_no, "payment_terms_template"
):
split_rows = get_split_invoice_rows(entry, payment_term_template, exc_rates)
if not split_rows:
continue
if len(split_rows) > 1:
frappe.msgprint(
_("Splitting {0} {1} into {2} rows as per Payment Terms").format(
_(entry.voucher_type), frappe.bold(entry.voucher_no), len(split_rows)
),
alert=True,
)
outstanding_invoices_after_split += split_rows
continue
# If not an invoice or no payment terms template, add as it is
outstanding_invoices_after_split.append(entry)
return outstanding_invoices_after_split
def get_currency_data(outstanding_invoices: list, company: str = None) -> dict:
"""Get currency and conversion data for a list of invoices."""
exc_rates = frappe._dict()
company_currency = (
frappe.db.get_value("Company", company, "default_currency") if company else None
)
exc_rates = frappe._dict()
for doctype in ["Sales Invoice", "Purchase Invoice"]:
invoices = [x.voucher_no for x in outstanding_invoices if x.voucher_type == doctype]
for x in frappe.db.get_all(
@@ -1570,71 +1605,54 @@ def split_invoices_based_on_payment_terms(outstanding_invoices, company):
company_currency=company_currency,
)
for idx, d in enumerate(outstanding_invoices):
if d.voucher_type in ["Sales Invoice", "Purchase Invoice"]:
payment_term_template = frappe.db.get_value(
d.voucher_type, d.voucher_no, "payment_terms_template"
return exc_rates
def get_split_invoice_rows(invoice: dict, payment_term_template: str, exc_rates: dict) -> list:
"""Split invoice based on its payment schedule table."""
split_rows = []
allocate_payment_based_on_payment_terms = frappe.db.get_value(
"Payment Terms Template", payment_term_template, "allocate_payment_based_on_payment_terms"
)
if not allocate_payment_based_on_payment_terms:
return [invoice]
payment_schedule = frappe.get_all(
"Payment Schedule", filters={"parent": invoice.voucher_no}, fields=["*"], order_by="due_date"
)
for payment_term in payment_schedule:
if not payment_term.outstanding > 0.1:
continue
doc_details = exc_rates.get(payment_term.parent, None)
is_multi_currency_acc = (doc_details.currency != doc_details.company_currency) and (
doc_details.party_account_currency != doc_details.company_currency
)
payment_term_outstanding = flt(payment_term.outstanding)
if not is_multi_currency_acc:
payment_term_outstanding = doc_details.conversion_rate * flt(payment_term.outstanding)
split_rows.append(
frappe._dict(
{
"due_date": invoice.due_date,
"currency": invoice.currency,
"voucher_no": invoice.voucher_no,
"voucher_type": invoice.voucher_type,
"posting_date": invoice.posting_date,
"invoice_amount": flt(invoice.invoice_amount),
"outstanding_amount": payment_term_outstanding
if payment_term_outstanding
else invoice.outstanding_amount,
"payment_term_outstanding": payment_term_outstanding,
"payment_amount": payment_term.payment_amount,
"payment_term": payment_term.payment_term,
}
)
if payment_term_template:
allocate_payment_based_on_payment_terms = frappe.db.get_value(
"Payment Terms Template", payment_term_template, "allocate_payment_based_on_payment_terms"
)
if allocate_payment_based_on_payment_terms:
payment_schedule = frappe.get_all(
"Payment Schedule", filters={"parent": d.voucher_no}, fields=["*"]
)
)
for payment_term in payment_schedule:
if payment_term.outstanding > 0.1:
doc_details = exc_rates.get(payment_term.parent, None)
is_multi_currency_acc = (doc_details.currency != doc_details.company_currency) and (
doc_details.party_account_currency != doc_details.company_currency
)
payment_term_outstanding = flt(payment_term.outstanding)
if not is_multi_currency_acc:
payment_term_outstanding = doc_details.conversion_rate * flt(payment_term.outstanding)
invoice_ref_based_on_payment_terms.setdefault(idx, [])
invoice_ref_based_on_payment_terms[idx].append(
frappe._dict(
{
"due_date": d.due_date,
"currency": d.currency,
"voucher_no": d.voucher_no,
"voucher_type": d.voucher_type,
"posting_date": d.posting_date,
"invoice_amount": flt(d.invoice_amount),
"outstanding_amount": payment_term_outstanding
if payment_term_outstanding
else d.outstanding_amount,
"payment_term_outstanding": payment_term_outstanding,
"payment_amount": payment_term.payment_amount,
"payment_term": payment_term.payment_term,
}
)
)
outstanding_invoices_after_split = []
if invoice_ref_based_on_payment_terms:
for idx, ref in invoice_ref_based_on_payment_terms.items():
voucher_no = ref[0]["voucher_no"]
voucher_type = ref[0]["voucher_type"]
frappe.msgprint(
_("Spliting {} {} into {} row(s) as per Payment Terms").format(
voucher_type, voucher_no, len(ref)
),
alert=True,
)
outstanding_invoices_after_split += invoice_ref_based_on_payment_terms[idx]
existing_row = list(filter(lambda x: x.get("voucher_no") == voucher_no, outstanding_invoices))
index = outstanding_invoices.index(existing_row[0])
outstanding_invoices.pop(index)
outstanding_invoices_after_split += outstanding_invoices
return outstanding_invoices_after_split
return split_rows
def get_orders_to_be_billed(
@@ -1838,18 +1856,24 @@ def get_company_defaults(company):
def get_outstanding_on_journal_entry(name):
res = frappe.db.sql(
"SELECT "
'CASE WHEN party_type IN ("Customer") '
"THEN ifnull(sum(debit_in_account_currency - credit_in_account_currency), 0) "
"ELSE ifnull(sum(credit_in_account_currency - debit_in_account_currency), 0) "
"END as outstanding_amount "
"FROM `tabGL Entry` WHERE (voucher_no=%s OR against_voucher=%s) "
"AND party_type IS NOT NULL "
'AND party_type != ""',
(name, name),
as_dict=1,
)
gl = frappe.qb.DocType("GL Entry")
res = (
frappe.qb.from_(gl)
.select(
Case()
.when(
gl.party_type == "Customer",
Coalesce(Sum(gl.debit_in_account_currency - gl.credit_in_account_currency), 0),
)
.else_(Coalesce(Sum(gl.credit_in_account_currency - gl.debit_in_account_currency), 0))
.as_("outstanding_amount")
)
.where(
(Coalesce(gl.party_type, "") != "")
& (gl.is_cancelled == 0)
& ((gl.voucher_no == name) | (gl.against_voucher == name))
)
).run(as_dict=True)
outstanding_amount = res[0].get("outstanding_amount", 0) if res else 0

View File

@@ -1,15 +1,17 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import json
import unittest
import frappe
from frappe import qb
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import flt, nowdate
from frappe.utils import add_days, flt, nowdate
from erpnext.accounts.doctype.payment_entry.payment_entry import (
InvalidPaymentEntry,
get_outstanding_reference_documents,
get_payment_entry,
get_reference_details,
)
@@ -21,6 +23,7 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import (
create_sales_invoice,
create_sales_invoice_against_cost_center,
)
from erpnext.accounts.general_ledger import make_gl_entries, make_reverse_gl_entries
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
from erpnext.setup.doctype.employee.test_employee import make_employee
@@ -1219,6 +1222,115 @@ class TestPaymentEntry(FrappeTestCase):
so.reload()
self.assertEqual(so.advance_paid, so.rounded_total)
def test_outstanding_invoices_api(self):
"""
Test if `get_outstanding_reference_documents` fetches invoices in the right order.
"""
customer = create_customer("Max Mustermann", "INR")
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)
)
si2 = create_sales_invoice(do_not_save=1, qty=1, rate=100, customer=customer)
si2.payment_terms_template = "Test Receivable Template"
si2.submit()
args = {
"posting_date": nowdate(),
"company": "_Test Company",
"party_type": "Customer",
"payment_type": "Pay",
"party": customer,
"party_account": "Debtors - _TC",
}
args.update(
{
"get_outstanding_invoices": True,
"from_posting_date": add_days(nowdate(), -4),
"to_posting_date": add_days(nowdate(), 2),
}
)
references = get_outstanding_reference_documents(args)
self.assertEqual(len(references), 3)
self.assertEqual(references[0].voucher_no, si.name)
self.assertEqual(references[1].voucher_no, si2.name)
self.assertEqual(references[2].voucher_no, si2.name)
self.assertEqual(references[1].payment_term, "Basic Amount Receivable")
self.assertEqual(references[2].payment_term, "Tax Receivable")
def test_partial_cancel_for_payment_entry(self):
si = create_sales_invoice()
pe = get_payment_entry(si.doctype, si.name)
pe.save()
pe.submit()
# Additional GL Entry
tax_amount = 10
reference_row = pe.references[0]
gl_args = {
"party_type": pe.party_type,
"party": pe.party,
"against_voucher_type": reference_row.reference_doctype,
"against_voucher": reference_row.reference_name,
"voucher_detail_no": reference_row.name,
}
gl_dicts = []
gl_dicts.extend(
[
pe.get_gl_dict(
{
"account": pe.paid_to,
"credit": tax_amount,
"credit_in_account_currency": tax_amount,
**gl_args,
}
),
pe.get_gl_dict(
{
"account": pe.paid_from,
"debit": tax_amount,
"debit_in_account_currency": tax_amount,
**gl_args,
}
),
]
)
make_gl_entries(gl_dicts)
# Assert PLEs Before
self.assertPLEntries(
pe,
[
{"amount": -100.0, "against_voucher_no": si.name},
{"amount": 10.0, "against_voucher_no": si.name},
],
)
# Partially cancel Payment Entry
make_reverse_gl_entries(gl_dicts, partial_cancel=True)
self.assertPLEntries(pe, [{"amount": -100.0, "against_voucher_no": si.name}])
def assertPLEntries(self, payment_doc, expected_pl_entries):
pl_entries = frappe.get_all(
"Payment Ledger Entry",
filters={
"voucher_type": payment_doc.doctype,
"voucher_no": payment_doc.name,
"delinked": 0,
},
fields=["amount", "against_voucher_no"],
)
out_str = json.dumps(sorted(pl_entries, key=json.dumps))
expected_out_str = json.dumps(sorted(expected_pl_entries, key=json.dumps))
self.assertEqual(out_str, expected_out_str)
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
@@ -1279,6 +1391,9 @@ def create_payment_terms_template():
def create_payment_terms_template_with_discount(
name=None, discount_type=None, discount=None, template_name=None
):
"""
Create a Payment Terms Template with % or amount discount.
"""
create_payment_term(name or "30 Credit Days with 10% Discount")
template_name = template_name or "Test Discount Template"

View File

@@ -13,6 +13,7 @@
"party_type",
"party",
"due_date",
"voucher_detail_no",
"cost_center",
"finance_book",
"voucher_type",
@@ -64,7 +65,8 @@
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Voucher Type",
"options": "DocType"
"options": "DocType",
"search_index": 1
},
{
"fieldname": "voucher_no",
@@ -72,14 +74,16 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Voucher No",
"options": "voucher_type"
"options": "voucher_type",
"search_index": 1
},
{
"fieldname": "against_voucher_type",
"fieldtype": "Link",
"in_standard_filter": 1,
"label": "Against Voucher Type",
"options": "DocType"
"options": "DocType",
"search_index": 1
},
{
"fieldname": "against_voucher_no",
@@ -87,7 +91,8 @@
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Against Voucher No",
"options": "against_voucher_type"
"options": "against_voucher_type",
"search_index": 1
},
{
"fieldname": "amount",
@@ -143,12 +148,18 @@
"fieldname": "remarks",
"fieldtype": "Text",
"label": "Remarks"
},
{
"fieldname": "voucher_detail_no",
"fieldtype": "Data",
"label": "Voucher Detail No",
"search_index": 1
}
],
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-10-30 16:15:00.470283",
"modified": "2023-11-08 10:53:10.664896",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Ledger Entry",

View File

@@ -203,9 +203,10 @@
],
"hide_toolbar": 1,
"icon": "icon-resize-horizontal",
"is_virtual": 1,
"issingle": 1,
"links": [],
"modified": "2023-08-15 05:35:50.109290",
"modified": "2023-11-17 17:33:55.701726",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation",
@@ -230,6 +231,5 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
"states": []
}

View File

@@ -29,6 +29,58 @@ class PaymentReconciliation(Document):
self.accounting_dimension_filter_conditions = []
self.ple_posting_date_filter = []
def load_from_db(self):
# 'modified' attribute is required for `run_doc_method` to work properly.
doc_dict = frappe._dict(
{
"modified": None,
"company": None,
"party": None,
"party_type": None,
"receivable_payable_account": None,
"default_advance_account": None,
"from_invoice_date": None,
"to_invoice_date": None,
"invoice_limit": 50,
"from_payment_date": None,
"to_payment_date": None,
"payment_limit": 50,
"minimum_invoice_amount": None,
"minimum_payment_amount": None,
"maximum_invoice_amount": None,
"maximum_payment_amount": None,
"bank_cash_account": None,
"cost_center": None,
"payment_name": None,
"invoice_name": None,
}
)
super(Document, self).__init__(doc_dict)
def save(self):
return
@staticmethod
def get_list(args):
pass
@staticmethod
def get_count(args):
pass
@staticmethod
def get_stats(args):
pass
def db_insert(self, *args, **kwargs):
pass
def db_update(self, *args, **kwargs):
pass
def delete(self):
pass
@frappe.whitelist()
def get_unreconciled_entries(self):
self.get_nonreconciled_payment_entries()
@@ -59,8 +111,6 @@ class PaymentReconciliation(Document):
def get_payment_entries(self):
order_doctype = "Sales Order" if self.party_type == "Customer" else "Purchase Order"
condition = self.get_conditions(get_payments=True)
if self.payment_name:
condition += "name like '%%{0}%%'".format(self.payment_name)
payment_entries = get_advance_payment_entries_for_regional(
self.party_type,
@@ -70,6 +120,7 @@ class PaymentReconciliation(Document):
against_all_orders=True,
limit=self.payment_limit,
condition=condition,
payment_name=self.payment_name,
)
return payment_entries
@@ -93,6 +144,8 @@ class PaymentReconciliation(Document):
"t2.against_account like %(bank_cash_account)s" if self.bank_cash_account else "1=1"
)
limit = f"limit {self.payment_limit}" if self.payment_limit else " "
# nosemgrep
journal_entries = frappe.db.sql(
"""
@@ -116,11 +169,13 @@ class PaymentReconciliation(Document):
ELSE {bank_account_condition}
END)
order by t1.posting_date
{limit}
""".format(
**{
"dr_or_cr": dr_or_cr,
"bank_account_condition": bank_account_condition,
"condition": condition,
"limit": limit,
}
),
{
@@ -146,7 +201,7 @@ class PaymentReconciliation(Document):
if self.payment_name:
conditions.append(doc.name.like(f"%{self.payment_name}%"))
self.return_invoices = (
self.return_invoices_query = (
qb.from_(doc)
.select(
ConstantColumn(voucher_type).as_("voucher_type"),
@@ -154,8 +209,11 @@ class PaymentReconciliation(Document):
doc.return_against,
)
.where(Criterion.all(conditions))
.run(as_dict=True)
)
if self.payment_limit:
self.return_invoices_query = self.return_invoices_query.limit(self.payment_limit)
self.return_invoices = self.return_invoices_query.run(as_dict=True)
def get_dr_or_cr_notes(self):
@@ -480,6 +538,27 @@ 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.extend(
[d.get("reference_name") for d in payments if d.get("reference_type") == "Journal Entry"]
)
if journals:
journals = list(set(journals))
journals_map = frappe._dict(
frappe.db.get_all(
"Journal Entry Account",
filters={"parent": ("in", journals), "account": ("in", [self.receivable_payable_account])},
fields=[
"parent as `name`",
"exchange_rate",
],
as_list=1,
)
)
invoice_exchange_map.update(journals_map)
return invoice_exchange_map
def validate_allocation(self):

View File

@@ -1137,6 +1137,40 @@ class TestPaymentReconciliation(FrappeTestCase):
self.assertEqual(pay.unallocated_amount, 1000)
self.assertEqual(pay.difference_amount, 0)
def test_rounding_of_unallocated_amount(self):
self.supplier = "_Test Supplier USD"
pi = self.create_purchase_invoice(qty=1, rate=10, do_not_submit=True)
pi.supplier = self.supplier
pi.currency = "USD"
pi.conversion_rate = 80
pi.credit_to = self.creditors_usd
pi.save().submit()
pe = get_payment_entry(pi.doctype, pi.name)
pe.target_exchange_rate = 78.726500000
pe.received_amount = 26.75
pe.paid_amount = 2105.93
pe.references = []
pe.save().submit()
# unallocated_amount will have some rounding loss - 26.749950
self.assertNotEqual(pe.unallocated_amount, 26.75)
pr = frappe.get_doc("Payment Reconciliation")
pr.company = self.company
pr.party_type = "Supplier"
pr.party = self.supplier
pr.receivable_payable_account = self.creditors_usd
pr.from_invoice_date = pr.to_invoice_date = pr.from_payment_date = pr.to_payment_date = nowdate()
pr.get_unreconciled_entries()
invoices = [invoice.as_dict() for invoice in pr.invoices]
payments = [payment.as_dict() for payment in pr.payments]
pr.allocate_entries(frappe._dict({"invoices": invoices, "payments": payments}))
# Should not raise frappe.exceptions.ValidationError: Payment Entry has been modified after you pulled it. Please pull it again.
pr.reconcile()
def make_customer(customer_name, currency=None):
if not frappe.db.exists("Customer", customer_name):

View File

@@ -159,9 +159,10 @@
"label": "Difference Posting Date"
}
],
"is_virtual": 1,
"istable": 1,
"links": [],
"modified": "2023-10-23 10:44:56.066303",
"modified": "2023-11-17 17:33:38.612615",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Allocation",

View File

@@ -6,4 +6,6 @@ from frappe.model.document import Document
class PaymentReconciliationAllocation(Document):
pass
@staticmethod
def get_list(args):
pass

View File

@@ -71,9 +71,10 @@
"label": "Exchange Rate"
}
],
"is_virtual": 1,
"istable": 1,
"links": [],
"modified": "2022-11-08 18:18:02.502149",
"modified": "2023-11-17 17:33:45.455166",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Invoice",

View File

@@ -6,4 +6,6 @@ from frappe.model.document import Document
class PaymentReconciliationInvoice(Document):
pass
@staticmethod
def get_list(args):
pass

View File

@@ -107,9 +107,10 @@
"options": "Cost Center"
}
],
"is_virtual": 1,
"istable": 1,
"links": [],
"modified": "2023-09-03 07:43:29.965353",
"modified": "2023-11-17 17:33:34.818530",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation Payment",

View File

@@ -6,4 +6,6 @@ from frappe.model.document import Document
class PaymentReconciliationPayment(Document):
pass
@staticmethod
def get_list(args):
pass

View File

@@ -18,6 +18,7 @@
"is_pos",
"is_return",
"update_billed_amount_in_sales_order",
"update_billed_amount_in_delivery_note",
"column_break1",
"company",
"posting_date",
@@ -1549,12 +1550,19 @@
"fieldtype": "Currency",
"label": "Amount Eligible for Commission",
"read_only": 1
},
{
"default": "1",
"depends_on": "eval: doc.is_return && doc.return_against",
"fieldname": "update_billed_amount_in_delivery_note",
"fieldtype": "Check",
"label": "Update Billed Amount in Delivery Note"
}
],
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2022-09-30 03:49:50.455199",
"modified": "2023-11-20 12:27:12.848149",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -659,7 +659,7 @@ def get_stock_availability(item_code, warehouse):
return bin_qty - pos_sales_qty, is_stock_item
else:
is_stock_item = True
if frappe.db.exists("Product Bundle", item_code):
if frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0}):
return get_bundle_availability(item_code, warehouse), is_stock_item
else:
is_stock_item = False
@@ -705,7 +705,7 @@ def get_pos_reserved_qty(item_code, warehouse):
reserved_qty = (
frappe.qb.from_(p_inv)
.from_(p_item)
.select(Sum(p_item.qty).as_("qty"))
.select(Sum(p_item.stock_qty).as_("stock_qty"))
.where(
(p_inv.name == p_item.parent)
& (IfNull(p_inv.consolidated_invoice, "") == "")
@@ -716,7 +716,7 @@ def get_pos_reserved_qty(item_code, warehouse):
)
).run(as_dict=True)
return reserved_qty[0].qty or 0 if reserved_qty else 0
return flt(reserved_qty[0].stock_qty) if reserved_qty else 0
@frappe.whitelist()

View File

@@ -185,6 +185,7 @@
"label": "Image"
},
{
"fetch_from": "item_code.image",
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
@@ -821,7 +822,7 @@
],
"istable": 1,
"links": [],
"modified": "2022-11-02 12:52:39.125295",
"modified": "2023-11-14 18:33:22.585715",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice Item",
@@ -831,4 +832,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -415,7 +415,7 @@ def reconcile(doc: None | str = None) -> None:
# Update the parent doc about the exception
frappe.db.rollback()
traceback = frappe.get_traceback()
traceback = frappe.get_traceback(with_context=True)
if traceback:
message = "Traceback: <br>" + traceback
frappe.db.set_value("Process Payment Reconciliation Log", log, "error_log", message)

View File

@@ -110,7 +110,7 @@
"in_create": 1,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2023-04-21 17:36:26.642617",
"modified": "2023-11-02 11:32:12.254018",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Payment Reconciliation Log",
@@ -125,7 +125,19 @@
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"role": "Accounts Manager",
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "Accounts User",
"share": 1,
"write": 1
}

View File

@@ -15,6 +15,7 @@
"group_by",
"cost_center",
"territory",
"ignore_exchange_rate_revaluation_journals",
"column_break_14",
"to_date",
"finance_book",
@@ -374,10 +375,16 @@
"fieldname": "pdf_name",
"fieldtype": "Data",
"label": "PDF Name"
},
{
"default": "0",
"fieldname": "ignore_exchange_rate_revaluation_journals",
"fieldtype": "Check",
"label": "Ignore Exchange Rate Revaluation Journals"
}
],
"links": [],
"modified": "2023-08-28 12:59:53.071334",
"modified": "2023-12-18 12:20:08.965120",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Process Statement Of Accounts",

View File

@@ -64,6 +64,18 @@ def get_statement_dict(doc, get_statement_dict=False):
statement_dict = {}
ageing = ""
err_journals = None
if doc.report == "General Ledger" and doc.ignore_exchange_rate_revaluation_journals:
err_journals = frappe.db.get_all(
"Journal Entry",
filters={
"company": doc.company,
"docstatus": 1,
"voucher_type": ("in", ["Exchange Rate Revaluation", "Exchange Gain Or Loss"]),
},
as_list=True,
)
for entry in doc.customers:
if doc.include_ageing:
ageing = set_ageing(doc, entry)
@@ -76,6 +88,8 @@ def get_statement_dict(doc, get_statement_dict=False):
)
filters = get_common_filters(doc)
if err_journals:
filters.update({"voucher_no_not_in": [x[0] for x in err_journals]})
if doc.report == "General Ledger":
filters.update(get_gl_filters(doc, entry, tax_id, presentation_currency))

View File

@@ -31,7 +31,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
super.onload();
// Ignore linked advances
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger"];
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
if(!this.frm.doc.__islocal) {
// show credit_to in print format
@@ -164,6 +164,18 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
}
})
}, __("Get Items From"));
if (!this.frm.doc.is_return) {
frappe.db.get_single_value("Buying Settings", "maintain_same_rate").then((value) => {
if (value) {
this.frm.doc.items.forEach((item) => {
this.frm.fields_dict.items.grid.update_docfield_property(
"rate", "read_only", (item.purchase_receipt && item.pr_detail)
);
});
}
});
}
}
this.frm.toggle_reqd("supplier_warehouse", this.frm.doc.is_subcontracted);
@@ -181,7 +193,7 @@ erpnext.accounts.PurchaseInvoice = class PurchaseInvoice extends erpnext.buying.
}
this.frm.set_df_property("tax_withholding_category", "hidden", doc.apply_tds ? 0 : 1);
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(me.frm);
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(me.frm);
}
unblock_invoice() {

View File

@@ -383,7 +383,8 @@
"label": "Supplier Invoice No",
"oldfieldname": "bill_no",
"oldfieldtype": "Data",
"print_hide": 1
"print_hide": 1,
"search_index": 1
},
{
"fieldname": "column_break_15",
@@ -406,7 +407,8 @@
"no_copy": 1,
"options": "Purchase Invoice",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "section_addresses",
@@ -1592,7 +1594,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2023-10-16 16:24:51.886231",
"modified": "2023-11-03 15:47:30.319200",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -13,6 +13,7 @@ from erpnext.accounts.deferred_revenue import validate_service_stop_date
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
validate_docs_for_deferred_accounting,
validate_docs_for_voucher_types,
)
from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
check_if_return_invoice_linked_with_payment_entry,
@@ -494,6 +495,7 @@ class PurchaseInvoice(BuyingController):
def validate_for_repost(self):
self.validate_write_off_account()
self.validate_expense_account()
validate_docs_for_voucher_types(["Purchase Invoice"])
validate_docs_for_deferred_accounting([], [self.name])
def on_submit(self):
@@ -532,7 +534,11 @@ class PurchaseInvoice(BuyingController):
if self.update_stock == 1:
self.repost_future_sle_and_gle()
self.update_project()
if (
frappe.db.get_single_value("Buying Settings", "project_update_frequency") == "Each Transaction"
):
self.update_project()
update_linked_doc(self.doctype, self.name, self.inter_company_invoice_reference)
self.update_advance_tax_references()
@@ -970,11 +976,17 @@ class PurchaseInvoice(BuyingController):
)
assets = frappe.db.get_all(
"Asset", filters={"purchase_invoice": self.name, "item_code": item.item_code}
"Asset",
filters={"purchase_invoice": self.name, "item_code": item.item_code},
fields=["name", "asset_quantity"],
)
for asset in assets:
frappe.db.set_value("Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate))
frappe.db.set_value("Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate))
frappe.db.set_value(
"Asset", asset.name, "gross_purchase_amount", flt(item.valuation_rate) * asset.asset_quantity
)
frappe.db.set_value(
"Asset", asset.name, "purchase_receipt_amount", flt(item.valuation_rate) * asset.asset_quantity
)
def make_stock_adjustment_entry(
self, gl_entries, item, voucher_wise_stock_value, account_currency
@@ -1269,7 +1281,10 @@ class PurchaseInvoice(BuyingController):
if self.update_stock == 1:
self.repost_future_sle_and_gle()
self.update_project()
if (
frappe.db.get_single_value("Buying Settings", "project_update_frequency") == "Each Transaction"
):
self.update_project()
self.db_set("status", "Cancelled")
unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
@@ -1281,19 +1296,29 @@ class PurchaseInvoice(BuyingController):
"Repost Payment Ledger Items",
"Repost Accounting Ledger",
"Repost Accounting Ledger Items",
"Unreconcile Payment",
"Unreconcile Payment Entries",
"Payment Ledger Entry",
"Tax Withheld Vouchers",
)
self.update_advance_tax_references(cancel=1)
def update_project(self):
project_list = []
projects = frappe._dict()
for d in self.items:
if d.project and d.project not in project_list:
project = frappe.get_doc("Project", d.project)
project.update_purchase_costing()
project.db_update()
project_list.append(d.project)
if d.project:
if self.docstatus == 1:
projects[d.project] = projects.get(d.project, 0) + d.base_net_amount
elif self.docstatus == 2:
projects[d.project] = projects.get(d.project, 0) - d.base_net_amount
pj = frappe.qb.DocType("Project")
for proj, value in projects.items():
res = (
frappe.qb.from_(pj).select(pj.total_purchase_cost).where(pj.name == proj).for_update().run()
)
current_purchase_cost = res and res[0][0] or 0
frappe.db.set_value("Project", proj, "total_purchase_cost", current_purchase_cost + value)
def validate_supplier_invoice(self):
if self.bill_date:
@@ -1641,10 +1666,6 @@ def make_inter_company_sales_invoice(source_name, target_doc=None):
return make_inter_company_transaction("Purchase Invoice", source_name, target_doc)
def on_doctype_update():
frappe.db.add_index("Purchase Invoice", ["supplier", "is_return", "return_against"])
@frappe.whitelist()
def make_purchase_receipt(source_name, target_doc=None):
def update_item(obj, target, source_parent):
@@ -1686,6 +1707,4 @@ def make_purchase_receipt(source_name, target_doc=None):
target_doc,
)
doc.set_onload("ignore_price_list", True)
return doc

View File

@@ -1838,6 +1838,12 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
disable_dimension()
def test_repost_accounting_entries(self):
# update repost settings
settings = frappe.get_doc("Repost Accounting Ledger Settings")
if not [x for x in settings.allowed_types if x.document_type == "Purchase Invoice"]:
settings.append("allowed_types", {"document_type": "Purchase Invoice", "allowed": True})
settings.save()
pi = make_purchase_invoice(
rate=1000,
price_list_rate=1000,

View File

@@ -156,6 +156,7 @@
"width": "300px"
},
{
"fetch_from": "item_code.image",
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
@@ -491,6 +492,7 @@
"fieldtype": "Column Break"
},
{
"allow_on_submit": 1,
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
@@ -498,6 +500,7 @@
"print_hide": 1
},
{
"allow_on_submit": 1,
"default": ":Company",
"depends_on": "eval:!doc.is_fixed_asset",
"fieldname": "cost_center",
@@ -890,7 +893,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-10-03 21:01:01.824892",
"modified": "2023-12-25 22:00:28.043555",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -5,9 +5,7 @@ frappe.ui.form.on("Repost Accounting Ledger", {
setup: function(frm) {
frm.fields_dict['vouchers'].grid.get_field('voucher_type').get_query = function(doc) {
return {
filters: {
name: ['in', ['Purchase Invoice', 'Sales Invoice', 'Payment Entry', 'Journal Entry']],
}
query: "erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger.get_repost_allowed_types"
}
}

View File

@@ -10,9 +10,7 @@ from frappe.utils.data import comma_and
class RepostAccountingLedger(Document):
def __init__(self, *args, **kwargs):
super(RepostAccountingLedger, self).__init__(*args, **kwargs)
self._allowed_types = set(
["Purchase Invoice", "Sales Invoice", "Payment Entry", "Journal Entry"]
)
self._allowed_types = get_allowed_types_from_settings()
def validate(self):
self.validate_vouchers()
@@ -53,15 +51,7 @@ class RepostAccountingLedger(Document):
def validate_vouchers(self):
if self.vouchers:
# Validate voucher types
voucher_types = set([x.voucher_type for x in self.vouchers])
if disallowed_types := voucher_types.difference(self._allowed_types):
frappe.throw(
_("{0} types are not allowed. Only {1} are.").format(
frappe.bold(comma_and(list(disallowed_types))),
frappe.bold(comma_and(list(self._allowed_types))),
)
)
validate_docs_for_voucher_types([x.voucher_type for x in self.vouchers])
def get_existing_ledger_entries(self):
vouchers = [x.voucher_no for x in self.vouchers]
@@ -118,7 +108,7 @@ class RepostAccountingLedger(Document):
return rendered_page
def on_submit(self):
if len(self.vouchers) > 1:
if len(self.vouchers) > 5:
job_name = "repost_accounting_ledger_" + self.name
frappe.enqueue(
method="erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger.start_repost",
@@ -157,12 +147,19 @@ def start_repost(account_repost_doc=str) -> None:
doc.docstatus = 1
doc.make_gl_entries()
elif doc.doctype in ["Payment Entry", "Journal Entry"]:
elif doc.doctype in ["Payment Entry", "Journal Entry", "Expense Claim"]:
if not repost_doc.delete_cancelled_entries:
doc.make_gl_entries(1)
doc.make_gl_entries()
frappe.db.commit()
def get_allowed_types_from_settings():
return [
x.document_type
for x in frappe.db.get_all(
"Repost Allowed Types", filters={"allowed": True}, fields=["distinct(document_type)"]
)
]
def validate_docs_for_deferred_accounting(sales_docs, purchase_docs):
@@ -186,3 +183,37 @@ def validate_docs_for_deferred_accounting(sales_docs, purchase_docs):
frappe.bold(comma_and([x[0] for x in docs_with_deferred_expense + docs_with_deferred_revenue]))
)
)
def validate_docs_for_voucher_types(doc_voucher_types):
allowed_types = get_allowed_types_from_settings()
# Validate voucher types
voucher_types = set(doc_voucher_types)
if disallowed_types := voucher_types.difference(allowed_types):
message = "are" if len(disallowed_types) > 1 else "is"
frappe.throw(
_("{0} {1} not allowed to be reposted. Modify {2} to enable reposting.").format(
frappe.bold(comma_and(list(disallowed_types))),
message,
frappe.bold(
frappe.utils.get_link_to_form(
"Repost Accounting Ledger Settings", "Repost Accounting Ledger Settings"
)
),
)
)
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_repost_allowed_types(doctype, txt, searchfield, start, page_len, filters):
filters = {"allowed": True}
if txt:
filters.update({"document_type": ("like", f"%{txt}%")})
if allowed_types := frappe.db.get_all(
"Repost Allowed Types", filters=filters, fields=["distinct(document_type)"], as_list=1
):
return allowed_types
return []

View File

@@ -20,8 +20,9 @@ class TestRepostAccountingLedger(AccountsTestMixin, FrappeTestCase):
self.create_company()
self.create_customer()
self.create_item()
update_repost_settings()
def teadDown(self):
def tearDown(self):
frappe.db.rollback()
def test_01_basic_functions(self):
@@ -82,9 +83,6 @@ class TestRepostAccountingLedger(AccountsTestMixin, FrappeTestCase):
# Submit repost document
ral.save().submit()
# background jobs don't run on test cases. Manually triggering repost function.
start_repost(ral.name)
res = (
qb.from_(gl)
.select(gl.voucher_no, Sum(gl.debit).as_("debit"), Sum(gl.credit).as_("credit"))
@@ -169,26 +167,6 @@ class TestRepostAccountingLedger(AccountsTestMixin, FrappeTestCase):
pe = get_payment_entry(si.doctype, si.name)
pe.save().submit()
# without deletion flag set
ral = frappe.new_doc("Repost Accounting Ledger")
ral.company = self.company
ral.delete_cancelled_entries = False
ral.append("vouchers", {"voucher_type": si.doctype, "voucher_no": si.name})
ral.append("vouchers", {"voucher_type": pe.doctype, "voucher_no": pe.name})
ral.save()
# assert preview data is generated
preview = ral.generate_preview()
self.assertIsNotNone(preview)
ral.save().submit()
# background jobs don't run on test cases. Manually triggering repost function.
start_repost(ral.name)
self.assertIsNotNone(frappe.db.exists("GL Entry", {"voucher_no": si.name, "is_cancelled": 1}))
self.assertIsNotNone(frappe.db.exists("GL Entry", {"voucher_no": pe.name, "is_cancelled": 1}))
# with deletion flag set
ral = frappe.new_doc("Repost Accounting Ledger")
ral.company = self.company
@@ -197,6 +175,38 @@ class TestRepostAccountingLedger(AccountsTestMixin, FrappeTestCase):
ral.append("vouchers", {"voucher_type": pe.doctype, "voucher_no": pe.name})
ral.save().submit()
start_repost(ral.name)
self.assertIsNone(frappe.db.exists("GL Entry", {"voucher_no": si.name, "is_cancelled": 1}))
self.assertIsNone(frappe.db.exists("GL Entry", {"voucher_no": pe.name, "is_cancelled": 1}))
def test_05_without_deletion_flag(self):
si = create_sales_invoice(
item=self.item,
company=self.company,
customer=self.customer,
debit_to=self.debit_to,
parent_cost_center=self.cost_center,
cost_center=self.cost_center,
rate=100,
)
pe = get_payment_entry(si.doctype, si.name)
pe.save().submit()
# without deletion flag set
ral = frappe.new_doc("Repost Accounting Ledger")
ral.company = self.company
ral.delete_cancelled_entries = False
ral.append("vouchers", {"voucher_type": si.doctype, "voucher_no": si.name})
ral.append("vouchers", {"voucher_type": pe.doctype, "voucher_no": pe.name})
ral.save().submit()
self.assertIsNotNone(frappe.db.exists("GL Entry", {"voucher_no": si.name, "is_cancelled": 1}))
self.assertIsNotNone(frappe.db.exists("GL Entry", {"voucher_no": pe.name, "is_cancelled": 1}))
def update_repost_settings():
allowed_types = ["Sales Invoice", "Purchase Invoice", "Payment Entry", "Journal Entry"]
repost_settings = frappe.get_doc("Repost Accounting Ledger Settings")
for x in allowed_types:
repost_settings.append("allowed_types", {"document_type": x, "allowed": True})
repost_settings.save()

View File

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

View File

@@ -0,0 +1,46 @@
{
"actions": [],
"creation": "2023-11-07 09:57:20.619939",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"allowed_types"
],
"fields": [
{
"fieldname": "allowed_types",
"fieldtype": "Table",
"label": "Allowed Doctypes",
"options": "Repost Allowed Types"
}
],
"in_create": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-07 14:24:13.321522",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Accounting Ledger Settings",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"print": 1,
"read": 1,
"role": "Administrator",
"share": 1,
"write": 1
},
{
"read": 1,
"role": "System Manager",
"select": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class RepostAccountingLedgerSettings(Document):
pass

View File

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

View File

@@ -0,0 +1,45 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2023-11-07 09:58:03.595382",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"document_type",
"column_break_sfzb",
"allowed"
],
"fields": [
{
"fieldname": "document_type",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Doctype",
"options": "DocType"
},
{
"default": "0",
"fieldname": "allowed",
"fieldtype": "Check",
"in_list_view": 1,
"label": "Allowed"
},
{
"fieldname": "column_break_sfzb",
"fieldtype": "Column Break"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2023-11-07 10:01:39.217861",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Allowed Types",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

@@ -0,0 +1,9 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class RepostAllowedTypes(Document):
pass

View File

@@ -43,7 +43,7 @@ def start_payment_ledger_repost(docname=None):
except Exception as e:
frappe.db.rollback()
traceback = frappe.get_traceback()
traceback = frappe.get_traceback(with_context=True)
if traceback:
message = "Traceback: <br>" + traceback
frappe.db.set_value(repost_doc.doctype, repost_doc.name, "repost_error_log", message)

View File

@@ -34,7 +34,7 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
super.onload();
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payments", "Unreconcile Payment Entries"];
'POS Closing Entry', 'Journal Entry', 'Payment Entry', "Repost Payment Ledger", "Repost Accounting Ledger", "Unreconcile Payment", "Unreconcile Payment Entries"];
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
// show debit_to in print format
@@ -178,10 +178,9 @@ erpnext.accounts.SalesInvoiceController = class SalesInvoiceController extends e
}
}
erpnext.accounts.unreconcile_payments.add_unreconcile_btn(me.frm);
erpnext.accounts.unreconcile_payment.add_unreconcile_btn(me.frm);
}
make_maintenance_schedule() {
frappe.model.open_mapped_doc({
method: "erpnext.accounts.doctype.sales_invoice.sales_invoice.make_maintenance_schedule",
@@ -557,15 +556,6 @@ cur_frm.fields_dict.write_off_cost_center.get_query = function(doc) {
}
}
// Income Account in Details Table
// --------------------------------
cur_frm.set_query("income_account", "items", function(doc) {
return{
query: "erpnext.controllers.queries.get_income_account",
filters: {'company': doc.company}
}
});
// Cost Center in Details Table
// -----------------------------
cur_frm.fields_dict["items"].grid.get_field("cost_center").get_query = function(doc) {
@@ -660,6 +650,16 @@ frappe.ui.form.on('Sales Invoice', {
};
});
frm.set_query("income_account", "items", function() {
return{
query: "erpnext.controllers.queries.get_income_account",
filters: {
'company': frm.doc.company,
"disabled": 0
}
}
});
frm.custom_make_buttons = {
'Delivery Note': 'Delivery',
'Sales Invoice': 'Return / Credit Note',

View File

@@ -26,6 +26,7 @@
"is_return",
"return_against",
"update_billed_amount_in_sales_order",
"update_billed_amount_in_delivery_note",
"is_debit_note",
"amended_from",
"accounting_dimensions_section",
@@ -1612,7 +1613,8 @@
"hide_seconds": 1,
"label": "Inter Company Invoice Reference",
"options": "Purchase Invoice",
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "customer_group",
@@ -2144,6 +2146,13 @@
"fieldname": "use_company_roundoff_cost_center",
"fieldtype": "Check",
"label": "Use Company default Cost Center for Round off"
},
{
"default": "1",
"depends_on": "eval: doc.is_return",
"fieldname": "update_billed_amount_in_delivery_note",
"fieldtype": "Check",
"label": "Update Billed Amount in Delivery Note"
}
],
"icon": "fa fa-file-text",
@@ -2156,7 +2165,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2023-06-19 16:02:05.309332",
"modified": "2023-11-23 16:56:29.679499",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -17,6 +17,7 @@ from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
)
from erpnext.accounts.doctype.repost_accounting_ledger.repost_accounting_ledger import (
validate_docs_for_deferred_accounting,
validate_docs_for_voucher_types,
)
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
get_party_tax_withholding_details,
@@ -180,6 +181,7 @@ class SalesInvoice(SellingController):
self.validate_write_off_account()
self.validate_account_for_change_amount()
self.validate_income_account()
validate_docs_for_voucher_types(["Sales Invoice"])
validate_docs_for_deferred_accounting([self.name], [])
def validate_fixed_asset(self):
@@ -261,6 +263,7 @@ class SalesInvoice(SellingController):
self.update_status_updater_args()
self.update_prevdoc_status()
self.update_billing_status_in_dn()
self.clear_unallocated_mode_of_payments()
@@ -407,7 +410,7 @@ class SalesInvoice(SellingController):
"Repost Payment Ledger Items",
"Repost Accounting Ledger",
"Repost Accounting Ledger Items",
"Unreconcile Payments",
"Unreconcile Payment",
"Unreconcile Payment Entries",
"Payment Ledger Entry",
)
@@ -1036,7 +1039,7 @@ class SalesInvoice(SellingController):
def make_customer_gl_entry(self, gl_entries):
# Checked both rounding_adjustment and rounded_total
# because rounded_total had value even before introcution of posting GLE based on rounded total
# because rounded_total had value even before introduction of posting GLE based on rounded total
grand_total = (
self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
)
@@ -1271,7 +1274,7 @@ class SalesInvoice(SellingController):
if skip_change_gl_entries and payment_mode.account == self.account_for_change_amount:
payment_mode.base_amount -= flt(self.change_amount)
if payment_mode.amount:
if payment_mode.base_amount:
# POS, make payment entries
gl_entries.append(
self.get_gl_dict(
@@ -1433,6 +1436,8 @@ class SalesInvoice(SellingController):
)
def update_billing_status_in_dn(self, update_modified=True):
if self.is_return and not self.update_billed_amount_in_delivery_note:
return
updated_delivery_notes = []
for d in self.get("items"):
if d.dn_detail:
@@ -1929,7 +1934,6 @@ def make_delivery_note(source_name, target_doc=None):
set_missing_values,
)
doclist.set_onload("ignore_price_list", True)
return doclist
@@ -2191,9 +2195,18 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
def get_received_items(reference_name, doctype, reference_fieldname):
reference_field = "inter_company_invoice_reference"
if doctype == "Purchase Order":
reference_field = "inter_company_order_reference"
filters = {
reference_field: reference_name,
"docstatus": 1,
}
target_doctypes = frappe.get_all(
doctype,
filters={"inter_company_invoice_reference": reference_name, "docstatus": 1},
filters=filters,
as_list=True,
)
@@ -2375,10 +2388,6 @@ def get_loyalty_programs(customer):
return lp_details
def on_doctype_update():
frappe.db.add_index("Sales Invoice", ["customer", "is_return", "return_against"])
@frappe.whitelist()
def create_invoice_discounting(source_name, target_doc=None):
invoice = frappe.get_doc("Sales Invoice", source_name)

View File

@@ -782,6 +782,28 @@ class TestSalesInvoice(FrappeTestCase):
w = self.make()
self.assertEqual(w.outstanding_amount, w.base_rounded_total)
def test_rounded_total_with_cash_discount(self):
si = frappe.copy_doc(test_records[2])
item = copy.deepcopy(si.get("items")[0])
item.update(
{
"qty": 1,
"rate": 14960.66,
}
)
si.set("items", [item])
si.set("taxes", [])
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 1
si.insert()
self.assertEqual(si.grand_total, 14959.66)
self.assertEqual(si.rounded_total, 14960)
self.assertEqual(si.rounding_adjustment, 0.34)
def test_payment(self):
w = self.make()
@@ -2769,6 +2791,12 @@ class TestSalesInvoice(FrappeTestCase):
@change_settings("Selling Settings", {"enable_discount_accounting": 1})
def test_additional_discount_for_sales_invoice_with_discount_accounting_enabled(self):
from erpnext.accounts.doctype.repost_accounting_ledger.test_repost_accounting_ledger import (
update_repost_settings,
)
update_repost_settings()
additional_discount_account = create_account(
account_name="Discount Account",
parent_account="Indirect Expenses - _TC",

View File

@@ -167,6 +167,7 @@
"print_hide": 1
},
{
"fetch_from": "item_code.image",
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
@@ -891,7 +892,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2023-07-25 11:58:10.723833",
"modified": "2023-11-14 18:34:10.479329",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
@@ -901,4 +902,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -10,7 +10,7 @@ from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sal
from erpnext.accounts.test.accounts_mixin import AccountsTestMixin
class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
class TestUnreconcilePayment(AccountsTestMixin, FrappeTestCase):
def setUp(self):
self.create_company()
self.create_customer()
@@ -73,7 +73,7 @@ class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
unreconcile = frappe.get_doc(
{
"doctype": "Unreconcile Payments",
"doctype": "Unreconcile Payment",
"company": self.company,
"voucher_type": pe.doctype,
"voucher_no": pe.name,
@@ -138,7 +138,7 @@ class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
unreconcile = frappe.get_doc(
{
"doctype": "Unreconcile Payments",
"doctype": "Unreconcile Payment",
"company": self.company,
"voucher_type": pe2.doctype,
"voucher_no": pe2.name,
@@ -196,7 +196,7 @@ class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
unreconcile = frappe.get_doc(
{
"doctype": "Unreconcile Payments",
"doctype": "Unreconcile Payment",
"company": self.company,
"voucher_type": pe.doctype,
"voucher_no": pe.name,
@@ -281,7 +281,7 @@ class TestUnreconcilePayments(AccountsTestMixin, FrappeTestCase):
unreconcile = frappe.get_doc(
{
"doctype": "Unreconcile Payments",
"doctype": "Unreconcile Payment",
"company": self.company,
"voucher_type": pe2.doctype,
"voucher_no": pe2.name,

View File

@@ -1,7 +1,7 @@
// Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
// For license information, please see license.txt
frappe.ui.form.on("Unreconcile Payments", {
frappe.ui.form.on("Unreconcile Payment", {
refresh(frm) {
frm.set_query("voucher_type", function() {
return {

View File

@@ -21,7 +21,7 @@
"fieldtype": "Link",
"label": "Amended From",
"no_copy": 1,
"options": "Unreconcile Payments",
"options": "Unreconcile Payment",
"print_hide": 1,
"read_only": 1
},
@@ -61,7 +61,7 @@
"modified": "2023-08-28 17:42:50.261377",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Unreconcile Payments",
"name": "Unreconcile Payment",
"naming_rule": "Expression",
"owner": "Administrator",
"permissions": [
@@ -90,4 +90,4 @@
"sort_order": "DESC",
"states": [],
"track_changes": 1
}
}

View File

@@ -15,7 +15,7 @@ from erpnext.accounts.utils import (
)
class UnreconcilePayments(Document):
class UnreconcilePayment(Document):
def validate(self):
self.supported_types = ["Payment Entry", "Journal Entry"]
if not self.voucher_type in self.supported_types:
@@ -142,7 +142,7 @@ def create_unreconcile_doc_for_selection(selections=None):
selections = frappe.json.loads(selections)
# assuming each row is a unique voucher
for row in selections:
unrecon = frappe.new_doc("Unreconcile Payments")
unrecon = frappe.new_doc("Unreconcile Payment")
unrecon.company = row.get("company")
unrecon.voucher_type = row.get("voucher_type")
unrecon.voucher_no = row.get("voucher_no")

View File

@@ -556,7 +556,12 @@ def get_round_off_account_and_cost_center(
def make_reverse_gl_entries(
gl_entries=None, voucher_type=None, voucher_no=None, adv_adj=False, update_outstanding="Yes"
gl_entries=None,
voucher_type=None,
voucher_no=None,
adv_adj=False,
update_outstanding="Yes",
partial_cancel=False,
):
"""
Get original gl entries of the voucher
@@ -576,14 +581,19 @@ def make_reverse_gl_entries(
if gl_entries:
create_payment_ledger_entry(
gl_entries, cancel=1, adv_adj=adv_adj, update_outstanding=update_outstanding
gl_entries,
cancel=1,
adv_adj=adv_adj,
update_outstanding=update_outstanding,
partial_cancel=partial_cancel,
)
validate_accounting_period(gl_entries)
check_freezing_date(gl_entries[0]["posting_date"], adv_adj)
is_opening = any(d.get("is_opening") == "Yes" for d in gl_entries)
validate_against_pcv(is_opening, gl_entries[0]["posting_date"], gl_entries[0]["company"])
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
if not partial_cancel:
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
for entry in gl_entries:
new_gle = copy.deepcopy(entry)

View File

@@ -31,7 +31,12 @@ from erpnext.accounts.utils import get_fiscal_year
from erpnext.exceptions import InvalidAccountCurrency, PartyDisabled, PartyFrozen
from erpnext.utilities.regional import temporary_flag
PURCHASE_TRANSACTION_TYPES = {"Purchase Order", "Purchase Receipt", "Purchase Invoice"}
PURCHASE_TRANSACTION_TYPES = {
"Supplier Quotation",
"Purchase Order",
"Purchase Receipt",
"Purchase Invoice",
}
SALES_TRANSACTION_TYPES = {
"Quotation",
"Sales Order",
@@ -190,7 +195,7 @@ def set_address_details(
company_address=None,
shipping_address=None,
*,
ignore_permissions=False
ignore_permissions=False,
):
billing_address_field = (
"customer_address" if party_type == "Lead" else party_type.lower() + "_address"
@@ -231,8 +236,10 @@ def set_address_details(
if shipping_address:
party_details.update(
shipping_address=shipping_address,
shipping_address_display=render_address(shipping_address),
**get_fetch_values(doctype, "shipping_address", shipping_address)
shipping_address_display=render_address(
shipping_address, check_permissions=not ignore_permissions
),
**get_fetch_values(doctype, "shipping_address", shipping_address),
)
if party_details.company_address:
@@ -243,7 +250,7 @@ def set_address_details(
party_details.company_address_display
or render_address(party_details.company_address, check_permissions=False)
),
**get_fetch_values(doctype, "billing_address", party_details.company_address)
**get_fetch_values(doctype, "billing_address", party_details.company_address),
)
# shipping address - if not already set
@@ -251,7 +258,7 @@ def set_address_details(
party_details.update(
shipping_address=party_details.billing_address,
shipping_address_display=party_details.billing_address_display,
**get_fetch_values(doctype, "shipping_address", party_details.billing_address)
**get_fetch_values(doctype, "shipping_address", party_details.billing_address),
)
party_address, shipping_address = (
@@ -949,6 +956,9 @@ def get_partywise_advanced_payment_amount(
if party:
query = query.where(ple.party == party)
if invoice_doctypes := frappe.get_hooks("invoice_doctypes"):
query = query.where(ple.voucher_type.notin(invoice_doctypes))
data = query.run()
if data:
return frappe._dict(data)

View File

@@ -144,11 +144,21 @@ frappe.query_reports["Accounts Payable"] = {
"label": __("Show Future Payments"),
"fieldtype": "Check",
},
{
"fieldname": "for_revaluation_journals",
"label": __("Revaluation Journals"),
"fieldtype": "Check",
},
{
"fieldname": "in_party_currency",
"label": __("In Party Currency"),
"fieldtype": "Check",
},
{
"fieldname": "ignore_accounts",
"label": __("Group by Voucher"),
"fieldtype": "Check",
}
},
],

View File

@@ -40,6 +40,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
"range2": 60,
"range3": 90,
"range4": 120,
"in_party_currency": 1,
}
data = execute(filters)

View File

@@ -110,6 +110,11 @@ frappe.query_reports["Accounts Payable Summary"] = {
"fieldname":"based_on_payment_terms",
"label": __("Based On Payment Terms"),
"fieldtype": "Check",
},
{
"fieldname": "for_revaluation_journals",
"label": __("Revaluation Journals"),
"fieldtype": "Check",
}
],

View File

@@ -114,10 +114,13 @@ frappe.query_reports["Accounts Receivable"] = {
"reqd": 1
},
{
"fieldname": "customer_group",
"fieldname":"customer_group",
"label": __("Customer Group"),
"fieldtype": "Link",
"options": "Customer Group"
"fieldtype": "MultiSelectList",
"options": "Customer Group",
get_data: function(txt) {
return frappe.db.get_link_options('Customer Group', txt);
}
},
{
"fieldname": "payment_terms_template",
@@ -173,6 +176,16 @@ frappe.query_reports["Accounts Receivable"] = {
"label": __("Show Remarks"),
"fieldtype": "Check",
},
{
"fieldname": "for_revaluation_journals",
"label": __("Revaluation Journals"),
"fieldtype": "Check",
},
{
"fieldname": "in_party_currency",
"label": __("In Party Currency"),
"fieldtype": "Check",
},
{
"fieldname": "ignore_accounts",
"label": __("Group by Voucher"),

View File

@@ -7,7 +7,7 @@ from collections import OrderedDict
import frappe
from frappe import _, qb, scrub
from frappe.query_builder import Criterion
from frappe.query_builder.functions import Date, Sum
from frappe.query_builder.functions import Date, Substring, Sum
from frappe.utils import cint, cstr, flt, getdate, nowdate
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
@@ -28,8 +28,8 @@ from erpnext.accounts.utils import get_currency_precision
# 6. Configurable Ageing Groups (0-30, 30-60 etc) can be set via filters
# 7. For overpayment against an invoice with payment terms, there will be an additional row
# 8. Invoice details like Sales Persons, Delivery Notes are also fetched comma separated
# 9. Report amounts are in "Party Currency" if party is selected, or company currency for multi-party
# 10. This reports is based on all GL Entries that are made against account_type "Receivable" or "Payable"
# 9. Report amounts are in party currency if in_party_currency is selected, otherwise company currency
# 10. This report is based on Payment Ledger Entries
def execute(filters=None):
@@ -84,6 +84,9 @@ class ReceivablePayableReport(object):
self.total_row_map = {}
self.skip_total_row = 1
if self.filters.get("in_party_currency"):
self.skip_total_row = 1
def get_data(self):
self.get_ple_entries()
self.get_sales_invoices_or_customers_based_on_sales_person()
@@ -117,7 +120,7 @@ class ReceivablePayableReport(object):
for ple in self.ple_entries:
# get the balance object for voucher_type
if self.filters.get("ingore_accounts"):
if self.filters.get("ignore_accounts"):
key = (ple.voucher_type, ple.voucher_no, ple.party)
else:
key = (ple.account, ple.voucher_type, ple.voucher_no, ple.party)
@@ -145,7 +148,7 @@ class ReceivablePayableReport(object):
if self.filters.get("group_by_party"):
self.init_subtotal_row(ple.party)
if self.filters.get("group_by_party"):
if self.filters.get("group_by_party") and not self.filters.get("in_party_currency"):
self.init_subtotal_row("Total")
def get_invoices(self, ple):
@@ -188,7 +191,7 @@ class ReceivablePayableReport(object):
):
return
if self.filters.get("ingore_accounts"):
if self.filters.get("ignore_accounts"):
key = (ple.against_voucher_type, ple.against_voucher_no, ple.party)
else:
key = (ple.account, ple.against_voucher_type, ple.against_voucher_no, ple.party)
@@ -200,7 +203,7 @@ class ReceivablePayableReport(object):
if ple.against_voucher_no in self.return_entries:
return_against = self.return_entries.get(ple.against_voucher_no)
if return_against:
if self.filters.get("ingore_accounts"):
if self.filters.get("ignore_accounts"):
key = (ple.against_voucher_type, return_against, ple.party)
else:
key = (ple.account, ple.against_voucher_type, return_against, ple.party)
@@ -209,7 +212,7 @@ class ReceivablePayableReport(object):
if not row:
# no invoice, this is an invoice / stand-alone payment / credit note
if self.filters.get("ingore_accounts"):
if self.filters.get("ignore_accounts"):
row = self.voucher_balance.get((ple.voucher_type, ple.voucher_no, ple.party))
else:
row = self.voucher_balance.get((ple.account, ple.voucher_type, ple.voucher_no, ple.party))
@@ -224,8 +227,7 @@ class ReceivablePayableReport(object):
if not row:
return
# amount in "Party Currency", if its supplied. If not, amount in company currency
if self.filters.get("party_type") and self.filters.get("party"):
if self.filters.get("in_party_currency") or self.filters.get("party_account"):
amount = ple.amount_in_account_currency
else:
amount = ple.amount
@@ -244,8 +246,12 @@ class ReceivablePayableReport(object):
row.invoiced_in_account_currency += amount_in_account_currency
else:
if self.is_invoice(ple):
row.credit_note -= amount
row.credit_note_in_account_currency -= amount_in_account_currency
if row.voucher_no == ple.voucher_no == ple.against_voucher_no:
row.paid -= amount
row.paid_in_account_currency -= amount_in_account_currency
else:
row.credit_note -= amount
row.credit_note_in_account_currency -= amount_in_account_currency
else:
row.paid -= amount
row.paid_in_account_currency -= amount_in_account_currency
@@ -256,8 +262,10 @@ class ReceivablePayableReport(object):
def update_sub_total_row(self, row, party):
total_row = self.total_row_map.get(party)
for field in self.get_currency_fields():
total_row[field] += row.get(field, 0.0)
if total_row:
for field in self.get_currency_fields():
total_row[field] += row.get(field, 0.0)
total_row["currency"] = row.get("currency", "")
def append_subtotal_row(self, party):
sub_total_row = self.total_row_map.get(party)
@@ -281,11 +289,20 @@ class ReceivablePayableReport(object):
row.invoice_grand_total = row.invoiced
if (abs(row.outstanding) > 1.0 / 10**self.currency_precision) and (
(abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision)
or (row.voucher_no in self.err_journals)
):
must_consider = False
if self.filters.get("for_revaluation_journals"):
if (abs(row.outstanding) > 0.0 / 10**self.currency_precision) or (
(abs(row.outstanding_in_account_currency) > 0.0 / 10**self.currency_precision)
):
must_consider = True
else:
if (abs(row.outstanding) > 1.0 / 10**self.currency_precision) and (
(abs(row.outstanding_in_account_currency) > 1.0 / 10**self.currency_precision)
or (row.voucher_no in self.err_journals)
):
must_consider = True
if must_consider:
# non-zero oustanding, we must consider this row
if self.is_invoice(row) and self.filters.based_on_payment_terms:
@@ -309,7 +326,7 @@ class ReceivablePayableReport(object):
if self.filters.get("group_by_party"):
self.append_subtotal_row(self.previous_party)
if self.data:
self.data.append(self.total_row_map.get("Total"))
self.data.append(self.total_row_map.get("Total", {}))
def append_row(self, row):
self.allocate_future_payments(row)
@@ -440,7 +457,7 @@ class ReceivablePayableReport(object):
party_details = self.get_party_details(row.party) or {}
row.update(party_details)
if self.filters.get("party_type") and self.filters.get("party"):
if self.filters.get("in_party_currency") or self.filters.get("party_account"):
row.currency = row.account_currency
else:
row.currency = self.company_currency
@@ -732,6 +749,7 @@ class ReceivablePayableReport(object):
query = (
qb.from_(ple)
.select(
ple.name,
ple.account,
ple.voucher_type,
ple.voucher_no,
@@ -745,13 +763,20 @@ class ReceivablePayableReport(object):
ple.account_currency,
ple.amount,
ple.amount_in_account_currency,
ple.remarks,
)
.where(ple.delinked == 0)
.where(Criterion.all(self.qb_selection_filter))
.where(Criterion.any(self.or_filters))
)
if self.filters.get("show_remarks"):
if remarks_length := frappe.db.get_single_value(
"Accounts Settings", "receivable_payable_remarks_length"
):
query = query.select(Substring(ple.remarks, 1, remarks_length).as_("remarks"))
else:
query = query.select(ple.remarks)
if self.filters.get("group_by_party"):
query = query.orderby(self.ple.party, self.ple.posting_date)
else:
@@ -837,7 +862,13 @@ class ReceivablePayableReport(object):
self.customer = qb.DocType("Customer")
if self.filters.get("customer_group"):
self.get_hierarchical_filters("Customer Group", "customer_group")
groups = get_customer_group_with_children(self.filters.customer_group)
customers = (
qb.from_(self.customer)
.select(self.customer.name)
.where(self.customer["customer_group"].isin(groups))
)
self.qb_selection_filter.append(self.ple.party.isin(customers))
if self.filters.get("territory"):
self.get_hierarchical_filters("Territory", "territory")
@@ -1062,7 +1093,7 @@ class ReceivablePayableReport(object):
)
if self.filters.show_remarks:
self.add_column(label=_("Remarks"), fieldname="remarks", fieldtype="Text", width=200),
self.add_column(label=_("Remarks"), fieldname="remarks", fieldtype="Text", width=200)
def add_column(self, label, fieldname=None, fieldtype="Currency", options=None, width=120):
if not fieldname:
@@ -1129,3 +1160,19 @@ class ReceivablePayableReport(object):
.run()
)
self.err_journals = [x[0] for x in results] if results else []
def get_customer_group_with_children(customer_groups):
if not isinstance(customer_groups, list):
customer_groups = [d.strip() for d in customer_groups.strip().split(",") if d]
all_customer_groups = []
for d in customer_groups:
if frappe.db.exists("Customer Group", d):
lft, rgt = frappe.db.get_value("Customer Group", d, ["lft", "rgt"])
children = frappe.get_all("Customer Group", filters={"lft": [">=", lft], "rgt": ["<=", rgt]})
all_customer_groups += [c.name for c in children]
else:
frappe.throw(_("Customer Group: {0} does not exist").format(d))
return list(set(all_customer_groups))

View File

@@ -76,6 +76,41 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
return credit_note
def test_pos_receivable(self):
filters = {
"company": self.company,
"party_type": "Customer",
"party": [self.customer],
"report_date": add_days(today(), 2),
"based_on_payment_terms": 0,
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
"show_remarks": False,
}
pos_inv = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)
pos_inv.posting_date = add_days(today(), 2)
pos_inv.is_pos = 1
pos_inv.append(
"payments",
frappe._dict(
mode_of_payment="Cash",
amount=flt(pos_inv.grand_total / 2),
),
)
pos_inv.disable_rounded_total = 1
pos_inv.save()
pos_inv.submit()
report = execute(filters)
expected_data = [[pos_inv.grand_total, pos_inv.paid_amount, 0]]
row = report[1][-1]
self.assertEqual(expected_data[0], [row.invoiced, row.paid, row.credit_note])
pos_inv.cancel()
def test_accounts_receivable(self):
filters = {
"company": self.company,
@@ -475,6 +510,30 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
report = execute(filters)[1]
self.assertEqual(len(report), 0)
def test_multi_customer_group_filter(self):
si = self.create_sales_invoice()
cus_group = frappe.db.get_value("Customer", self.customer, "customer_group")
# Create a list of customer groups, e.g., ["Group1", "Group2"]
cus_groups_list = [cus_group, "_Test Customer Group 1"]
filters = {
"company": self.company,
"report_date": today(),
"range1": 30,
"range2": 60,
"range3": 90,
"range4": 120,
"customer_group": cus_groups_list, # Use the list of customer groups
}
report = execute(filters)[1]
# Assert that the report contains data for the specified customer groups
self.assertTrue(len(report) > 0)
for row in report:
# Assert that the customer group of each row is in the list of customer groups
self.assertIn(row.customer_group, cus_groups_list)
def test_party_account_filter(self):
si1 = self.create_sales_invoice()
self.customer2 = (
@@ -520,7 +579,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
filters.update({"party_account": self.debtors_usd})
report = execute(filters)[1]
self.assertEqual(len(report), 1)
expected_data = [8000.0, 8000.0, self.debtors_usd, si2.currency]
expected_data = [100.0, 100.0, self.debtors_usd, si2.currency]
row = report[0]
self.assertEqual(
expected_data, [row.invoiced, row.outstanding, row.party_account, row.account_currency]
@@ -557,6 +616,7 @@ class TestAccountsReceivable(AccountsTestMixin, FrappeTestCase):
"range2": 60,
"range3": 90,
"range4": 120,
"in_party_currency": 1,
}
si = self.create_sales_invoice(no_payment_schedule=True, do_not_submit=True)

View File

@@ -139,6 +139,11 @@ frappe.query_reports["Accounts Receivable Summary"] = {
"label": __("Show GL Balance"),
"fieldtype": "Check",
},
{
"fieldname": "for_revaluation_journals",
"label": __("Revaluation Journals"),
"fieldtype": "Check",
}
],
onload: function(report) {

View File

@@ -8,6 +8,7 @@ from frappe.utils import cint, flt
from erpnext.accounts.party import get_partywise_advanced_payment_amount
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
from erpnext.accounts.utils import get_currency_precision
def execute(filters=None):
@@ -35,6 +36,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
def get_data(self, args):
self.data = []
self.receivables = ReceivablePayableReport(self.filters).run(args)[1]
self.currency_precision = get_currency_precision() or 2
self.get_party_total(args)
@@ -58,7 +60,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
gl_balance_map = get_gl_balance(self.filters.report_date, self.filters.company)
for party, party_dict in self.party_total.items():
if party_dict.outstanding == 0:
if flt(party_dict.outstanding, self.currency_precision) == 0:
continue
row = frappe._dict()

View File

@@ -31,6 +31,18 @@ frappe.query_reports["Asset Depreciation Ledger"] = {
"fieldtype": "Link",
"options": "Asset"
},
{
"fieldname":"asset_category",
"label": __("Asset Category"),
"fieldtype": "Link",
"options": "Asset Category"
},
{
"fieldname":"cost_center",
"label": __("Cost Center"),
"fieldtype": "Link",
"options": "Cost Center"
},
{
"fieldname":"finance_book",
"label": __("Finance Book"),
@@ -38,10 +50,10 @@ frappe.query_reports["Asset Depreciation Ledger"] = {
"options": "Finance Book"
},
{
"fieldname":"asset_category",
"label": __("Asset Category"),
"fieldtype": "Link",
"options": "Asset Category"
}
"fieldname": "include_default_book_assets",
"label": __("Include Default FB Assets"),
"fieldtype": "Check",
"default": 1
},
]
}

View File

@@ -1,15 +1,15 @@
{
"add_total_row": 1,
"add_total_row": 0,
"columns": [],
"creation": "2016-04-08 14:49:58.133098",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 2,
"idx": 6,
"is_standard": "Yes",
"letterhead": null,
"modified": "2023-07-26 21:05:33.554778",
"modified": "2023-11-08 20:17:05.774211",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Asset Depreciation Ledger",

View File

@@ -4,7 +4,7 @@
import frappe
from frappe import _
from frappe.utils import flt
from frappe.utils import cstr, flt
def execute(filters=None):
@@ -32,7 +32,6 @@ def get_data(filters):
filters_data.append(["against_voucher", "=", filters.get("asset")])
if filters.get("asset_category"):
assets = frappe.db.sql_list(
"""select name from tabAsset
where asset_category = %s and docstatus=1""",
@@ -41,12 +40,27 @@ def get_data(filters):
filters_data.append(["against_voucher", "in", assets])
if filters.get("finance_book"):
filters_data.append(["finance_book", "in", ["", filters.get("finance_book")]])
company_fb = frappe.get_cached_value("Company", filters.get("company"), "default_finance_book")
if filters.get("include_default_book_assets") and company_fb:
if filters.get("finance_book") and cstr(filters.get("finance_book")) != cstr(company_fb):
frappe.throw(_("To use a different finance book, please uncheck 'Include Default FB Assets'"))
else:
finance_book = company_fb
elif filters.get("finance_book"):
finance_book = filters.get("finance_book")
else:
finance_book = None
if finance_book:
or_filters_data = [["finance_book", "in", ["", finance_book]], ["finance_book", "is", "not set"]]
else:
or_filters_data = [["finance_book", "in", [""]], ["finance_book", "is", "not set"]]
gl_entries = frappe.get_all(
"GL Entry",
filters=filters_data,
or_filters=or_filters_data,
fields=["against_voucher", "debit_in_account_currency as debit", "voucher_no", "posting_date"],
order_by="against_voucher, posting_date",
)
@@ -61,7 +75,9 @@ def get_data(filters):
asset_data = assets_details.get(d.against_voucher)
if asset_data:
if not asset_data.get("accumulated_depreciation_amount"):
asset_data.accumulated_depreciation_amount = d.debit
asset_data.accumulated_depreciation_amount = d.debit + asset_data.get(
"opening_accumulated_depreciation"
)
else:
asset_data.accumulated_depreciation_amount += d.debit
@@ -70,7 +86,7 @@ def get_data(filters):
{
"depreciation_amount": d.debit,
"depreciation_date": d.posting_date,
"amount_after_depreciation": (
"value_after_depreciation": (
flt(row.gross_purchase_amount) - flt(row.accumulated_depreciation_amount)
),
"depreciation_entry": d.voucher_no,
@@ -88,10 +104,12 @@ def get_assets_details(assets):
fields = [
"name as asset",
"gross_purchase_amount",
"opening_accumulated_depreciation",
"asset_category",
"status",
"depreciation_method",
"purchase_date",
"cost_center",
]
for d in frappe.get_all("Asset", fields=fields, filters={"name": ("in", assets)}):
@@ -121,6 +139,12 @@ def get_columns():
"fieldtype": "Currency",
"width": 120,
},
{
"label": _("Opening Accumulated Depreciation"),
"fieldname": "opening_accumulated_depreciation",
"fieldtype": "Currency",
"width": 140,
},
{
"label": _("Depreciation Amount"),
"fieldname": "depreciation_amount",
@@ -134,8 +158,8 @@ def get_columns():
"width": 210,
},
{
"label": _("Amount After Depreciation"),
"fieldname": "amount_after_depreciation",
"label": _("Value After Depreciation"),
"fieldname": "value_after_depreciation",
"fieldtype": "Currency",
"width": 180,
},
@@ -153,12 +177,13 @@ def get_columns():
"options": "Asset Category",
"width": 120,
},
{"label": _("Current Status"), "fieldname": "status", "fieldtype": "Data", "width": 120},
{
"label": _("Depreciation Method"),
"fieldname": "depreciation_method",
"fieldtype": "Data",
"width": 130,
"label": _("Cost Center"),
"fieldtype": "Link",
"fieldname": "cost_center",
"options": "Cost Center",
"width": 100,
},
{"label": _("Current Status"), "fieldname": "status", "fieldtype": "Data", "width": 120},
{"label": _("Purchase Date"), "fieldname": "purchase_date", "fieldtype": "Date", "width": 120},
]

View File

@@ -15,7 +15,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Balance Sheet"]["filters"].push({
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"label": __("Include Default FB Entries"),
"fieldtype": "Check",
"default": 1
});

View File

@@ -2,7 +2,44 @@
// License: GNU General Public License v3. See license.txt
frappe.query_reports["Budget Variance Report"] = {
"filters": [
"filters": get_filters(),
"formatter": function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
if (column.fieldname.includes(__("variance"))) {
if (data[column.fieldname] < 0) {
value = "<span style='color:red'>" + value + "</span>";
}
else if (data[column.fieldname] > 0) {
value = "<span style='color:green'>" + value + "</span>";
}
}
return value;
}
}
function get_filters() {
function get_dimensions() {
let result = [];
frappe.call({
method: "erpnext.accounts.doctype.accounting_dimension.accounting_dimension.get_dimensions",
args: {
'with_cost_center_and_project': true
},
async: false,
callback: function(r) {
if(!r.exc) {
result = r.message[0].map(elem => elem.document_type);
}
}
});
return result;
}
let budget_against_options = get_dimensions();
let filters = [
{
fieldname: "from_fiscal_year",
label: __("From Fiscal Year"),
@@ -44,9 +81,13 @@ frappe.query_reports["Budget Variance Report"] = {
fieldname: "budget_against",
label: __("Budget Against"),
fieldtype: "Select",
options: ["Cost Center", "Project"],
options: budget_against_options,
default: "Cost Center",
reqd: 1,
get_data: function() {
console.log(this.options);
return ["Emacs", "Rocks"];
},
on_change: function() {
frappe.query_report.set_filter_value("budget_against_filter", []);
frappe.query_report.refresh();
@@ -71,24 +112,8 @@ frappe.query_reports["Budget Variance Report"] = {
fieldtype: "Check",
default: 0,
},
],
"formatter": function (value, row, column, data, default_formatter) {
value = default_formatter(value, row, column, data);
]
if (column.fieldname.includes(__("variance"))) {
if (data[column.fieldname] < 0) {
value = "<span style='color:red'>" + value + "</span>";
}
else if (data[column.fieldname] > 0) {
value = "<span style='color:green'>" + value + "</span>";
}
}
return value;
}
return filters;
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Budget Variance Report"].filters[4].options.push(dimension["document_type"]);
});

View File

@@ -16,7 +16,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
frappe.query_reports["Cash Flow"]["filters"].push(
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"label": __("Include Default FB Entries"),
"fieldtype": "Check",
"default": 1
}

View File

@@ -105,7 +105,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"label": __("Include Default FB Entries"),
"fieldtype": "Check",
"default": 1
},

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _, scrub
from frappe import _, qb, scrub
from frappe.utils import getdate, nowdate
@@ -38,7 +38,6 @@ class PartyLedgerSummaryReport(object):
"""
Additional Columns for 'User Permission' based access control
"""
from frappe import qb
if self.filters.party_type == "Customer":
self.territories = frappe._dict({})
@@ -365,13 +364,29 @@ class PartyLedgerSummaryReport(object):
def get_party_adjustment_amounts(self):
conditions = self.prepare_conditions()
income_or_expense = (
"Expense Account" if self.filters.party_type == "Customer" else "Income Account"
account_type = "Expense Account" if self.filters.party_type == "Customer" else "Income Account"
income_or_expense_accounts = frappe.db.get_all(
"Account", filters={"account_type": account_type, "company": self.filters.company}, pluck="name"
)
invoice_dr_or_cr = "debit" if self.filters.party_type == "Customer" else "credit"
reverse_dr_or_cr = "credit" if self.filters.party_type == "Customer" else "debit"
round_off_account = frappe.get_cached_value("Company", self.filters.company, "round_off_account")
gl = qb.DocType("GL Entry")
if not income_or_expense_accounts:
# prevent empty 'in' condition
income_or_expense_accounts.append("")
accounts_query = (
qb.from_(gl)
.select(gl.voucher_type, gl.voucher_no)
.where(
(gl.account.isin(income_or_expense_accounts))
& (gl.posting_date.gte(self.filters.from_date))
& (gl.posting_date.lte(self.filters.to_date))
)
)
gl_entries = frappe.db.sql(
"""
select
@@ -381,16 +396,15 @@ class PartyLedgerSummaryReport(object):
where
docstatus < 2 and is_cancelled = 0
and (voucher_type, voucher_no) in (
select voucher_type, voucher_no from `tabGL Entry` gle, `tabAccount` acc
where acc.name = gle.account and acc.account_type = '{income_or_expense}'
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2
{accounts_query}
) and (voucher_type, voucher_no) in (
select voucher_type, voucher_no from `tabGL Entry` gle
where gle.party_type=%(party_type)s and ifnull(party, '') != ''
and gle.posting_date between %(from_date)s and %(to_date)s and gle.docstatus < 2 {conditions}
)
""".format(
conditions=conditions, income_or_expense=income_or_expense
""".format(
accounts_query=accounts_query,
conditions=conditions,
),
self.filters,
as_dict=True,
@@ -414,7 +428,7 @@ class PartyLedgerSummaryReport(object):
elif gle.party:
parties.setdefault(gle.party, 0)
parties[gle.party] += gle.get(reverse_dr_or_cr) - gle.get(invoice_dr_or_cr)
elif frappe.get_cached_value("Account", gle.account, "account_type") == income_or_expense:
elif frappe.get_cached_value("Account", gle.account, "account_type") == account_type:
accounts.setdefault(gle.account, 0)
accounts[gle.account] += gle.get(invoice_dr_or_cr) - gle.get(reverse_dr_or_cr)
else:

View File

@@ -8,7 +8,17 @@ import re
import frappe
from frappe import _
from frappe.utils import add_days, add_months, cint, cstr, flt, formatdate, get_first_day, getdate
from frappe.utils import (
add_days,
add_months,
cint,
cstr,
flt,
formatdate,
get_first_day,
getdate,
today,
)
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
@@ -43,6 +53,8 @@ def get_period_list(
year_start_date = getdate(period_start_date)
year_end_date = getdate(period_end_date)
year_end_date = getdate(today()) if year_end_date > getdate(today()) else year_end_date
months_to_add = {"Yearly": 12, "Half-Yearly": 6, "Quarterly": 3, "Monthly": 1}[periodicity]
period_list = []
@@ -561,9 +573,7 @@ def apply_additional_conditions(doctype, query, from_date, ignore_closing_entrie
company_fb = frappe.get_cached_value("Company", filters.company, "default_finance_book")
if filters.finance_book and company_fb and cstr(filters.finance_book) != cstr(company_fb):
frappe.throw(
_("To use a different finance book, please uncheck 'Include Default Book Entries'")
)
frappe.throw(_("To use a different finance book, please uncheck 'Include Default FB Entries'"))
query = query.where(
(gl_entry.finance_book.isin([cstr(filters.finance_book), cstr(company_fb), ""]))

View File

@@ -79,7 +79,9 @@ class General_Payment_Ledger_Comparison(object):
.select(
gle.company,
gle.account,
gle.voucher_type,
gle.voucher_no,
gle.party_type,
gle.party,
outstanding,
)
@@ -89,7 +91,9 @@ class General_Payment_Ledger_Comparison(object):
& (gle.account.isin(val.accounts))
)
.where(Criterion.all(filter_criterion))
.groupby(gle.company, gle.account, gle.voucher_no, gle.party)
.groupby(
gle.company, gle.account, gle.voucher_type, gle.voucher_no, gle.party_type, gle.party
)
.run()
)
@@ -112,7 +116,13 @@ class General_Payment_Ledger_Comparison(object):
self.account_types[acc_type].ple = (
qb.from_(ple)
.select(
ple.company, ple.account, ple.voucher_no, ple.party, Sum(ple.amount).as_("outstanding")
ple.company,
ple.account,
ple.voucher_type,
ple.voucher_no,
ple.party_type,
ple.party,
Sum(ple.amount).as_("outstanding"),
)
.where(
(ple.company == self.filters.company)
@@ -120,7 +130,9 @@ class General_Payment_Ledger_Comparison(object):
& (ple.account.isin(val.accounts))
)
.where(Criterion.all(filter_criterion))
.groupby(ple.company, ple.account, ple.voucher_no, ple.party)
.groupby(
ple.company, ple.account, ple.voucher_type, ple.voucher_no, ple.party_type, ple.party
)
.run()
)
@@ -138,12 +150,12 @@ class General_Payment_Ledger_Comparison(object):
self.diff = frappe._dict({})
for x in self.variation_in_payment_ledger:
self.diff[(x[0], x[1], x[2], x[3])] = frappe._dict({"gl_balance": x[4]})
self.diff[(x[0], x[1], x[2], x[3], x[4], x[5])] = frappe._dict({"gl_balance": x[6]})
for x in self.variation_in_general_ledger:
self.diff.setdefault((x[0], x[1], x[2], x[3]), frappe._dict({"gl_balance": 0.0})).update(
frappe._dict({"pl_balance": x[4]})
)
self.diff.setdefault(
(x[0], x[1], x[2], x[3], x[4], x[5]), frappe._dict({"gl_balance": 0.0})
).update(frappe._dict({"pl_balance": x[6]}))
def generate_data(self):
self.data = []
@@ -151,8 +163,12 @@ class General_Payment_Ledger_Comparison(object):
self.data.append(
frappe._dict(
{
"voucher_no": key[2],
"party": key[3],
"company": key[0],
"account": key[1],
"voucher_type": key[2],
"voucher_no": key[3],
"party_type": key[4],
"party": key[5],
"gl_balance": val.gl_balance,
"pl_balance": val.pl_balance,
}
@@ -162,12 +178,52 @@ class General_Payment_Ledger_Comparison(object):
def get_columns(self):
self.columns = []
options = None
self.columns.append(
dict(
label=_("Company"),
fieldname="company",
fieldtype="Link",
options="Company",
width="100",
)
)
self.columns.append(
dict(
label=_("Account"),
fieldname="account",
fieldtype="Link",
options="Account",
width="100",
)
)
self.columns.append(
dict(
label=_("Voucher Type"),
fieldname="voucher_type",
fieldtype="Link",
options="DocType",
width="100",
)
)
self.columns.append(
dict(
label=_("Voucher No"),
fieldname="voucher_no",
fieldtype="Data",
options=options,
fieldtype="Dynamic Link",
options="voucher_type",
width="100",
)
)
self.columns.append(
dict(
label=_("Party Type"),
fieldname="party_type",
fieldtype="Link",
options="DocType",
width="100",
)
)
@@ -176,8 +232,8 @@ class General_Payment_Ledger_Comparison(object):
dict(
label=_("Party"),
fieldname="party",
fieldtype="Data",
options=options,
fieldtype="Dynamic Link",
options="party_type",
width="100",
)
)

View File

@@ -50,7 +50,11 @@ class TestGeneralAndPaymentLedger(FrappeTestCase, AccountsTestMixin):
self.assertEqual(len(data), 1)
expected = {
"company": sinv.company,
"account": sinv.debit_to,
"voucher_type": sinv.doctype,
"voucher_no": sinv.name,
"party_type": "Customer",
"party": sinv.customer,
"gl_balance": sinv.grand_total,
"pl_balance": sinv.grand_total - 1,

View File

@@ -175,7 +175,7 @@ frappe.query_reports["General Ledger"] = {
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"label": __("Include Default FB Entries"),
"fieldtype": "Check",
"default": 1
},
@@ -188,7 +188,13 @@ frappe.query_reports["General Ledger"] = {
"fieldname": "show_net_values_in_party_account",
"label": __("Show Net Values in Party Account"),
"fieldtype": "Check"
},
{
"fieldname": "show_remarks",
"label": __("Show Remarks"),
"fieldtype": "Check"
}
]
}

View File

@@ -163,6 +163,14 @@ def get_gl_entries(filters, accounting_dimensions):
select_fields = """, debit, credit, debit_in_account_currency,
credit_in_account_currency """
if filters.get("show_remarks"):
if remarks_length := frappe.db.get_single_value(
"Accounts Settings", "general_ledger_remarks_length"
):
select_fields += f",substr(remarks, 1, {remarks_length}) as 'remarks'"
else:
select_fields += """,remarks"""
order_by_statement = "order by posting_date, account, creation"
if filters.get("include_dimensions"):
@@ -189,7 +197,7 @@ def get_gl_entries(filters, accounting_dimensions):
voucher_type, voucher_no, {dimension_fields}
cost_center, project,
against_voucher_type, against_voucher, account_currency,
remarks, against, is_opening, creation {select_fields}
against, is_opening, creation {select_fields}
from `tabGL Entry`
where company=%(company)s {conditions}
{order_by_statement}
@@ -223,6 +231,9 @@ def get_conditions(filters):
if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s")
if filters.get("voucher_no_not_in"):
conditions.append("voucher_no not in %(voucher_no_not_in)s")
if filters.get("group_by") == "Group by Party" and not filters.get("party_type"):
conditions.append("party_type in ('Customer', 'Supplier')")
@@ -249,9 +260,7 @@ def get_conditions(filters):
if filters.get("company_fb") and cstr(filters.get("finance_book")) != cstr(
filters.get("company_fb")
):
frappe.throw(
_("To use a different finance book, please uncheck 'Include Default Book Entries'")
)
frappe.throw(_("To use a different finance book, please uncheck 'Include Default FB Entries'"))
else:
conditions.append("(finance_book in (%(finance_book)s, '') OR finance_book IS NULL)")
else:
@@ -276,7 +285,8 @@ def get_conditions(filters):
if accounting_dimensions:
for dimension in accounting_dimensions:
if not dimension.disabled:
# Ignore 'Finance Book' set up as dimension in below logic, as it is already handled in above section
if not dimension.disabled and dimension.document_type != "Finance Book":
if filters.get(dimension.fieldname):
if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
filters[dimension.fieldname] = get_dimension_with_children(
@@ -593,8 +603,10 @@ def get_columns(filters):
"width": 100,
},
{"label": _("Supplier Invoice No"), "fieldname": "bill_no", "fieldtype": "Data", "width": 100},
{"label": _("Remarks"), "fieldname": "remarks", "width": 400},
]
)
if filters.get("show_remarks"):
columns.extend([{"label": _("Remarks"), "fieldname": "remarks", "width": 400}])
return columns

View File

@@ -309,7 +309,8 @@ def get_conditions(filters):
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
if additional_query_columns:
additional_query_columns = "," + ",".join(additional_query_columns)
return frappe.db.sql(
"""
select

View File

@@ -381,7 +381,8 @@ def get_group_by_conditions(filters, doctype):
def get_items(filters, additional_query_columns, additional_conditions=None):
conditions = get_conditions(filters, additional_conditions)
if additional_query_columns:
additional_query_columns = "," + ",".join(additional_query_columns)
return frappe.db.sql(
"""
select

View File

@@ -119,8 +119,4 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
"initial_depth": 3
}
erpnext.dimension_filters.forEach((dimension) => {
frappe.query_reports["Profitability Analysis"].filters[1].options.push(dimension["document_type"]);
});
});

View File

@@ -52,6 +52,12 @@ frappe.query_reports["Purchase Register"] = {
"label": __("Item Group"),
"fieldtype": "Link",
"options": "Item Group"
},
{
"fieldname": "include_payments",
"label": __("Show Ledger View"),
"fieldtype": "Check",
"default": 0
}
]
}

View File

@@ -4,13 +4,22 @@
import frappe
from frappe import _, msgprint
from frappe.utils import flt
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, getdate
from pypika import Order
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
get_dimension_with_children,
from erpnext.accounts.party import get_party_account
from erpnext.accounts.report.utils import (
apply_common_conditions,
get_advance_taxes_and_charges,
get_journal_entries,
get_opening_row,
get_party_details,
get_payment_entries,
get_query_columns,
get_taxes_query,
get_values_for_columns,
)
from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns
def execute(filters=None):
@@ -21,9 +30,15 @@ def _execute(filters=None, additional_table_columns=None):
if not filters:
filters = {}
include_payments = filters.get("include_payments")
if filters.get("include_payments") and not filters.get("supplier"):
frappe.throw(_("Please select a supplier for fetching payments."))
invoice_list = get_invoices(filters, get_query_columns(additional_table_columns))
if filters.get("include_payments"):
invoice_list += get_payments(filters)
columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns(
invoice_list, additional_table_columns
invoice_list, additional_table_columns, include_payments
)
if not invoice_list:
@@ -33,14 +48,28 @@ def _execute(filters=None, additional_table_columns=None):
invoice_expense_map = get_invoice_expense_map(invoice_list)
internal_invoice_map = get_internal_invoice_map(invoice_list)
invoice_expense_map, invoice_tax_map = get_invoice_tax_map(
invoice_list, invoice_expense_map, expense_accounts
invoice_list, invoice_expense_map, expense_accounts, include_payments
)
invoice_po_pr_map = get_invoice_po_pr_map(invoice_list)
suppliers = list(set(d.supplier for d in invoice_list))
supplier_details = get_supplier_details(suppliers)
supplier_details = get_party_details("Supplier", suppliers)
company_currency = frappe.get_cached_value("Company", filters.company, "default_currency")
res = []
if include_payments:
opening_row = get_opening_row(
"Supplier", filters.supplier, getdate(filters.from_date), filters.company
)[0]
res.append(
{
"payable_account": opening_row.account,
"debit": flt(opening_row.debit),
"credit": flt(opening_row.credit),
"balance": flt(opening_row.balance),
}
)
data = []
for inv in invoice_list:
# invoice details
@@ -48,24 +77,23 @@ def _execute(filters=None, additional_table_columns=None):
purchase_receipt = list(set(invoice_po_pr_map.get(inv.name, {}).get("purchase_receipt", [])))
project = list(set(invoice_po_pr_map.get(inv.name, {}).get("project", [])))
row = [
inv.name,
inv.posting_date,
inv.supplier,
inv.supplier_name,
*get_values_for_columns(additional_table_columns, inv).values(),
supplier_details.get(inv.supplier), # supplier_group
inv.tax_id,
inv.credit_to,
inv.mode_of_payment,
", ".join(project),
inv.bill_no,
inv.bill_date,
inv.remarks,
", ".join(purchase_order),
", ".join(purchase_receipt),
company_currency,
]
row = {
"voucher_type": inv.doctype,
"voucher_no": inv.name,
"posting_date": inv.posting_date,
"supplier_id": inv.supplier,
"supplier_name": inv.supplier_name,
**get_values_for_columns(additional_table_columns, inv),
"supplier_group": supplier_details.get(inv.supplier).get("supplier_group"), # supplier_group
"tax_id": supplier_details.get(inv.supplier).get("tax_id"),
"payable_account": inv.credit_to,
"mode_of_payment": inv.mode_of_payment,
"project": ", ".join(project) if inv.doctype == "Purchase Invoice" else inv.project,
"remarks": inv.remarks,
"purchase_order": ", ".join(purchase_order),
"purchase_receipt": ", ".join(purchase_receipt),
"currency": company_currency,
}
# map expense values
base_net_total = 0
@@ -75,14 +103,16 @@ def _execute(filters=None, additional_table_columns=None):
else:
expense_amount = flt(invoice_expense_map.get(inv.name, {}).get(expense_acc))
base_net_total += expense_amount
row.append(expense_amount)
row.update({frappe.scrub(expense_acc): expense_amount})
# Add amount in unrealized account
for account in unrealized_profit_loss_accounts:
row.append(flt(internal_invoice_map.get((inv.name, account))))
row.update(
{frappe.scrub(account + "_unrealized"): flt(internal_invoice_map.get((inv.name, account)))}
)
# net total
row.append(base_net_total or inv.base_net_total)
row.update({"net_total": base_net_total or inv.base_net_total})
# tax account
total_tax = 0
@@ -90,45 +120,190 @@ def _execute(filters=None, additional_table_columns=None):
if tax_acc not in expense_accounts:
tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc))
total_tax += tax_amount
row.append(tax_amount)
row.update({frappe.scrub(tax_acc): tax_amount})
# total tax, grand total, rounded total & outstanding amount
row += [total_tax, inv.base_grand_total, flt(inv.base_grand_total, 0), inv.outstanding_amount]
row.update(
{
"total_tax": total_tax,
"grand_total": inv.base_grand_total,
"rounded_total": inv.base_rounded_total,
"outstanding_amount": inv.outstanding_amount,
}
)
if inv.doctype == "Purchase Invoice":
row.update({"debit": inv.base_grand_total, "credit": 0.0})
else:
row.update({"debit": 0.0, "credit": inv.base_grand_total})
data.append(row)
return columns, data
res += sorted(data, key=lambda x: x["posting_date"])
if include_payments:
running_balance = flt(opening_row.balance)
for row in range(1, len(res)):
running_balance += res[row]["debit"] - res[row]["credit"]
res[row].update({"balance": running_balance})
return columns, res, None, None, None, include_payments
def get_columns(invoice_list, additional_table_columns):
def get_columns(invoice_list, additional_table_columns, include_payments=False):
"""return columns based on filters"""
columns = [
_("Invoice") + ":Link/Purchase Invoice:120",
_("Posting Date") + ":Date:80",
_("Supplier Id") + "::120",
_("Supplier Name") + "::120",
{
"label": _("Voucher Type"),
"fieldname": "voucher_type",
"width": 120,
},
{
"label": _("Voucher"),
"fieldname": "voucher_no",
"fieldtype": "Dynamic Link",
"options": "voucher_type",
"width": 120,
},
{"label": _("Posting Date"), "fieldname": "posting_date", "fieldtype": "Date", "width": 80},
{
"label": _("Supplier"),
"fieldname": "supplier_id",
"fieldtype": "Link",
"options": "Supplier",
"width": 120,
},
{"label": _("Supplier Name"), "fieldname": "supplier_name", "fieldtype": "Data", "width": 120},
]
if additional_table_columns:
if additional_table_columns and not include_payments:
columns += additional_table_columns
columns += [
_("Supplier Group") + ":Link/Supplier Group:120",
_("Tax Id") + "::80",
_("Payable Account") + ":Link/Account:120",
_("Mode of Payment") + ":Link/Mode of Payment:80",
_("Project") + ":Link/Project:80",
_("Bill No") + "::120",
_("Bill Date") + ":Date:80",
_("Remarks") + "::150",
_("Purchase Order") + ":Link/Purchase Order:100",
_("Purchase Receipt") + ":Link/Purchase Receipt:100",
{"fieldname": "currency", "label": _("Currency"), "fieldtype": "Data", "width": 80},
]
if not include_payments:
columns += [
{
"label": _("Supplier Group"),
"fieldname": "supplier_group",
"fieldtype": "Link",
"options": "Supplier Group",
"width": 120,
},
{"label": _("Tax Id"), "fieldname": "tax_id", "fieldtype": "Data", "width": 80},
{
"label": _("Payable Account"),
"fieldname": "payable_account",
"fieldtype": "Link",
"options": "Account",
"width": 100,
},
{
"label": _("Mode Of Payment"),
"fieldname": "mode_of_payment",
"fieldtype": "Data",
"width": 120,
},
{
"label": _("Project"),
"fieldname": "project",
"fieldtype": "Link",
"options": "Project",
"width": 80,
},
{"label": _("Bill No"), "fieldname": "bill_no", "fieldtype": "Data", "width": 120},
{"label": _("Bill Date"), "fieldname": "bill_date", "fieldtype": "Date", "width": 80},
{
"label": _("Purchase Order"),
"fieldname": "purchase_order",
"fieldtype": "Link",
"options": "Purchase Order",
"width": 100,
},
{
"label": _("Purchase Receipt"),
"fieldname": "purchase_receipt",
"fieldtype": "Link",
"options": "Purchase Receipt",
"width": 100,
},
{"fieldname": "currency", "label": _("Currency"), "fieldtype": "Data", "width": 80},
]
else:
columns += [
{
"fieldname": "payable_account",
"label": _("Payable Account"),
"fieldtype": "Link",
"options": "Account",
"width": 120,
},
{"fieldname": "debit", "label": _("Debit"), "fieldtype": "Currency", "width": 120},
{"fieldname": "credit", "label": _("Credit"), "fieldtype": "Currency", "width": 120},
{"fieldname": "balance", "label": _("Balance"), "fieldtype": "Currency", "width": 120},
]
account_columns, accounts = get_account_columns(invoice_list, include_payments)
columns = (
columns
+ account_columns[0]
+ account_columns[1]
+ [
{
"label": _("Net Total"),
"fieldname": "net_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
]
+ account_columns[2]
+ [
{
"label": _("Total Tax"),
"fieldname": "total_tax",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
]
)
if not include_payments:
columns += [
{
"label": _("Grand Total"),
"fieldname": "grand_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Rounded Total"),
"fieldname": "rounded_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Outstanding Amount"),
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
]
columns += [{"label": _("Remarks"), "fieldname": "remarks", "fieldtype": "Data", "width": 120}]
return columns, accounts[0], accounts[2], accounts[1]
def get_account_columns(invoice_list, include_payments):
expense_accounts = []
tax_accounts = []
unrealized_profit_loss_accounts = []
expense_columns = []
tax_columns = []
unrealized_profit_loss_account_columns = []
if invoice_list:
expense_accounts = frappe.db.sql_list(
"""select distinct expense_account
@@ -139,15 +314,18 @@ def get_columns(invoice_list, additional_table_columns):
tuple([inv.name for inv in invoice_list]),
)
tax_accounts = frappe.db.sql_list(
"""select distinct account_head
from `tabPurchase Taxes and Charges` where parenttype = 'Purchase Invoice'
and docstatus = 1 and (account_head is not null and account_head != '')
and category in ('Total', 'Valuation and Total')
and parent in (%s) order by account_head"""
% ", ".join(["%s"] * len(invoice_list)),
tuple(inv.name for inv in invoice_list),
purchase_taxes_query = get_taxes_query(
invoice_list, "Purchase Taxes and Charges", "Purchase Invoice"
)
purchase_tax_accounts = purchase_taxes_query.run(as_dict=True, pluck="account_head")
tax_accounts = purchase_tax_accounts
if include_payments:
advance_taxes_query = get_taxes_query(
invoice_list, "Advance Taxes and Charges", "Payment Entry"
)
advance_tax_accounts = advance_taxes_query.run(as_dict=True, pluck="account_head")
tax_accounts = set(tax_accounts + advance_tax_accounts)
unrealized_profit_loss_accounts = frappe.db.sql_list(
"""SELECT distinct unrealized_profit_loss_account
@@ -158,108 +336,109 @@ def get_columns(invoice_list, additional_table_columns):
tuple(inv.name for inv in invoice_list),
)
expense_columns = [(account + ":Currency/currency:120") for account in expense_accounts]
unrealized_profit_loss_account_columns = [
(account + ":Currency/currency:120") for account in unrealized_profit_loss_accounts
]
tax_columns = [
(account + ":Currency/currency:120")
for account in tax_accounts
if account not in expense_accounts
]
for account in expense_accounts:
expense_columns.append(
{
"label": account,
"fieldname": frappe.scrub(account),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
)
columns = (
columns
+ expense_columns
+ unrealized_profit_loss_account_columns
+ [_("Net Total") + ":Currency/currency:120"]
+ tax_columns
+ [
_("Total Tax") + ":Currency/currency:120",
_("Grand Total") + ":Currency/currency:120",
_("Rounded Total") + ":Currency/currency:120",
_("Outstanding Amount") + ":Currency/currency:120",
]
)
for account in tax_accounts:
if account not in expense_accounts:
tax_columns.append(
{
"label": account,
"fieldname": frappe.scrub(account),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
)
return columns, expense_accounts, tax_accounts, unrealized_profit_loss_accounts
for account in unrealized_profit_loss_accounts:
unrealized_profit_loss_account_columns.append(
{
"label": account,
"fieldname": frappe.scrub(account),
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
)
columns = [expense_columns, unrealized_profit_loss_account_columns, tax_columns]
accounts = [expense_accounts, unrealized_profit_loss_accounts, tax_accounts]
def get_conditions(filters):
conditions = ""
if filters.get("company"):
conditions += " and company=%(company)s"
if filters.get("supplier"):
conditions += " and supplier = %(supplier)s"
if filters.get("from_date"):
conditions += " and posting_date>=%(from_date)s"
if filters.get("to_date"):
conditions += " and posting_date<=%(to_date)s"
if filters.get("mode_of_payment"):
conditions += " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"
if filters.get("cost_center"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.cost_center, '') = %(cost_center)s)"""
if filters.get("warehouse"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.warehouse, '') = %(warehouse)s)"""
if filters.get("item_group"):
conditions += """ and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s)"""
accounting_dimensions = get_accounting_dimensions(as_list=False)
if accounting_dimensions:
common_condition = """
and exists(select name from `tabPurchase Invoice Item`
where parent=`tabPurchase Invoice`.name
"""
for dimension in accounting_dimensions:
if filters.get(dimension.fieldname):
if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
filters[dimension.fieldname] = get_dimension_with_children(
dimension.document_type, filters.get(dimension.fieldname)
)
conditions += (
common_condition
+ "and ifnull(`tabPurchase Invoice`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
else:
conditions += (
common_condition
+ "and ifnull(`tabPurchase Invoice`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
return conditions
return columns, accounts
def get_invoices(filters, additional_query_columns):
conditions = get_conditions(filters)
return frappe.db.sql(
"""
select
name, posting_date, credit_to, supplier, supplier_name, tax_id, bill_no, bill_date,
remarks, base_net_total, base_grand_total, outstanding_amount,
mode_of_payment {0}
from `tabPurchase Invoice`
where docstatus = 1 {1}
order by posting_date desc, name desc""".format(
additional_query_columns, conditions
),
filters,
as_dict=1,
pi = frappe.qb.DocType("Purchase Invoice")
query = (
frappe.qb.from_(pi)
.select(
ConstantColumn("Purchase Invoice").as_("doctype"),
pi.name,
pi.posting_date,
pi.credit_to,
pi.supplier,
pi.supplier_name,
pi.tax_id,
pi.bill_no,
pi.bill_date,
pi.remarks,
pi.base_net_total,
pi.base_grand_total,
pi.base_rounded_total,
pi.outstanding_amount,
pi.mode_of_payment,
)
.where((pi.docstatus == 1))
.orderby(pi.posting_date, pi.name, order=Order.desc)
)
if additional_query_columns:
for col in additional_query_columns:
query = query.select(col)
if filters.get("supplier"):
query = query.where(pi.supplier == filters.supplier)
query = get_conditions(filters, query, "Purchase Invoice")
query = apply_common_conditions(
filters, query, doctype="Purchase Invoice", child_doctype="Purchase Invoice Item"
)
invoices = query.run(as_dict=True)
return invoices
def get_conditions(filters, query, doctype):
parent_doc = frappe.qb.DocType(doctype)
if filters.get("mode_of_payment"):
query = query.where(parent_doc.mode_of_payment == filters.mode_of_payment)
return query
def get_payments(filters):
args = frappe._dict(
account="credit_to",
account_fieldname="paid_to",
party="supplier",
party_name="supplier_name",
party_account=get_party_account("Supplier", filters.supplier, filters.company),
)
payment_entries = get_payment_entries(filters, args)
journal_entries = get_journal_entries(filters, args)
return payment_entries + journal_entries
def get_invoice_expense_map(invoice_list):
expense_details = frappe.db.sql(
@@ -300,7 +479,9 @@ def get_internal_invoice_map(invoice_list):
return internal_invoice_map
def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
def get_invoice_tax_map(
invoice_list, invoice_expense_map, expense_accounts, include_payments=False
):
tax_details = frappe.db.sql(
"""
select parent, account_head, case add_deduct_tax when "Add" then sum(base_tax_amount_after_discount_amount)
@@ -315,6 +496,9 @@ def get_invoice_tax_map(invoice_list, invoice_expense_map, expense_accounts):
as_dict=1,
)
if include_payments:
tax_details += get_advance_taxes_and_charges(invoice_list)
invoice_tax_map = {}
for d in tax_details:
if d.account_head in expense_accounts:
@@ -382,17 +566,3 @@ def get_account_details(invoice_list):
account_map[acc.name] = acc.parent_account
return account_map
def get_supplier_details(suppliers):
supplier_details = {}
for supp in frappe.db.sql(
"""select name, supplier_group from `tabSupplier`
where name in (%s)"""
% ", ".join(["%s"] * len(suppliers)),
tuple(suppliers),
as_dict=1,
):
supplier_details.setdefault(supp.name, supp.supplier_group)
return supplier_details

View File

@@ -0,0 +1,128 @@
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_months, getdate, today
from erpnext.accounts.report.purchase_register.purchase_register import execute
class TestPurchaseRegister(FrappeTestCase):
def test_purchase_register(self):
frappe.db.sql("delete from `tabPurchase Invoice` where company='_Test Company 6'")
frappe.db.sql("delete from `tabGL Entry` where company='_Test Company 6'")
filters = frappe._dict(
company="_Test Company 6", from_date=add_months(today(), -1), to_date=today()
)
pi = make_purchase_invoice()
report_results = execute(filters)
first_row = frappe._dict(report_results[1][0])
self.assertEqual(first_row.voucher_type, "Purchase Invoice")
self.assertEqual(first_row.voucher_no, pi.name)
self.assertEqual(first_row.payable_account, "Creditors - _TC6")
self.assertEqual(first_row.net_total, 1000)
self.assertEqual(first_row.total_tax, 100)
self.assertEqual(first_row.grand_total, 1100)
def test_purchase_register_ledger_view(self):
frappe.db.sql("delete from `tabPurchase Invoice` where company='_Test Company 6'")
frappe.db.sql("delete from `tabGL Entry` where company='_Test Company 6'")
filters = frappe._dict(
company="_Test Company 6",
from_date=add_months(today(), -1),
to_date=today(),
include_payments=True,
supplier="_Test Supplier",
)
pi = make_purchase_invoice()
pe = make_payment_entry()
report_results = execute(filters)
first_row = frappe._dict(report_results[1][2])
self.assertEqual(first_row.voucher_type, "Payment Entry")
self.assertEqual(first_row.voucher_no, pe.name)
self.assertEqual(first_row.payable_account, "Creditors - _TC6")
self.assertEqual(first_row.debit, 0)
self.assertEqual(first_row.credit, 600)
self.assertEqual(first_row.balance, 500)
def make_purchase_invoice():
from erpnext.accounts.doctype.account.test_account import create_account
from erpnext.accounts.doctype.cost_center.test_cost_center import create_cost_center
from erpnext.stock.doctype.warehouse.test_warehouse import create_warehouse
gst_acc = create_account(
account_name="GST",
account_type="Tax",
parent_account="Duties and Taxes - _TC6",
company="_Test Company 6",
account_currency="INR",
)
create_warehouse(warehouse_name="_Test Warehouse - _TC6", company="_Test Company 6")
create_cost_center(cost_center_name="_Test Cost Center", company="_Test Company 6")
pi = create_purchase_invoice_with_taxes()
pi.submit()
return pi
def create_purchase_invoice_with_taxes():
return frappe.get_doc(
{
"doctype": "Purchase Invoice",
"posting_date": today(),
"supplier": "_Test Supplier",
"company": "_Test Company 6",
"cost_center": "_Test Cost Center - _TC6",
"taxes_and_charges": "",
"currency": "INR",
"credit_to": "Creditors - _TC6",
"items": [
{
"doctype": "Purchase Invoice Item",
"cost_center": "_Test Cost Center - _TC6",
"item_code": "_Test Item",
"qty": 1,
"rate": 1000,
"expense_account": "Stock Received But Not Billed - _TC6",
}
],
"taxes": [
{
"account_head": "GST - _TC6",
"cost_center": "_Test Cost Center - _TC6",
"add_deduct_tax": "Add",
"category": "Valuation and Total",
"charge_type": "Actual",
"description": "Shipping Charges",
"doctype": "Purchase Taxes and Charges",
"parentfield": "taxes",
"rate": 100,
"tax_amount": 100.0,
}
],
}
)
def make_payment_entry():
frappe.set_user("Administrator")
from erpnext.accounts.doctype.payment_entry.test_payment_entry import create_payment_entry
return create_payment_entry(
company="_Test Company 6",
party_type="Supplier",
party="_Test Supplier",
payment_type="Pay",
paid_from="Cash - _TC6",
paid_to="Creditors - _TC6",
paid_amount=600,
save=1,
submit=1,
)

View File

@@ -64,6 +64,12 @@ frappe.query_reports["Sales Register"] = {
"label": __("Item Group"),
"fieldtype": "Link",
"options": "Item Group"
},
{
"fieldname": "include_payments",
"label": __("Show Ledger View"),
"fieldtype": "Check",
"default": 0
}
]
}

View File

@@ -5,13 +5,22 @@
import frappe
from frappe import _, msgprint
from frappe.model.meta import get_field_precision
from frappe.utils import flt
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, getdate
from pypika import Order
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
get_dimension_with_children,
from erpnext.accounts.party import get_party_account
from erpnext.accounts.report.utils import (
apply_common_conditions,
get_advance_taxes_and_charges,
get_journal_entries,
get_opening_row,
get_party_details,
get_payment_entries,
get_query_columns,
get_taxes_query,
get_values_for_columns,
)
from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns
def execute(filters=None):
@@ -22,9 +31,15 @@ def _execute(filters, additional_table_columns=None):
if not filters:
filters = frappe._dict({})
include_payments = filters.get("include_payments")
if filters.get("include_payments") and not filters.get("customer"):
frappe.throw(_("Please select a customer for fetching payments."))
invoice_list = get_invoices(filters, get_query_columns(additional_table_columns))
columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts = get_columns(
invoice_list, additional_table_columns
if filters.get("include_payments"):
invoice_list += get_payments(filters)
columns, income_accounts, unrealized_profit_loss_accounts, tax_accounts = get_columns(
invoice_list, additional_table_columns, include_payments
)
if not invoice_list:
@@ -34,13 +49,29 @@ def _execute(filters, additional_table_columns=None):
invoice_income_map = get_invoice_income_map(invoice_list)
internal_invoice_map = get_internal_invoice_map(invoice_list)
invoice_income_map, invoice_tax_map = get_invoice_tax_map(
invoice_list, invoice_income_map, income_accounts
invoice_list, invoice_income_map, income_accounts, include_payments
)
# Cost Center & Warehouse Map
invoice_cc_wh_map = get_invoice_cc_wh_map(invoice_list)
invoice_so_dn_map = get_invoice_so_dn_map(invoice_list)
company_currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency")
mode_of_payments = get_mode_of_payments([inv.name for inv in invoice_list])
customers = list(set(d.customer for d in invoice_list))
customer_details = get_party_details("Customer", customers)
res = []
if include_payments:
opening_row = get_opening_row(
"Customer", filters.customer, getdate(filters.from_date), filters.company
)[0]
res.append(
{
"receivable_account": opening_row.account,
"debit": flt(opening_row.debit),
"credit": flt(opening_row.credit),
"balance": flt(opening_row.balance),
}
)
data = []
for inv in invoice_list:
@@ -51,14 +82,15 @@ def _execute(filters, additional_table_columns=None):
warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
row = {
"invoice": inv.name,
"voucher_type": inv.doctype,
"voucher_no": inv.name,
"posting_date": inv.posting_date,
"customer": inv.customer,
"customer_name": inv.customer_name,
**get_values_for_columns(additional_table_columns, inv),
"customer_group": inv.get("customer_group"),
"territory": inv.get("territory"),
"tax_id": inv.get("tax_id"),
"customer_group": customer_details.get(inv.customer).get("customer_group"),
"territory": customer_details.get(inv.customer).get("territory"),
"tax_id": customer_details.get(inv.customer).get("tax_id"),
"receivable_account": inv.debit_to,
"mode_of_payment": ", ".join(mode_of_payments.get(inv.name, [])),
"project": inv.project,
@@ -66,7 +98,7 @@ def _execute(filters, additional_table_columns=None):
"remarks": inv.remarks,
"sales_order": ", ".join(sales_order),
"delivery_note": ", ".join(delivery_note),
"cost_center": ", ".join(cost_center),
"cost_center": ", ".join(cost_center) if inv.doctype == "Sales Invoice" else inv.cost_center,
"warehouse": ", ".join(warehouse),
"currency": company_currency,
}
@@ -116,19 +148,36 @@ def _execute(filters, additional_table_columns=None):
}
)
if inv.doctype == "Sales Invoice":
row.update({"debit": inv.base_grand_total, "credit": 0.0})
else:
row.update({"debit": 0.0, "credit": inv.base_grand_total})
data.append(row)
return columns, data
res += sorted(data, key=lambda x: x["posting_date"])
if include_payments:
running_balance = flt(opening_row.balance)
for row in range(1, len(res)):
running_balance += res[row]["debit"] - res[row]["credit"]
res[row].update({"balance": running_balance})
return columns, res, None, None, None, include_payments
def get_columns(invoice_list, additional_table_columns):
def get_columns(invoice_list, additional_table_columns, include_payments=False):
"""return columns based on filters"""
columns = [
{
"label": _("Invoice"),
"fieldname": "invoice",
"fieldtype": "Link",
"options": "Sales Invoice",
"label": _("Voucher Type"),
"fieldname": "voucher_type",
"width": 120,
},
{
"label": _("Voucher"),
"fieldname": "voucher_no",
"fieldtype": "Dynamic Link",
"options": "voucher_type",
"width": 120,
},
{"label": _("Posting Date"), "fieldname": "posting_date", "fieldtype": "Date", "width": 80},
@@ -142,83 +191,156 @@ def get_columns(invoice_list, additional_table_columns):
{"label": _("Customer Name"), "fieldname": "customer_name", "fieldtype": "Data", "width": 120},
]
if additional_table_columns:
if additional_table_columns and not include_payments:
columns += additional_table_columns
columns += [
if not include_payments:
columns += [
{
"label": _("Customer Group"),
"fieldname": "customer_group",
"fieldtype": "Link",
"options": "Customer Group",
"width": 120,
},
{
"label": _("Territory"),
"fieldname": "territory",
"fieldtype": "Link",
"options": "Territory",
"width": 80,
},
{"label": _("Tax Id"), "fieldname": "tax_id", "fieldtype": "Data", "width": 80},
{
"label": _("Receivable Account"),
"fieldname": "receivable_account",
"fieldtype": "Link",
"options": "Account",
"width": 100,
},
{
"label": _("Mode Of Payment"),
"fieldname": "mode_of_payment",
"fieldtype": "Data",
"width": 120,
},
{
"label": _("Project"),
"fieldname": "project",
"fieldtype": "Link",
"options": "Project",
"width": 80,
},
{"label": _("Owner"), "fieldname": "owner", "fieldtype": "Data", "width": 100},
{
"label": _("Sales Order"),
"fieldname": "sales_order",
"fieldtype": "Link",
"options": "Sales Order",
"width": 100,
},
{
"label": _("Delivery Note"),
"fieldname": "delivery_note",
"fieldtype": "Link",
"options": "Delivery Note",
"width": 100,
},
{
"label": _("Cost Center"),
"fieldname": "cost_center",
"fieldtype": "Link",
"options": "Cost Center",
"width": 100,
},
{
"label": _("Warehouse"),
"fieldname": "warehouse",
"fieldtype": "Link",
"options": "Warehouse",
"width": 100,
},
{"fieldname": "currency", "label": _("Currency"), "fieldtype": "Data", "width": 80},
]
else:
columns += [
{
"fieldname": "receivable_account",
"label": _("Receivable Account"),
"fieldtype": "Link",
"options": "Account",
"width": 120,
},
{"fieldname": "debit", "label": _("Debit"), "fieldtype": "Currency", "width": 120},
{"fieldname": "credit", "label": _("Credit"), "fieldtype": "Currency", "width": 120},
{"fieldname": "balance", "label": _("Balance"), "fieldtype": "Currency", "width": 120},
]
account_columns, accounts = get_account_columns(invoice_list, include_payments)
net_total_column = [
{
"label": _("Customer Group"),
"fieldname": "customer_group",
"fieldtype": "Link",
"options": "Customer Group",
"label": _("Net Total"),
"fieldname": "net_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Territory"),
"fieldname": "territory",
"fieldtype": "Link",
"options": "Territory",
"width": 80,
},
{"label": _("Tax Id"), "fieldname": "tax_id", "fieldtype": "Data", "width": 120},
{
"label": _("Receivable Account"),
"fieldname": "receivable_account",
"fieldtype": "Link",
"options": "Account",
"width": 80,
},
{
"label": _("Mode Of Payment"),
"fieldname": "mode_of_payment",
"fieldtype": "Data",
"width": 120,
},
{
"label": _("Project"),
"fieldname": "project",
"fieldtype": "Link",
"options": "Project",
"width": 80,
},
{"label": _("Owner"), "fieldname": "owner", "fieldtype": "Data", "width": 150},
{"label": _("Remarks"), "fieldname": "remarks", "fieldtype": "Data", "width": 150},
{
"label": _("Sales Order"),
"fieldname": "sales_order",
"fieldtype": "Link",
"options": "Sales Order",
"width": 100,
},
{
"label": _("Delivery Note"),
"fieldname": "delivery_note",
"fieldtype": "Link",
"options": "Delivery Note",
"width": 100,
},
{
"label": _("Cost Center"),
"fieldname": "cost_center",
"fieldtype": "Link",
"options": "Cost Center",
"width": 100,
},
{
"label": _("Warehouse"),
"fieldname": "warehouse",
"fieldtype": "Link",
"options": "Warehouse",
"width": 100,
},
{"fieldname": "currency", "label": _("Currency"), "fieldtype": "Data", "width": 80},
}
]
total_columns = [
{
"label": _("Tax Total"),
"fieldname": "tax_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
]
if not include_payments:
total_columns += [
{
"label": _("Grand Total"),
"fieldname": "grand_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Rounded Total"),
"fieldname": "rounded_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Outstanding Amount"),
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
]
columns = (
columns
+ account_columns[0]
+ account_columns[2]
+ net_total_column
+ account_columns[1]
+ total_columns
)
columns += [{"label": _("Remarks"), "fieldname": "remarks", "fieldtype": "Data", "width": 150}]
return columns, accounts[0], accounts[1], accounts[2]
def get_account_columns(invoice_list, include_payments):
income_accounts = []
tax_accounts = []
unrealized_profit_loss_accounts = []
income_columns = []
tax_columns = []
unrealized_profit_loss_accounts = []
unrealized_profit_loss_account_columns = []
if invoice_list:
@@ -230,14 +352,16 @@ def get_columns(invoice_list, additional_table_columns):
tuple(inv.name for inv in invoice_list),
)
tax_accounts = frappe.db.sql_list(
"""select distinct account_head
from `tabSales Taxes and Charges` where parenttype = 'Sales Invoice'
and docstatus = 1 and base_tax_amount_after_discount_amount != 0
and parent in (%s) order by account_head"""
% ", ".join(["%s"] * len(invoice_list)),
tuple(inv.name for inv in invoice_list),
)
sales_taxes_query = get_taxes_query(invoice_list, "Sales Taxes and Charges", "Sales Invoice")
sales_tax_accounts = sales_taxes_query.run(as_dict=True, pluck="account_head")
tax_accounts = sales_tax_accounts
if include_payments:
advance_taxes_query = get_taxes_query(
invoice_list, "Advance Taxes and Charges", "Payment Entry"
)
advance_tax_accounts = advance_taxes_query.run(as_dict=True, pluck="account_head")
tax_accounts = set(tax_accounts + advance_tax_accounts)
unrealized_profit_loss_accounts = frappe.db.sql_list(
"""SELECT distinct unrealized_profit_loss_account
@@ -283,134 +407,82 @@ def get_columns(invoice_list, additional_table_columns):
}
)
net_total_column = [
{
"label": _("Net Total"),
"fieldname": "net_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
}
]
columns = [income_columns, unrealized_profit_loss_account_columns, tax_columns]
accounts = [income_accounts, unrealized_profit_loss_accounts, tax_accounts]
total_columns = [
{
"label": _("Tax Total"),
"fieldname": "tax_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Grand Total"),
"fieldname": "grand_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Rounded Total"),
"fieldname": "rounded_total",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
{
"label": _("Outstanding Amount"),
"fieldname": "outstanding_amount",
"fieldtype": "Currency",
"options": "currency",
"width": 120,
},
]
columns = (
columns
+ income_columns
+ unrealized_profit_loss_account_columns
+ net_total_column
+ tax_columns
+ total_columns
)
return columns, income_accounts, tax_accounts, unrealized_profit_loss_accounts
def get_conditions(filters):
conditions = ""
accounting_dimensions = get_accounting_dimensions(as_list=False) or []
accounting_dimensions_list = [d.fieldname for d in accounting_dimensions]
if filters.get("company"):
conditions += " and company=%(company)s"
if filters.get("customer") and "customer" not in accounting_dimensions_list:
conditions += " and customer = %(customer)s"
if filters.get("from_date"):
conditions += " and posting_date >= %(from_date)s"
if filters.get("to_date"):
conditions += " and posting_date <= %(to_date)s"
if filters.get("owner"):
conditions += " and owner = %(owner)s"
def get_sales_invoice_item_field_condition(field, table="Sales Invoice Item") -> str:
if not filters.get(field) or field in accounting_dimensions_list:
return ""
return f""" and exists(select name from `tab{table}`
where parent=`tabSales Invoice`.name
and ifnull(`tab{table}`.{field}, '') = %({field})s)"""
conditions += get_sales_invoice_item_field_condition("mode_of_payment", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("cost_center")
conditions += get_sales_invoice_item_field_condition("warehouse")
conditions += get_sales_invoice_item_field_condition("brand")
conditions += get_sales_invoice_item_field_condition("item_group")
if accounting_dimensions:
common_condition = """
and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
"""
for dimension in accounting_dimensions:
if filters.get(dimension.fieldname):
if frappe.get_cached_value("DocType", dimension.document_type, "is_tree"):
filters[dimension.fieldname] = get_dimension_with_children(
dimension.document_type, filters.get(dimension.fieldname)
)
conditions += (
common_condition
+ "and ifnull(`tabSales Invoice`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
else:
conditions += (
common_condition
+ "and ifnull(`tabSales Invoice`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
return conditions
return columns, accounts
def get_invoices(filters, additional_query_columns):
conditions = get_conditions(filters)
return frappe.db.sql(
"""
select name, posting_date, debit_to, project, customer,
customer_name, owner, remarks, territory, tax_id, customer_group,
base_net_total, base_grand_total, base_rounded_total, outstanding_amount,
is_internal_customer, represents_company, company {0}
from `tabSales Invoice`
where docstatus = 1 {1}
order by posting_date desc, name desc""".format(
additional_query_columns, conditions
),
filters,
as_dict=1,
si = frappe.qb.DocType("Sales Invoice")
query = (
frappe.qb.from_(si)
.select(
ConstantColumn("Sales Invoice").as_("doctype"),
si.name,
si.posting_date,
si.debit_to,
si.project,
si.customer,
si.customer_name,
si.owner,
si.remarks,
si.territory,
si.tax_id,
si.customer_group,
si.base_net_total,
si.base_grand_total,
si.base_rounded_total,
si.outstanding_amount,
si.is_internal_customer,
si.represents_company,
si.company,
)
.where((si.docstatus == 1))
.orderby(si.posting_date, si.name, order=Order.desc)
)
if additional_query_columns:
for col in additional_query_columns:
query = query.select(col)
if filters.get("customer"):
query = query.where(si.customer == filters.customer)
query = get_conditions(filters, query, "Sales Invoice")
query = apply_common_conditions(
filters, query, doctype="Sales Invoice", child_doctype="Sales Invoice Item"
)
invoices = query.run(as_dict=True)
return invoices
def get_conditions(filters, query, doctype):
parent_doc = frappe.qb.DocType(doctype)
if filters.get("owner"):
query = query.where(parent_doc.owner == filters.owner)
if filters.get("mode_of_payment"):
payment_doc = frappe.qb.DocType("Sales Invoice Payment")
query = query.inner_join(payment_doc).on(parent_doc.name == payment_doc.parent)
query = query.where(payment_doc.mode_of_payment == filters.mode_of_payment).distinct()
return query
def get_payments(filters):
args = frappe._dict(
account="debit_to",
account_fieldname="paid_from",
party="customer",
party_name="customer_name",
party_account=get_party_account("Customer", filters.customer, filters.company),
)
payment_entries = get_payment_entries(filters, args)
journal_entries = get_journal_entries(filters, args)
return payment_entries + journal_entries
def get_invoice_income_map(invoice_list):
income_details = frappe.db.sql(
@@ -447,7 +519,7 @@ def get_internal_invoice_map(invoice_list):
return internal_invoice_map
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts):
def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts, include_payments=False):
tax_details = frappe.db.sql(
"""select parent, account_head,
sum(base_tax_amount_after_discount_amount) as tax_amount
@@ -457,6 +529,9 @@ def get_invoice_tax_map(invoice_list, invoice_income_map, income_accounts):
as_dict=1,
)
if include_payments:
tax_details += get_advance_taxes_and_charges(invoice_list)
invoice_tax_map = {}
for d in tax_details:
if d.account_head in income_accounts:

View File

@@ -47,6 +47,7 @@ def get_result(
out = []
for name, details in gle_map.items():
tax_amount, total_amount, grand_total, base_total = 0, 0, 0, 0
bill_no, bill_date = "", ""
tax_withholding_category = tax_category_map.get(name)
rate = tax_rate_map.get(tax_withholding_category)
@@ -70,7 +71,10 @@ def get_result(
if net_total_map.get(name):
if voucher_type == "Journal Entry" and tax_amount and rate:
# back calcalute total amount from rate and tax_amount
total_amount = grand_total = base_total = tax_amount / (rate / 100)
if rate:
total_amount = grand_total = base_total = tax_amount / (rate / 100)
elif voucher_type == "Purchase Invoice":
total_amount, grand_total, base_total, bill_no, bill_date = net_total_map.get(name)
else:
total_amount, grand_total, base_total = net_total_map.get(name)
else:
@@ -96,7 +100,7 @@ def get_result(
row.update(
{
"section_code": tax_withholding_category,
"section_code": tax_withholding_category or "",
"entity_type": party_map.get(party, {}).get(party_type),
"rate": rate,
"total_amount": total_amount,
@@ -106,10 +110,14 @@ def get_result(
"transaction_date": posting_date,
"transaction_type": voucher_type,
"ref_no": name,
"supplier_invoice_no": bill_no,
"supplier_invoice_date": bill_date,
}
)
out.append(row)
out.sort(key=lambda x: x["section_code"])
return out
@@ -157,14 +165,14 @@ def get_gle_map(documents):
def get_columns(filters):
pan = "pan" if frappe.db.has_column(filters.party_type, "pan") else "tax_id"
columns = [
{"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 60},
{
"label": _(filters.get("party_type")),
"fieldname": "party",
"fieldtype": "Dynamic Link",
"options": "party_type",
"width": 180,
"label": _("Section Code"),
"options": "Tax Withholding Category",
"fieldname": "section_code",
"fieldtype": "Link",
"width": 90,
},
{"label": _(frappe.unscrub(pan)), "fieldname": pan, "fieldtype": "Data", "width": 60},
]
if filters.naming_series == "Naming Series":
@@ -176,54 +184,73 @@ def get_columns(filters):
"width": 180,
}
)
else:
columns.append(
{
"label": _(filters.get("party_type")),
"fieldname": "party",
"fieldtype": "Dynamic Link",
"options": "party_type",
"width": 180,
}
)
columns.extend(
[
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100},
]
)
if filters.party_type == "Supplier":
columns.extend(
[
{
"label": _("Supplier Invoice No"),
"fieldname": "supplier_invoice_no",
"fieldtype": "Data",
"width": 120,
},
{
"label": _("Supplier Invoice Date"),
"fieldname": "supplier_invoice_date",
"fieldtype": "Date",
"width": 120,
},
]
)
columns.extend(
[
{
"label": _("Date of Transaction"),
"fieldname": "transaction_date",
"fieldtype": "Date",
"width": 100,
"label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
"fieldname": "rate",
"fieldtype": "Percent",
"width": 60,
},
{
"label": _("Section Code"),
"options": "Tax Withholding Category",
"fieldname": "section_code",
"fieldtype": "Link",
"width": 90,
},
{"label": _("Entity Type"), "fieldname": "entity_type", "fieldtype": "Data", "width": 100},
{
"label": _("Total Amount"),
"fieldname": "total_amount",
"fieldtype": "Float",
"width": 90,
},
{
"label": _("TDS Rate %") if filters.get("party_type") == "Supplier" else _("TCS Rate %"),
"fieldname": "rate",
"fieldtype": "Percent",
"width": 90,
},
{
"label": _("Tax Amount"),
"fieldname": "tax_amount",
"fieldtype": "Float",
"width": 90,
},
{
"label": _("Grand Total"),
"fieldname": "grand_total",
"fieldtype": "Float",
"width": 90,
"width": 120,
},
{
"label": _("Base Total"),
"fieldname": "base_total",
"fieldtype": "Float",
"width": 90,
"width": 120,
},
{"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 100},
{
"label": _("Tax Amount"),
"fieldname": "tax_amount",
"fieldtype": "Float",
"width": 120,
},
{
"label": _("Grand Total"),
"fieldname": "grand_total",
"fieldtype": "Float",
"width": 120,
},
{"label": _("Transaction Type"), "fieldname": "transaction_type", "width": 130},
{
"label": _("Reference No."),
"fieldname": "ref_no",
@@ -231,6 +258,12 @@ def get_columns(filters):
"options": "transaction_type",
"width": 180,
},
{
"label": _("Date of Transaction"),
"fieldname": "transaction_date",
"fieldtype": "Date",
"width": 100,
},
]
)
@@ -253,27 +286,7 @@ def get_tds_docs(filters):
"Tax Withholding Account", {"company": filters.get("company")}, pluck="account"
)
query_filters = {
"account": ("in", tds_accounts),
"posting_date": ("between", [filters.get("from_date"), filters.get("to_date")]),
"is_cancelled": 0,
"against": ("not in", bank_accounts),
}
party = frappe.get_all(filters.get("party_type"), pluck="name")
or_filters.update({"against": ("in", party), "voucher_type": "Journal Entry"})
if filters.get("party"):
del query_filters["account"]
del query_filters["against"]
or_filters = {"against": filters.get("party"), "party": filters.get("party")}
tds_docs = frappe.get_all(
"GL Entry",
filters=query_filters,
or_filters=or_filters,
fields=["voucher_no", "voucher_type", "against", "party"],
)
tds_docs = get_tds_docs_query(filters, bank_accounts, tds_accounts).run(as_dict=True)
for d in tds_docs:
if d.voucher_type == "Purchase Invoice":
@@ -309,6 +322,42 @@ def get_tds_docs(filters):
)
def get_tds_docs_query(filters, bank_accounts, tds_accounts):
if not tds_accounts:
frappe.throw(
_("No {0} Accounts found for this company.").format(frappe.bold("Tax Withholding")),
title=_("Accounts Missing Error"),
)
gle = frappe.qb.DocType("GL Entry")
query = (
frappe.qb.from_(gle)
.select("voucher_no", "voucher_type", "against", "party")
.where((gle.is_cancelled == 0))
)
if filters.get("from_date"):
query = query.where(gle.posting_date >= filters.get("from_date"))
if filters.get("to_date"):
query = query.where(gle.posting_date <= filters.get("to_date"))
if bank_accounts:
query = query.where(gle.against.notin(bank_accounts))
if filters.get("party"):
party = [filters.get("party")]
jv_condition = gle.against.isin(party) | (
(gle.voucher_type == "Journal Entry") & (gle.party == filters.get("party"))
)
else:
party = frappe.get_all(filters.get("party_type"), pluck="name")
jv_condition = gle.against.isin(party) | (
(gle.voucher_type == "Journal Entry")
& ((gle.party_type == filters.get("party_type")) | (gle.party_type == ""))
)
query = query.where((gle.account.isin(tds_accounts) & jv_condition) | gle.party.isin(party))
return query
def get_journal_entry_party_map(journal_entries):
journal_entry_party_map = {}
for d in frappe.db.get_all(
@@ -335,6 +384,8 @@ def get_doc_info(vouchers, doctype, tax_category_map, net_total_map=None):
"base_tax_withholding_net_total",
"grand_total",
"base_total",
"bill_no",
"bill_date",
],
"Sales Invoice": ["base_net_total", "grand_total", "base_total"],
"Payment Entry": [
@@ -353,7 +404,13 @@ def get_doc_info(vouchers, doctype, tax_category_map, net_total_map=None):
for entry in entries:
tax_category_map.update({entry.name: entry.tax_withholding_category})
if doctype == "Purchase Invoice":
value = [entry.base_tax_withholding_net_total, entry.grand_total, entry.base_total]
value = [
entry.base_tax_withholding_net_total,
entry.grand_total,
entry.base_total,
entry.bill_no,
entry.bill_date,
]
elif doctype == "Sales Invoice":
value = [entry.base_net_total, entry.grand_total, entry.base_total]
elif doctype == "Payment Entry":

View File

@@ -96,7 +96,7 @@ frappe.require("assets/erpnext/js/financial_statements.js", function() {
},
{
"fieldname": "include_default_book_entries",
"label": __("Include Default Book Entries"),
"label": __("Include Default FB Entries"),
"fieldtype": "Check",
"default": 1
},

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