Compare commits

..

457 Commits

Author SHA1 Message Date
Frappe PR Bot
fa6a479ed9 chore(release): Bumped to Version 15.27.7
## [15.27.7](https://github.com/frappe/erpnext/compare/v15.27.6...v15.27.7) (2024-06-19)

### Bug Fixes

* add LCV flag to determine negative expenses ([83ccb32](83ccb32be6))
* add strings for translation in pos_item_cart.js ([f4852d4](f4852d472a))
* add test case for update received qty in MR ([858058c](858058c9e1))
* add test case for update received qty in MR ([aaee028](aaee02835b))
* add test case for update received qty in MR ([125d97a](125d97a182))
* add test case for update received qty in MR - import sorter ([084658e](084658e8ff))
* add test case for update received qty in MR - import sorter ([21596c6](21596c6c23))
* allow Employee role to select Department (backport [#41877](https://github.com/frappe/erpnext/issues/41877)) ([#41881](https://github.com/frappe/erpnext/issues/41881)) ([3bc5076](3bc5076dfc))
* batch qty in the dropdown field ([67d1709](67d1709ef8))
* consistent query field name in item wise purchase register with item wise sales register ([a43c181](a43c181673))
* download materials request plan in PP ([7193633](7193633773))
* download materials request plan in PP ([ef2a6c7](ef2a6c788e))
* download materials request plan in PP -prettier ([3370825](337082512e))
* download materials request plan in production plan ([9cb7c27](9cb7c279a4))
* duplicate rows fetching in RFQ ([c159e3b](c159e3b06f))
* handle NoneType error where customer details are not available in sales register ([ceafa0c](ceafa0ce28))
* incorrect batch return from sales return ([b64b433](b64b4330a3))
* item_code filter in item-wise sales-purchase register ([98c8fed](98c8feded0))
* migrate lead notes ([5663432](5663432bd8))
* only show user and date if available ([24ee765](24ee765e6a))
* parameters for PI references ([8618402](8618402829))
* regional overide for updating item valution ([5ea2cdc](5ea2cdcaad))
* reposting validation related PCV ([794ade8](794ade832f))
* reset perpetual inventory flag after test ([4c11f2b](4c11f2bff2))
* return from accepted and rejected warehouse at a same time not working ([6c57971](6c57971abc))
* update received qty in MR on purchase invoice submit with update stock ([7e9f6ae](7e9f6aee58))
* update received qty in MR on purchase invoice submit with update stock ([4551b4b](4551b4b638))
* use invoice outstanding on Dunning ([#41817](https://github.com/frappe/erpnext/issues/41817)) ([04f0c96](04f0c96af7))
2024-06-19 06:28:10 +00:00
ruthra kumar
a60879fec0 Merge pull request #41941 from frappe/version-15-hotfix
chore: release v15
2024-06-19 11:56:54 +05:30
ruthra kumar
cd1db37c74 chore: fix linter 2024-06-19 11:25:02 +05:30
ruthra kumar
e3608f285f Merge branch 'version-15' into version-15-hotfix 2024-06-19 11:02:14 +05:30
Raffael Meyer
c110a9f2ad Merge pull request #41945 from frappe/mergify/bp/version-15-hotfix/pr-41421
fix: migrate lead notes (backport #41421)
2024-06-19 01:17:52 +02:00
barredterra
24ee765e6a fix: only show user and date if available
(cherry picked from commit 895aede590)
2024-06-18 22:57:25 +00:00
barredterra
5663432bd8 fix: migrate lead notes
(cherry picked from commit 382d0ff453)
2024-06-18 22:57:24 +00:00
ruthra kumar
d64432c3f4 Merge pull request #41938 from frappe/mergify/bp/version-15-hotfix/pr-41900
refactor: ignore unreconcile doc for PO and SO on cancel/delete (backport #41900)
2024-06-18 10:54:51 +05:30
ljain112
7cc5579eca refactor: ignore unreconcile doc for PO and SO on cancel/delete
(cherry picked from commit b618d685c6)
2024-06-18 04:58:09 +00:00
rohitwaghchaure
60b16a4b1e Merge pull request #41935 from frappe/mergify/bp/version-15-hotfix/pr-41931
fix: reposting validation related PCV (backport #41931)
2024-06-18 09:41:43 +05:30
Rohit Waghchaure
794ade832f fix: reposting validation related PCV
(cherry picked from commit 194f1dc674)
2024-06-17 12:21:59 +00:00
rohitwaghchaure
75edb7708f Merge pull request #41932 from frappe/mergify/bp/version-15-hotfix/pr-41907
fix: add strings for translation in pos_item_cart.js (backport #41907)
2024-06-17 17:49:24 +05:30
mahsem
f4852d472a fix: add strings for translation in pos_item_cart.js
fix: add strings for translation in pos_item_cart.js
(cherry picked from commit 2fb3e5da4a)
2024-06-17 11:40:49 +00:00
rohitwaghchaure
db7fb7d7b1 Merge pull request #41928 from frappe/mergify/bp/version-15-hotfix/pr-41927
fix: consistent query field name in item wise purchase register with item wise sales register (backport #41927)
2024-06-17 16:53:28 +05:30
rohitwaghchaure
ae0725d55a Merge pull request #41929 from frappe/mergify/bp/version-15-hotfix/pr-41920
fix: handle NoneType error where customer details are not available in sales register (backport #41920)
2024-06-17 16:52:59 +05:30
ljain112
ceafa0ce28 fix: handle NoneType error where customer details are not available in sales register
(cherry picked from commit f876fec6f5)
2024-06-17 09:29:38 +00:00
ljain112
a43c181673 fix: consistent query field name in item wise purchase register with item wise sales register
(cherry picked from commit 6d539e0fc0)
2024-06-17 09:28:27 +00:00
rohitwaghchaure
ae83236b7c Merge pull request #41926 from frappe/mergify/bp/version-15-hotfix/pr-41921
fix: item_code filter in item-wise sales-purchase register (backport #41921)
2024-06-17 14:56:21 +05:30
Nihantra Patel
98c8feded0 fix: item_code filter in item-wise sales-purchase register
(cherry picked from commit 757aef3972)
2024-06-17 08:32:26 +00:00
rohitwaghchaure
5a2005395b Merge pull request #41918 from frappe/mergify/bp/version-15-hotfix/pr-41898
fix: update received qty in MR on purchase invoice submit with update stock (backport #41898)
2024-06-17 13:59:54 +05:30
rohitwaghchaure
ecb889707d Merge pull request #41924 from frappe/mergify/bp/version-15-hotfix/pr-41922
fix: duplicate rows fetching in RFQ (backport #41922)
2024-06-17 13:58:15 +05:30
ruthra kumar
e3539ac2de Merge pull request #41913 from frappe/mergify/bp/version-15-hotfix/pr-40187
fix: valuation tax entries on LCV after billing PR (backport #40187)
2024-06-17 13:53:17 +05:30
Rohit Waghchaure
c159e3b06f fix: duplicate rows fetching in RFQ
(cherry picked from commit 555510c128)
2024-06-17 07:36:59 +00:00
Nihantra C. Patel
7e9f6aee58 fix: update received qty in MR on purchase invoice submit with update stock 2024-06-17 11:39:42 +05:30
Nihantra Patel
084658e8ff fix: add test case for update received qty in MR - import sorter
(cherry picked from commit 77959596db)
2024-06-17 06:06:35 +00:00
Nihantra Patel
21596c6c23 fix: add test case for update received qty in MR - import sorter
(cherry picked from commit 73f22ba9a0)
2024-06-17 06:06:35 +00:00
Nihantra Patel
858058c9e1 fix: add test case for update received qty in MR
(cherry picked from commit 62e4e88f1d)
2024-06-17 06:06:34 +00:00
Nihantra Patel
aaee02835b fix: add test case for update received qty in MR
(cherry picked from commit cff1050159)
2024-06-17 06:06:34 +00:00
Nihantra Patel
125d97a182 fix: add test case for update received qty in MR
(cherry picked from commit ebb0cef601)
2024-06-17 06:06:34 +00:00
Nihantra Patel
4551b4b638 fix: update received qty in MR on purchase invoice submit with update stock
(cherry picked from commit 13cb53fa89)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
2024-06-17 06:06:34 +00:00
rohitwaghchaure
9771bbdb75 Merge pull request #41917 from frappe/mergify/bp/version-15-hotfix/pr-41916
fix: incorrect batch return from sales return (backport #41916)
2024-06-17 11:35:24 +05:30
Rohit Waghchaure
b64b4330a3 fix: incorrect batch return from sales return
(cherry picked from commit 317047c808)
2024-06-17 05:47:25 +00:00
ruthra kumar
b577d95ecd chore: resolve conflicts 2024-06-16 20:50:03 +05:30
Gursheen Anand
248e9cac71 chore: resolve conflicts
(cherry picked from commit 54a58e9205)

# Conflicts:
#	erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
2024-06-15 15:12:22 +00:00
Gursheen Anand
4c11f2bff2 fix: reset perpetual inventory flag after test
(cherry picked from commit 0b36cbe307)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-06-15 15:12:22 +00:00
Gursheen Anand
8618402829 fix: parameters for PI references
(cherry picked from commit 8b3d46610e)

# Conflicts:
#	erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2024-06-15 15:12:22 +00:00
Gursheen Anand
c7c9d33954 test: LCV entries after billing
(cherry picked from commit 53642e7417)

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

# Conflicts:
#	erpnext/stock/doctype/landed_cost_voucher/landed_cost_voucher.py
2024-06-15 15:12:21 +00:00
Smit Vora
69de359728 Merge pull request #41890 from frappe/mergify/bp/version-15-hotfix/pr-41842
fix: regional overide for updating item valution (backport #41842)
2024-06-15 09:16:01 +05:30
ljain112
5ea2cdcaad fix: regional overide for updating item valution
(cherry picked from commit 1a10f0bcbd)
2024-06-13 08:09:51 +00:00
rohitwaghchaure
ac2e760d81 Merge pull request #41888 from frappe/mergify/bp/version-15-hotfix/pr-41886
fix: download materials request plan in production plan (backport #41886)
2024-06-13 11:23:59 +05:30
Kishan0330
164973a42c refactor: change warehousesData variable name
(cherry picked from commit f4e369977a)
2024-06-13 05:45:17 +00:00
Kishan0330
9cb7c279a4 fix: download materials request plan in production plan
(cherry picked from commit 6e55651795)
2024-06-13 05:45:17 +00:00
Frappe PR Bot
9ccfbe1bf5 chore(release): Bumped to Version 15.27.6
## [15.27.6](https://github.com/frappe/erpnext/compare/v15.27.5...v15.27.6) (2024-06-12)

### Bug Fixes

* batch qty in the dropdown field ([2c9b390](2c9b3908dd))
* return from accepted and rejected warehouse at a same time not working ([00b7c49](00b7c49b4b))
2024-06-12 11:54:13 +00:00
rohitwaghchaure
5004d95f59 Merge pull request #41873 from frappe/mergify/bp/version-15/pr-41868
fix: batch qty in the dropdown field (backport #41865) (backport #41868)
2024-06-12 17:22:57 +05:30
rohitwaghchaure
2990b4ec85 Merge pull request #41875 from frappe/mergify/bp/version-15/pr-41874
fix: return from accepted and rejected warehouse at a same time not working (backport #41872) (backport #41874)
2024-06-12 17:22:39 +05:30
mergify[bot]
3bc5076dfc fix: allow Employee role to select Department (backport #41877) (#41881)
* fix: allow Employee role to select Department (#41877)

(cherry picked from commit 56082f5a29)

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

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-06-12 17:19:36 +05:30
Frappe PR Bot
b34191e81f chore(release): Bumped to Version 15.27.5
## [15.27.5](https://github.com/frappe/erpnext/compare/v15.27.4...v15.27.5) (2024-06-12)

### Bug Fixes

* use invoice outstanding on Dunning ([#41817](https://github.com/frappe/erpnext/issues/41817)) ([a89b4f4](a89b4f49fe))
2024-06-12 11:32:40 +00:00
ruthra kumar
59be55fd8a Merge pull request #41879 from frappe/mergify/bp/version-15/pr-41817
fix: use invoice outstanding on Dunning (backport #41817)
2024-06-12 17:01:13 +05:30
ruthra kumar
a89b4f49fe fix: use invoice outstanding on Dunning (#41817)
(cherry picked from commit cf0a29b05f)
2024-06-12 11:13:34 +00:00
ruthra kumar
2f5533c676 Merge pull request #41876 from frappe/mergify/bp/version-15-hotfix/pr-41817
fix: use invoice outstanding on Dunning (backport #41817)
2024-06-12 16:42:08 +05:30
ruthra kumar
04f0c96af7 fix: use invoice outstanding on Dunning (#41817)
(cherry picked from commit cf0a29b05f)
2024-06-12 10:54:57 +00:00
Rohit Waghchaure
00b7c49b4b fix: return from accepted and rejected warehouse at a same time not working
(cherry picked from commit 17731f09ef)
(cherry picked from commit 6c57971abc)
2024-06-12 10:51:44 +00:00
rohitwaghchaure
6e9ad4ddd2 Merge pull request #41874 from frappe/mergify/bp/version-15-hotfix/pr-41872
fix: return from accepted and rejected warehouse at a same time not working (backport #41872)
2024-06-12 16:20:15 +05:30
Rohit Waghchaure
6c57971abc fix: return from accepted and rejected warehouse at a same time not working
(cherry picked from commit 17731f09ef)
2024-06-12 10:17:33 +00:00
Rohit Waghchaure
2c9b3908dd fix: batch qty in the dropdown field
(cherry picked from commit eb426c69fe)
(cherry picked from commit 67d1709ef8)
2024-06-12 10:17:32 +00:00
rohitwaghchaure
c04ba3864e Merge pull request #41868 from frappe/mergify/bp/version-15-hotfix/pr-41865
fix: batch qty in the dropdown field (backport #41865)
2024-06-12 15:46:06 +05:30
rohitwaghchaure
da15df1f28 Merge pull request #41869 from frappe/mergify/bp/version-15-hotfix/pr-41650
chore: typo in bom_operation.json (backport #41650)
2024-06-12 15:22:51 +05:30
rohitwaghchaure
94ef2eabb1 Merge pull request #41870 from frappe/mergify/bp/version-15-hotfix/pr-41867
fix: download materials request plan in PP (backport #41867)
2024-06-12 15:22:33 +05:30
Nihantra C. Patel
337082512e fix: download materials request plan in PP -prettier
(cherry picked from commit a1c4e0e93c)
2024-06-12 07:33:12 +00:00
Himanshu Shivhare
764235b390 chore: typo in bom_operation.json (#41650)
chore: typo in bom_operation.json
(cherry picked from commit 7ee2a19f53)
2024-06-12 07:33:11 +00:00
Nihantra C. Patel
7193633773 fix: download materials request plan in PP
(cherry picked from commit cb52b76342)
2024-06-12 07:33:11 +00:00
Nihantra C. Patel
ef2a6c788e fix: download materials request plan in PP
(cherry picked from commit f4acdd9636)
2024-06-12 07:33:11 +00:00
Rohit Waghchaure
67d1709ef8 fix: batch qty in the dropdown field
(cherry picked from commit eb426c69fe)
2024-06-12 07:32:03 +00:00
Frappe PR Bot
4d2d38cd9d chore(release): Bumped to Version 15.27.4
## [15.27.4](https://github.com/frappe/erpnext/compare/v15.27.3...v15.27.4) (2024-06-11)

### Bug Fixes

* Add additional condition application ([1fca6ea](1fca6ea5e7))
* Add posting date to key for consolidated view ([9472085](94720851c6))
* Add timestamp to key for immutable views ([9e9bc8b](9e9bc8b59c))
* asset depreciations and balances report correction (backport [#41824](https://github.com/frappe/erpnext/issues/41824)) ([#41851](https://github.com/frappe/erpnext/issues/41851)) ([28b7fad](28b7fad579))
* calculate totals and taxes ([5544309](5544309048))
* Do no apply pricing rule on qty change for mapped docs ([822bc58](822bc581f3))
* do not fetch items with no active BOM in PP (backport [#41833](https://github.com/frappe/erpnext/issues/41833)) ([#41835](https://github.com/frappe/erpnext/issues/41835)) ([30c0b2b](30c0b2bb54))
* enable no_copy for timesheet in sales invoice ([f1ad0f6](f1ad0f6f26))
* fixing Item-wise sales register ([f36db7e](f36db7ebaf))
* fixing Item-wise sales register [#41373](https://github.com/frappe/erpnext/issues/41373) ([5e0fa1b](5e0fa1b75e))
* fixing Item-wise sales register and purchase register [#41373](https://github.com/frappe/erpnext/issues/41373) ([a4b28ba](a4b28ba354))
* Item-wise Sales and Purchase register with no item codes [#41373](https://github.com/frappe/erpnext/issues/41373) ([96405e8](96405e8e49))
* stock_value_change for legacy serial nos (backport [#41825](https://github.com/frappe/erpnext/issues/41825)) ([#41826](https://github.com/frappe/erpnext/issues/41826)) ([a7971cf](a7971cf844))
* terms and conditions for material request (backport [#41834](https://github.com/frappe/erpnext/issues/41834)) ([#41837](https://github.com/frappe/erpnext/issues/41837)) ([1ead667](1ead66721d))
* typo in method - holiday list (backport [#41811](https://github.com/frappe/erpnext/issues/41811)) ([#41812](https://github.com/frappe/erpnext/issues/41812)) ([4d3e883](4d3e883130))
* valuation rate for backdated legacy serial/batches (backport [#41788](https://github.com/frappe/erpnext/issues/41788)) ([#41821](https://github.com/frappe/erpnext/issues/41821)) ([8d31243](8d31243a42))
* valuation rate for serial and batch bundle for current bundle (backport [#41850](https://github.com/frappe/erpnext/issues/41850)) ([#41860](https://github.com/frappe/erpnext/issues/41860)) ([3e4c568](3e4c568ddc))
* **Vehicle:** allow doc renaming and add test (backport [#41729](https://github.com/frappe/erpnext/issues/41729)) ([#41785](https://github.com/frappe/erpnext/issues/41785)) ([4d37739](4d37739dd3))
2024-06-11 13:18:31 +00:00
rohitwaghchaure
b87b438881 Merge pull request #41854 from frappe/version-15-hotfix
chore: release v15
2024-06-11 18:47:08 +05:30
mergify[bot]
3e4c568ddc fix: valuation rate for serial and batch bundle for current bundle (backport #41850) (#41860)
fix: valuation rate for serial and batch bundle for current bundle (#41850)

(cherry picked from commit 7249a691b3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-11 18:29:54 +05:30
mergify[bot]
28b7fad579 fix: asset depreciations and balances report correction (backport #41824) (#41851)
fix: asset depreciations and balances report correction (#41824)

* fix: asset depreciations and balances report correction

* chore: suppress linter warnings with # nosemgrep

(cherry picked from commit 857c689405)

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2024-06-11 18:18:11 +05:30
Frappe PR Bot
6157119bcf chore(release): Bumped to Version 15.27.3
## [15.27.3](https://github.com/frappe/erpnext/compare/v15.27.2...v15.27.3) (2024-06-11)

### Bug Fixes

* Add timestamp to key for immutable views ([439ef10](439ef109f3))
2024-06-11 09:50:57 +00:00
Deepesh Garg
144d7828e9 Merge pull request #41856 from frappe/mergify/bp/version-15/pr-41855
fix: Add timestamp to key for immutable views (#41852)
2024-06-11 15:17:29 +05:30
Deepesh Garg
439ef109f3 fix: Add timestamp to key for immutable views
(cherry picked from commit 6bded59f1c)
(cherry picked from commit 9e9bc8b59c)
2024-06-11 09:41:12 +00:00
Deepesh Garg
366f68e49c Merge pull request #41855 from frappe/mergify/bp/version-15-hotfix/pr-41852
fix: Add timestamp to key for immutable views (#41852)
2024-06-11 15:06:50 +05:30
Deepesh Garg
9e9bc8b59c fix: Add timestamp to key for immutable views
(cherry picked from commit 6bded59f1c)
2024-06-11 09:36:07 +00:00
ruthra kumar
75f3b47424 Merge pull request #41847 from frappe/mergify/bp/version-15-hotfix/pr-41707
refactor: add `Is opening` flag for payment entry (backport #41707)
2024-06-11 11:02:57 +05:30
ruthra kumar
acc2e88e7b Merge pull request #41846 from frappe/mergify/bp/version-15-hotfix/pr-41685
refactor: enabling partial TDS application on partial invoice (backport #41685)
2024-06-11 10:53:48 +05:30
ruthra kumar
818a553668 test: is_opening flag for advance in separate party account
(cherry picked from commit 17f968e1e1)
2024-06-11 04:57:07 +00:00
ruthra kumar
1fc802da6f refactor: restrict to 'Advance in Separate Party Account' type
(cherry picked from commit c36f0e4a33)
2024-06-11 04:57:07 +00:00
ruthra kumar
c664a27b1e refactor: is_opening in payment entry
(cherry picked from commit 05d17d0d73)
2024-06-11 04:57:07 +00:00
ruthra kumar
c0668373c7 refactor: enabling partial TDS application on partial invoice
(cherry picked from commit 091c5496b2)
2024-06-11 10:23:53 +05:30
ruthra kumar
45edc57af8 Merge pull request #41839 from frappe/mergify/bp/version-15-hotfix/pr-41793
fix: calculate totals and taxes (backport #41793)
2024-06-10 15:23:01 +05:30
Nihantra C. Patel
5544309048 fix: calculate totals and taxes
(cherry picked from commit a7ec0c1cec)
2024-06-10 09:49:03 +00:00
mergify[bot]
1ead66721d fix: terms and conditions for material request (backport #41834) (#41837)
fix: terms and conditions for material request (#41834)

(cherry picked from commit 4b026d66dc)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-10 15:17:19 +05:30
mergify[bot]
30c0b2bb54 fix: do not fetch items with no active BOM in PP (backport #41833) (#41835)
fix: do not fetch items with no active BOM in PP (#41833)

(cherry picked from commit 36413d14d8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-10 15:16:57 +05:30
Frappe PR Bot
f2909e9784 chore(release): Bumped to Version 15.27.2
## [15.27.2](https://github.com/frappe/erpnext/compare/v15.27.1...v15.27.2) (2024-06-10)

### Bug Fixes

* Add additional condition application ([45c16f6](45c16f615c))
* fixing Item-wise sales register ([9a629f8](9a629f860c))
* fixing Item-wise sales register [#41373](https://github.com/frappe/erpnext/issues/41373) ([d75d64e](d75d64eb25))
* fixing Item-wise sales register and purchase register [#41373](https://github.com/frappe/erpnext/issues/41373) ([50ef81a](50ef81a997))
* Item-wise Sales and Purchase register with no item codes [#41373](https://github.com/frappe/erpnext/issues/41373) ([3e0123b](3e0123ba7b))
2024-06-10 04:54:40 +00:00
Deepesh Garg
cd478dd74f Merge pull request #41831 from frappe/mergify/bp/version-15/pr-41827
fix: Item-wise Sales and Purchase register with no item codes (#41424)
2024-06-10 10:23:23 +05:30
Deepesh Garg
14c98fe6f0 chore: resolve conflicts
(cherry picked from commit c29db5afcd)
2024-06-10 04:52:42 +00:00
Deepesh Garg
45c16f615c fix: Add additional condition application
(cherry picked from commit 8ec364df6f)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
(cherry picked from commit 1fca6ea5e7)
2024-06-10 04:52:42 +00:00
Deepesh Garg
7ca848c2db chore: update condition queries in qb
(cherry picked from commit d2af36e1eb)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit 209af58f83)
2024-06-10 04:52:41 +00:00
Poorvi-R-Bhat
d75d64eb25 fix: fixing Item-wise sales register #41373
(cherry picked from commit eafa88b8e9)

# Conflicts:
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit 5e0fa1b75e)
2024-06-10 04:52:41 +00:00
Poorvi-R-Bhat
50ef81a997 fix: fixing Item-wise sales register and purchase register #41373
(cherry picked from commit 76073ae228)

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

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
(cherry picked from commit 96405e8e49)
2024-06-10 04:52:41 +00:00
Poorvi
9a629f860c fix: fixing Item-wise sales register
(cherry picked from commit c90185f533)
(cherry picked from commit f36db7ebaf)
2024-06-10 04:52:41 +00:00
Deepesh Garg
873a0dd844 Merge pull request #41827 from frappe/mergify/bp/version-15-hotfix/pr-41424
fix: Item-wise Sales and Purchase register with no item codes (#41424)
2024-06-09 20:19:33 +05:30
Deepesh Garg
c29db5afcd chore: resolve conflicts 2024-06-09 20:02:39 +05:30
Deepesh Garg
1fca6ea5e7 fix: Add additional condition application
(cherry picked from commit 8ec364df6f)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
2024-06-09 06:13:28 +00:00
Deepesh Garg
209af58f83 chore: update condition queries in qb
(cherry picked from commit d2af36e1eb)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
2024-06-09 06:13:28 +00:00
Poorvi-R-Bhat
5e0fa1b75e fix: fixing Item-wise sales register #41373
(cherry picked from commit eafa88b8e9)

# Conflicts:
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
2024-06-09 06:13:28 +00:00
Poorvi-R-Bhat
a4b28ba354 fix: fixing Item-wise sales register and purchase register #41373
(cherry picked from commit 76073ae228)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
2024-06-09 06:13:27 +00:00
Poorvi-R-Bhat
96405e8e49 fix: Item-wise Sales and Purchase register with no item codes #41373
(cherry picked from commit 1b45ecfcae)

# Conflicts:
#	erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
#	erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py
2024-06-09 06:13:27 +00:00
Poorvi
f36db7ebaf fix: fixing Item-wise sales register
(cherry picked from commit c90185f533)
2024-06-09 06:13:26 +00:00
mergify[bot]
a7971cf844 fix: stock_value_change for legacy serial nos (backport #41825) (#41826)
fix: stock_value_change for legacy serial nos (#41825)

(cherry picked from commit f6a4d391c0)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-07 23:05:50 +05:30
ruthra kumar
3f1d97259a Merge pull request #41823 from ruthra-kumar/enable_no_copy_for_timesheet
fix: enable no copy for timesheet in Sales Invoice
2024-06-07 20:24:44 +05:30
mergify[bot]
8d31243a42 fix: valuation rate for backdated legacy serial/batches (backport #41788) (#41821)
fix: valuation rate for backdated legacy serial/batches (#41788)

(cherry picked from commit 3956354e08)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-07 18:25:58 +05:30
ruthra kumar
f1ad0f6f26 fix: enable no_copy for timesheet in sales invoice 2024-06-07 16:50:21 +05:30
mergify[bot]
4d37739dd3 fix(Vehicle): allow doc renaming and add test (backport #41729) (#41785)
* fix(Vehicle): allow doc renaming and add test (#41729)

fix(Vehicle): allow renaming doc and add test

(cherry picked from commit c76f466528)

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

* fix: resolve conflicts for backporting

---------

Co-authored-by: Viny Selopal <52369157+vinyselopal@users.noreply.github.com>
Co-authored-by: Viny Selopal <viny0698@gmail.com>
2024-06-07 15:45:50 +05:30
mergify[bot]
4d3e883130 fix: typo in method - holiday list (backport #41811) (#41812)
fix: typo in method - holiday list (#41811)

(cherry picked from commit 699cfd85c6)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-06-06 19:46:02 +05:30
Frappe PR Bot
df4307fef8 chore(release): Bumped to Version 15.27.1
## [15.27.1](https://github.com/frappe/erpnext/compare/v15.27.0...v15.27.1) (2024-06-06)

### Bug Fixes

* Add posting date to key for consolidated view ([edd4e67](edd4e674d3))
2024-06-06 12:20:49 +00:00
Deepesh Garg
6039fb75e7 Merge pull request #41810 from frappe/mergify/bp/version-15/pr-41809
fix: Add posting date to key for consolidated view (#41808)
2024-06-06 17:49:05 +05:30
Deepesh Garg
edd4e674d3 fix: Add posting date to key for consolidated view
(cherry picked from commit 2c164b47a1)
(cherry picked from commit 94720851c6)
2024-06-06 12:18:29 +00:00
Deepesh Garg
b4838ab098 Merge pull request #41802 from frappe/mergify/bp/version-15-hotfix/pr-41727
fix: Do no apply pricing rule on qty change for mapped docs (#41727)
2024-06-06 17:48:25 +05:30
Deepesh Garg
3507d2e37d Merge pull request #41809 from frappe/mergify/bp/version-15-hotfix/pr-41808
fix: Add posting date to key for consolidated view (#41808)
2024-06-06 17:47:35 +05:30
Deepesh Garg
94720851c6 fix: Add posting date to key for consolidated view
(cherry picked from commit 2c164b47a1)
2024-06-06 12:15:12 +00:00
ruthra kumar
08c06d1142 Merge pull request #41807 from frappe/mergify/bp/version-15-hotfix/pr-41804
chore: repost settings permission overhaul (backport #41804)
2024-06-06 16:34:28 +05:30
ruthra kumar
0e562e9933 chore: repost settings permission overhaul
(cherry picked from commit 458d8f5ed8)
2024-06-06 16:14:27 +05:30
Deepesh Garg
822bc581f3 fix: Do no apply pricing rule on qty change for mapped docs
(cherry picked from commit 2b1242170c)
2024-06-06 03:44:14 +00:00
Frappe PR Bot
dcdaa02173 chore(release): Bumped to Version 15.27.0
# [15.27.0](https://github.com/frappe/erpnext/compare/v15.26.1...v15.27.0) (2024-06-05)

### Bug Fixes

* Auditor permissions (backport [#41659](https://github.com/frappe/erpnext/issues/41659)) ([#41661](https://github.com/frappe/erpnext/issues/41661)) ([27f3981](27f3981269))
* bank account no fieldname mismatch (backport [#41778](https://github.com/frappe/erpnext/issues/41778)) ([#41783](https://github.com/frappe/erpnext/issues/41783)) ([b94a6f2](b94a6f2d5c))
* batch selection issue (backport [#41692](https://github.com/frappe/erpnext/issues/41692)) ([#41693](https://github.com/frappe/erpnext/issues/41693)) ([24775db](24775db97e))
* **Company:** Allow Equity type account in unrealised exchange gain/loss account (backport [#41740](https://github.com/frappe/erpnext/issues/41740)) ([#41747](https://github.com/frappe/erpnext/issues/41747)) ([460ee5d](460ee5d542))
* condition filter for transaction pricing rule ([e493b11](e493b11ae3))
* convert percentage from str to float (backport [#41766](https://github.com/frappe/erpnext/issues/41766)) ([#41776](https://github.com/frappe/erpnext/issues/41776)) ([cd0852f](cd0852f05d))
* Copy depreciation schedule on asset split only if it exists (backport [#41775](https://github.com/frappe/erpnext/issues/41775)) ([#41784](https://github.com/frappe/erpnext/issues/41784)) ([03bf480](03bf48032e))
* filtered out data having none values in date field (backport [#41457](https://github.com/frappe/erpnext/issues/41457)) ([#41765](https://github.com/frappe/erpnext/issues/41765)) ([97b1b7f](97b1b7f842))
* Filters in account balance report ([0b9d89b](0b9d89b966))
* French chart of account the 4191 code must be of type Income Account ([797b718](797b718e5a))
* get assets received but not billed account only if any asset item is received (backport [#41734](https://github.com/frappe/erpnext/issues/41734)) ([#41735](https://github.com/frappe/erpnext/issues/41735)) ([638c944](638c94451e))
* Ignore disabling default currency field while creating new company (backport [#41699](https://github.com/frappe/erpnext/issues/41699)) ([#41761](https://github.com/frappe/erpnext/issues/41761)) ([dc922ab](dc922abfbe))
* incorrect accumulated depr amount in asset depr ledger (backport [#41654](https://github.com/frappe/erpnext/issues/41654)) ([#41763](https://github.com/frappe/erpnext/issues/41763)) ([a93cd02](a93cd02d54))
* incorrect batch selection while sales return (backport [#41768](https://github.com/frappe/erpnext/issues/41768)) ([#41772](https://github.com/frappe/erpnext/issues/41772)) ([95c0dc9](95c0dc9b38))
* key error for stock ledger report (backport [#41700](https://github.com/frappe/erpnext/issues/41700)) ([#41703](https://github.com/frappe/erpnext/issues/41703)) ([b22d714](b22d714103))
* link opportunity in prospect after creating opportunity from prospect (backport [#41769](https://github.com/frappe/erpnext/issues/41769)) ([#41777](https://github.com/frappe/erpnext/issues/41777)) ([d30aee5](d30aee5dd6))
* local var referenced before assignment (backport [#41780](https://github.com/frappe/erpnext/issues/41780)) ([#41782](https://github.com/frappe/erpnext/issues/41782)) ([3777cae](3777cae860))
* **minor:** corrected wrong filter condition (backport [#41755](https://github.com/frappe/erpnext/issues/41755)) ([#41762](https://github.com/frappe/erpnext/issues/41762)) ([a67fa68](a67fa6863e))
* payment term when creating PO from SO (backport [#41376](https://github.com/frappe/erpnext/issues/41376)) ([#41744](https://github.com/frappe/erpnext/issues/41744)) ([806ff5b](806ff5bc19))
* Select both account number and company in the account form (backport [#41731](https://github.com/frappe/erpnext/issues/41731)) ([#41737](https://github.com/frappe/erpnext/issues/41737)) ([c5d72cd](c5d72cd934))
* show material to supplier button (backport [#41686](https://github.com/frappe/erpnext/issues/41686)) ([#41688](https://github.com/frappe/erpnext/issues/41688)) ([1a24914](1a24914aed))
* **stock settings:** Allowed any number in stock frozen upto days field (backport [#41736](https://github.com/frappe/erpnext/issues/41736)) ([#41749](https://github.com/frappe/erpnext/issues/41749)) ([278682f](278682f4df))
* test for pricing rule transaction with cond ([0823de8](0823de86ad))
* Transaction currency value in Journal Entry (backport [#41717](https://github.com/frappe/erpnext/issues/41717)) ([#41720](https://github.com/frappe/erpnext/issues/41720)) ([77f58ca](77f58caa93))
* TypeError: 'float' object is not iterable (backport [#41758](https://github.com/frappe/erpnext/issues/41758)) ([#41764](https://github.com/frappe/erpnext/issues/41764)) ([12addb7](12addb7565))
* Use full name instead of abbreviation ([#41759](https://github.com/frappe/erpnext/issues/41759)) ([5448d5d](5448d5d1cb))
* work order created message pops up if no items are selected (backport [#41677](https://github.com/frappe/erpnext/issues/41677)) ([#41682](https://github.com/frappe/erpnext/issues/41682)) ([4e9faf6](4e9faf6ad6))

### Features

* optional to reconcile all serial nos / batches in stock reconciliation (backport [#41696](https://github.com/frappe/erpnext/issues/41696)) ([#41713](https://github.com/frappe/erpnext/issues/41713)) ([38249f4](38249f4170))
2024-06-05 01:20:36 +00:00
ruthra kumar
cd511c5277 Merge pull request #41773 from frappe/version-15-hotfix
chore: release v15
2024-06-05 06:49:10 +05:30
mergify[bot]
03bf48032e fix: Copy depreciation schedule on asset split only if it exists (backport #41775) (#41784)
fix: Copy depreciation schedule on asset split only if it exists (#41775)

(cherry picked from commit 689e1cfc23)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 22:25:40 +05:30
mergify[bot]
b94a6f2d5c fix: bank account no fieldname mismatch (backport #41778) (#41783)
fix: bank account no fieldname mismatch (#41778)

(cherry picked from commit d163dbec7d)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 22:25:28 +05:30
mergify[bot]
3777cae860 fix: local var referenced before assignment (backport #41780) (#41782)
fix: local var referenced before assignment (#41780)

(cherry picked from commit 4ff3e6caaa)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 22:25:20 +05:30
mergify[bot]
a67fa6863e fix(minor): corrected wrong filter condition (backport #41755) (#41762)
* fix(minor): corrected wrong filter condition (#41755)

(cherry picked from commit 60eb03a6c6)

# Conflicts:
#	erpnext/assets/report/fixed_asset_register/fixed_asset_register.py

* fix: resolved conflict

---------

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 21:53:28 +05:30
mergify[bot]
cd0852f05d fix: convert percentage from str to float (backport #41766) (#41776)
fix: convert percentage from str to float (#41766)

(cherry picked from commit 71f5470dfd)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 21:50:28 +05:30
mergify[bot]
d30aee5dd6 fix: link opportunity in prospect after creating opportunity from prospect (backport #41769) (#41777)
fix: link opportunity in prospect after creating opportunity from prospect (#41769)

(cherry picked from commit 12e48f0b63)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 21:50:18 +05:30
mergify[bot]
12addb7565 fix: TypeError: 'float' object is not iterable (backport #41758) (#41764)
* fix: TypeError: 'float' object is not iterable (#41758)

(cherry picked from commit cf508ce1ed)

# Conflicts:
#	erpnext/manufacturing/doctype/bom_creator/bom_creator.py
#	erpnext/public/js/bom_configurator/bom_configurator.bundle.js

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-04 14:54:34 +05:30
mergify[bot]
95c0dc9b38 fix: incorrect batch selection while sales return (backport #41768) (#41772)
fix: incorrect batch selection while sales return (#41768)

(cherry picked from commit cb6d8afa26)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-04 14:54:20 +05:30
mergify[bot]
97b1b7f842 fix: filtered out data having none values in date field (backport #41457) (#41765)
* fix: filtered out data having none values in date field

(cherry picked from commit 3bd455ac85)

* style: code optimization

(cherry picked from commit a36b7fb95a)

---------

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2024-06-04 12:21:16 +05:30
mergify[bot]
27f3981269 fix: Auditor permissions (backport #41659) (#41661)
* fix: allow Auditor to select a company

(cherry picked from commit 06401cc84f)

* fix: allow Auditor to read a Fiscal Year

(cherry picked from commit eaa4efbc45)

---------

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2024-06-04 12:19:36 +05:30
mergify[bot]
77f58caa93 fix: Transaction currency value in Journal Entry (backport #41717) (#41720)
fix: Transaction currency value in Journal Entry

(cherry picked from commit 169d77da54)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2024-06-04 12:18:28 +05:30
mergify[bot]
a93cd02d54 fix: incorrect accumulated depr amount in asset depr ledger (backport #41654) (#41763)
fix: incorrect accumulated depr amount in asset depr ledger (#41654)

* fix: incorrect accumulated depr amount in asset depr ledger

* refactor: depreciation amount retrieval with query builder

* style: apply formatting changes from pre-commit

(cherry picked from commit a8fc32dc32)

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2024-06-04 12:03:55 +05:30
mergify[bot]
dc922abfbe fix: Ignore disabling default currency field while creating new company (backport #41699) (#41761)
fix: Ignore disabling default currency field while creating new company (#41699)

(cherry picked from commit 80f6228d45)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 11:55:35 +05:30
Nabin Hait
5448d5d1cb fix: Use full name instead of abbreviation (#41759) 2024-06-04 11:41:30 +05:30
mergify[bot]
278682f4df fix(stock settings): Allowed any number in stock frozen upto days field (backport #41736) (#41749)
fix(stock settings): Allowed any number in stock frozen upto days field (#41736)

(cherry picked from commit 740c495014)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-04 11:22:32 +05:30
mergify[bot]
460ee5d542 fix(Company): Allow Equity type account in unrealised exchange gain/loss account (backport #41740) (#41747)
fix(Company): Allow Equity type account in unrealised exchange gain/loss account (#41740)

(cherry picked from commit d30c797d24)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-03 18:38:25 +05:30
mergify[bot]
806ff5bc19 fix: payment term when creating PO from SO (backport #41376) (#41744)
fix: payment term when creating PO from SO (#41376)

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

* fix: payment term when creating PO from SO

(cherry picked from commit 441596f795)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-06-03 18:37:39 +05:30
mergify[bot]
c5d72cd934 fix: Select both account number and company in the account form (backport #41731) (#41737)
fix: Select both account number and company in the account form (#41731)

* fix: Both the account number and the company should be selected in the account form

* fix: select both account number and company in the account form

(cherry picked from commit 5a75c847fe)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-06-03 18:36:58 +05:30
ruthra kumar
dd0cd8c4f8 Merge pull request #41746 from frappe/mergify/bp/version-15-hotfix/pr-41742
chore: System Manager should have  submit permission for repost doctypes (backport #41742)
2024-06-03 18:33:44 +05:30
ruthra kumar
d5158c6062 chore: Sys Manager shluld have submit permission for repost doctypes
(cherry picked from commit 4558f64c0f)
2024-06-03 12:21:05 +00:00
mergify[bot]
638c94451e fix: get assets received but not billed account only if any asset item is received (backport #41734) (#41735)
fix: get assets received but not billed account only if any asset item is received (#41734)

fix: get assets received but not billed account only if any asset item received
(cherry picked from commit 39885b2b01)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-06-03 16:18:29 +05:30
ruthra kumar
8ff5a67b99 Merge pull request #41714 from frappe/mergify/bp/version-15-hotfix/pr-41658
fix: condition-wise filter for transaction based pricing rule (backport #41658)
2024-06-01 18:31:11 +05:30
mergify[bot]
38249f4170 feat: optional to reconcile all serial nos / batches in stock reconciliation (backport #41696) (#41713)
* feat: optional to reconcile all serial nos / batches in stock reconciliation (#41696)

feat: optional to reconcile all serial/batch
(cherry picked from commit ee846f5950)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-06-01 18:30:33 +05:30
Dany Robert
0823de86ad fix: test for pricing rule transaction with cond
(cherry picked from commit 3f2343614b)
2024-06-01 12:45:20 +00:00
Dany Robert
e493b11ae3 fix: condition filter for transaction pricing rule
(cherry picked from commit e3fd82766f)
2024-06-01 12:45:19 +00:00
ruthra kumar
f73737db50 Merge pull request #41706 from frappe/mergify/bp/version-15-hotfix/pr-41232
fix: French chart of account the 4191 code must be of type Income Account (backport #41232)
2024-06-01 16:06:59 +05:30
Deepesh Garg
8d997c6703 Merge pull request #41678 from frappe/mergify/bp/version-15-hotfix/pr-41676
fix: Filters in account balance report (#41676)
2024-05-31 20:02:20 +05:30
Florian HENRY
797b718e5a fix: French chart of account the 4191 code must be of type Income Account
(cherry picked from commit 72057adc94)
2024-05-31 09:56:01 +00:00
mergify[bot]
b22d714103 fix: key error for stock ledger report (backport #41700) (#41703)
fix: key error for stock ledger report (#41700)

(cherry picked from commit 4e37ed9033)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-31 12:22:07 +05:30
Frappe PR Bot
55121a22a5 chore(release): Bumped to Version 15.26.1
## [15.26.1](https://github.com/frappe/erpnext/compare/v15.26.0...v15.26.1) (2024-05-30)

### Bug Fixes

* batch selection issue (backport [#41692](https://github.com/frappe/erpnext/issues/41692)) (backport [#41693](https://github.com/frappe/erpnext/issues/41693)) ([#41694](https://github.com/frappe/erpnext/issues/41694)) ([64835b9](64835b99ec))
2024-05-30 13:57:20 +00:00
mergify[bot]
64835b99ec fix: batch selection issue (backport #41692) (backport #41693) (#41694)
fix: batch selection issue (backport #41692) (#41693)

fix: batch selection issue (#41692)

(cherry picked from commit 968120d0eb)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-30 19:26:02 +05:30
mergify[bot]
4e9faf6ad6 fix: work order created message pops up if no items are selected (backport #41677) (#41682)
fix: work order created message pops up if no items are selected (#41677)

(cherry picked from commit 388ba7f945)

Co-authored-by: Nijith anil <83776819+nijithanil@users.noreply.github.com>
2024-05-30 18:51:26 +05:30
mergify[bot]
24775db97e fix: batch selection issue (backport #41692) (#41693)
fix: batch selection issue (#41692)

(cherry picked from commit 968120d0eb)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-30 18:49:12 +05:30
mergify[bot]
1a24914aed fix: show material to supplier button (backport #41686) (#41688)
fix: show material to supplier button (#41686)

(cherry picked from commit be9f960705)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-30 16:13:53 +05:30
Frappe PR Bot
56d83d44be chore(release): Bumped to Version 15.26.0
# [15.26.0](https://github.com/frappe/erpnext/compare/v15.25.0...v15.26.0) (2024-05-29)

### Bug Fixes

* add in some indices to speed up Purchase Order deletion ([3ed3b21](3ed3b214c8))
* cost center filter according to the company in project ([193b844](193b844bf1))
* cost center filter according to the company in project ([e6aaab3](e6aaab38b0))
* cost center filter according to the company in project ([563e15e](563e15e1c8))
* multiple issues related to serial and batch bundle (backport [#41662](https://github.com/frappe/erpnext/issues/41662)) ([#41668](https://github.com/frappe/erpnext/issues/41668)) ([dc0bb22](dc0bb220ed))
* not allow template item in product bundle item ([8fb3294](8fb3294674))
* not allow template item in product bundle item ([b64f5a4](b64f5a4e54))
* not allow template item in product bundle item - v15/v14 ([9864377](9864377b47))
* opening stock not showing in the stock ledger report for the bat… (backport [#41584](https://github.com/frappe/erpnext/issues/41584)) ([#41590](https://github.com/frappe/erpnext/issues/41590)) ([162ec7d](162ec7d6e8))
* SCR batch qty issue (backport [#41595](https://github.com/frappe/erpnext/issues/41595)) ([#41599](https://github.com/frappe/erpnext/issues/41599)) ([17ea958](17ea958170))
* set expense account as Assets RBNB only if it is booked in linked PR (backport [#41368](https://github.com/frappe/erpnext/issues/41368)) ([#41673](https://github.com/frappe/erpnext/issues/41673)) ([0a0970e](0a0970e0e7))
* Unable to 'Get Suppliers' using tags in Request for Quotation (backport [#41626](https://github.com/frappe/erpnext/issues/41626)) ([#41627](https://github.com/frappe/erpnext/issues/41627)) ([ca855e8](ca855e8ab8))

### Features

* Add Party details to Serial No Ledger Report ([#41656](https://github.com/frappe/erpnext/issues/41656)) ([7462de6](7462de66ce))

### Performance Improvements

* sales order UI render (backport [#41591](https://github.com/frappe/erpnext/issues/41591)) ([#41592](https://github.com/frappe/erpnext/issues/41592)) ([09d112a](09d112a061))
2024-05-29 07:54:16 +00:00
ruthra kumar
e940d13068 Merge pull request #41666 from frappe/version-15-hotfix
chore: release v15
2024-05-29 13:22:52 +05:30
Deepesh Garg
0b9d89b966 fix: Filters in account balance report
(cherry picked from commit 1c9fe691ea)
2024-05-29 07:20:47 +00:00
mergify[bot]
0a0970e0e7 fix: set expense account as Assets RBNB only if it is booked in linked PR (backport #41368) (#41673)
fix: set expense account as Assets RBNB only if it is booked in linked PR (#41368)

* fix: set expense account as Assets RBNB only if it is booked in linked PR

* fix: broken translations

(cherry picked from commit 014486de39)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-05-29 11:07:07 +05:30
Deepesh Garg
d29686f882 Merge pull request #41375 from Nihantra-Patel/no_add_variant_item_15-14
fix: not allow template item in product bundle item - v15/v14
2024-05-29 10:30:47 +05:30
mergify[bot]
dc0bb220ed fix: multiple issues related to serial and batch bundle (backport #41662) (#41668)
* fix: multiple issues related to serial and batch bundle (#41662)

(cherry picked from commit ce834f5dba)

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

* chore: fix conflicts

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-28 21:57:13 +05:30
Marica
2e8ae4dc30 Merge pull request #41667 from frappe/mergify/bp/version-15-hotfix/pr-41656
feat: Add Party details to Serial No Ledger Report (backport #41656)
2024-05-28 16:36:44 +05:30
Marica
7462de66ce feat: Add Party details to Serial No Ledger Report (#41656)
- Since no party details are present in Serial No anymore, it is hard to get a view of which SN was sold to/purchased from which party
- Add Party fields to report

(cherry picked from commit e3cf53a8b7)
2024-05-28 09:59:35 +00:00
ruthra kumar
c8098e9691 Merge pull request #41649 from frappe/mergify/bp/version-15-hotfix/pr-41401
fix: cost center filter according to the company in project (backport #41401)
2024-05-27 10:42:09 +05:30
Nihantra C. Patel
193b844bf1 fix: cost center filter according to the company in project
(cherry picked from commit 501c6aa126)
2024-05-27 04:41:12 +00:00
Nihantra C. Patel
e6aaab38b0 fix: cost center filter according to the company in project
(cherry picked from commit cfde8088b4)
2024-05-27 04:41:12 +00:00
Nihantra C. Patel
563e15e1c8 fix: cost center filter according to the company in project
(cherry picked from commit 249e8264dd)
2024-05-27 04:41:11 +00:00
mergify[bot]
ca855e8ab8 fix: Unable to 'Get Suppliers' using tags in Request for Quotation (backport #41626) (#41627)
fix: Unable to 'Get Suppliers' using tags in Request for Quotation (#41626)

(cherry picked from commit 683c1f04c8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-24 13:09:15 +05:30
Akhil Narang
7a0aef218f Merge pull request #41625 from frappe/mergify/bp/version-15-hotfix/pr-41601
fix: add in some indices to speed up Purchase Order deletion (backport #41601)
2024-05-24 12:27:29 +05:30
Akhil Narang
8f24fd6a60 Merge pull request #41611 from frappe/mergify/bp/version-15-hotfix/pr-41609
refactor: use `json` directly instead of using `frappe.json` (backport #41609)
2024-05-24 11:07:12 +05:30
Akhil Narang
c68afbc715 chore: resolve conflicts 2024-05-24 11:05:59 +05:30
Akhil Narang
3ed3b214c8 fix: add in some indices to speed up Purchase Order deletion
`tabSales Order`.`inter_company_order_reference`
`tabSales Invoice Item`.`purchase_order`

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

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
2024-05-24 05:28:24 +00:00
ruthra kumar
26569742fd Merge pull request #41605 from frappe/mergify/bp/version-15-hotfix/pr-41603
refactor: remove 'format:' based naming in internal doctypes (backport #41603)
2024-05-24 10:54:55 +05:30
ruthra kumar
d96c5885a3 Merge pull request #41607 from frappe/mergify/bp/version-15-hotfix/pr-41594
refactor: 'Payment Period Based On Invoice Date' report (backport #41594)
2024-05-24 10:53:51 +05:30
Akhil Narang
7af1b5d4ec refactor: use json directly instead of using frappe.json (#41609)
(cherry picked from commit 3f06f1905f)
Signed-off-by: Akhil Narang <me@akhilnarang.dev>
2024-05-24 10:51:09 +05:30
ruthra kumar
1ad2f06500 chore: resolve conflicts 2024-05-23 17:49:05 +05:30
ruthra kumar
22dd642413 refactor: replace against_voucher with against_voucher_no
(cherry picked from commit c4e2abb973)
2024-05-23 12:16:51 +00:00
ruthra kumar
37c90ef873 refactor: remove debit and credit
(cherry picked from commit 014b542cf3)
2024-05-23 12:16:50 +00:00
ruthra kumar
e0cb3ecc0f refactor: query payment ledger for payments
(cherry picked from commit cb3c20dcd3)
2024-05-23 12:16:50 +00:00
ruthra kumar
3176bb480f refactor: remove 'format:' based naming in internal doctypes
(cherry picked from commit e2ec3e453a)

# Conflicts:
#	erpnext/accounts/doctype/repost_accounting_ledger/repost_accounting_ledger.json
#	erpnext/accounts/doctype/repost_payment_ledger/repost_payment_ledger.json
2024-05-23 12:15:33 +00:00
mergify[bot]
17ea958170 fix: SCR batch qty issue (backport #41595) (#41599)
fix: SCR batch qty issue (#41595)

(cherry picked from commit 418439b58f)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-23 16:30:30 +05:30
Akhil Narang
c16debb8ee Merge pull request #41596 from frappe/mergify/bp/version-15-hotfix/pr-41576
chore: sync ruff config with framework (backport #41576)
2024-05-23 14:15:08 +05:30
Ankush Menat
58feaf1f4a ci: ruff only fix imports
(cherry picked from commit 85b1a8001b)
2024-05-23 07:22:22 +00:00
Ankush Menat
dc813ddaec ci: dont auto apply fixes
I've personally encountered ~5 instances of bad auto fixes, let
developers apply the fixes.

(cherry picked from commit 3b4913ec81)
2024-05-23 07:22:22 +00:00
mergify[bot]
09d112a061 perf: sales order UI render (backport #41591) (#41592)
perf: sales order UI render (#41591)

(cherry picked from commit ad817cddad)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-23 11:50:34 +05:30
mergify[bot]
162ec7d6e8 fix: opening stock not showing in the stock ledger report for the bat… (backport #41584) (#41590)
fix: opening stock not showing in the stock ledger report for the bat… (#41584)

fix: opening stock not showing in the stock ledger report for the batch filter
(cherry picked from commit 04a49cef24)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-22 19:58:27 +05:30
Frappe PR Bot
a3fdfba46f chore(release): Bumped to Version 15.25.0
# [15.25.0](https://github.com/frappe/erpnext/compare/v15.24.1...v15.25.0) (2024-05-22)

### Bug Fixes

* added validation message for low gross purchase amount (backport [#41502](https://github.com/frappe/erpnext/issues/41502)) ([#41553](https://github.com/frappe/erpnext/issues/41553)) ([89ba7a2](89ba7a22fb))
* Auto reconcile only after selecting bank account (backport [#41489](https://github.com/frappe/erpnext/issues/41489)) ([#41554](https://github.com/frappe/erpnext/issues/41554)) ([33eb251](33eb251727))
* bold total in exponential smoothing forecasting (backport [#41393](https://github.com/frappe/erpnext/issues/41393)) ([#41404](https://github.com/frappe/erpnext/issues/41404)) ([8101b51](8101b51899))
* BOM creator validation for parent row no (backport [#41413](https://github.com/frappe/erpnext/issues/41413)) ([#41558](https://github.com/frappe/erpnext/issues/41558)) ([953de99](953de995bc))
* convert invoice_portion value from str to float (backport [#41485](https://github.com/frappe/erpnext/issues/41485)) ([#41555](https://github.com/frappe/erpnext/issues/41555)) ([0a36139](0a36139ef4))
* correct report name in inner button (backport [#41568](https://github.com/frappe/erpnext/issues/41568)) ([#41572](https://github.com/frappe/erpnext/issues/41572)) ([4ccc426](4ccc426fec))
* create custom field for accounting dimensions only if the field not exists already ([#41557](https://github.com/frappe/erpnext/issues/41557)) ([68fa55c](68fa55ca02))
* Deadlock on submitting Sales Invoice (backport [#41417](https://github.com/frappe/erpnext/issues/41417)) ([#41562](https://github.com/frappe/erpnext/issues/41562)) ([49db19d](49db19d57a))
* Demo data clearing ([46ec61f](46ec61f0c9))
* Filters in trend reports ([52d5d7a](52d5d7a4d3))
* job card time logs overlap issue (backport [#41567](https://github.com/frappe/erpnext/issues/41567)) ([#41571](https://github.com/frappe/erpnext/issues/41571)) ([6554f19](6554f192fb))
* minor Dr and Cr between Purchase Receipt and Purchase Invoice ([3872cdc](3872cdc54a))
* not able to delete line items in the subcontracting receipt (backport [#41569](https://github.com/frappe/erpnext/issues/41569)) ([#41570](https://github.com/frappe/erpnext/issues/41570)) ([26c3235](26c3235bf9))
* not able to submit landed cost voucher (backport [#41481](https://github.com/frappe/erpnext/issues/41481)) ([#41486](https://github.com/frappe/erpnext/issues/41486)) ([a070ad7](a070ad786d))
* possible sql error on General Ledger ([e0a0cb7](e0a0cb7b25))
* print format bold for field "total" ([e36880d](e36880da2d))
* priority not working for multiple pricing rules (backport [#41516](https://github.com/frappe/erpnext/issues/41516)) ([#41525](https://github.com/frappe/erpnext/issues/41525)) ([5fd68f9](5fd68f9fcb))
* Show acheived amount and variance for parent item groups (backport [#41495](https://github.com/frappe/erpnext/issues/41495)) ([#41551](https://github.com/frappe/erpnext/issues/41551)) ([5e0bff3](5e0bff3a60))
* stock levels for batch (backport [#41494](https://github.com/frappe/erpnext/issues/41494)) ([#41501](https://github.com/frappe/erpnext/issues/41501)) ([938888c](938888cddd))
* timeout error while submitting purchase invoice (backport [#41520](https://github.com/frappe/erpnext/issues/41520)) ([#41522](https://github.com/frappe/erpnext/issues/41522)) ([fcd9f89](fcd9f89dee))
* typerror on hide_fields ([8ae9da5](8ae9da5484))
* Unable to add items in POS Invoice ([a90186f](a90186f9ae))
* validate reorder group warehouse (backport [#41478](https://github.com/frappe/erpnext/issues/41478)) ([#41480](https://github.com/frappe/erpnext/issues/41480)) ([a1ce514](a1ce514cf3))
* valuation rate for legacy serial nos (backport [#41543](https://github.com/frappe/erpnext/issues/41543)) ([#41545](https://github.com/frappe/erpnext/issues/41545)) ([f121b33](f121b33e29))

### Features

* Config to enable immutable ledger ([32c935b](32c935bc30))
* enter serial range in Serial/Batch Selector (backport [#41530](https://github.com/frappe/erpnext/issues/41530)) ([#41534](https://github.com/frappe/erpnext/issues/41534)) ([7225347](7225347387))
2024-05-22 08:49:10 +00:00
ruthra kumar
1b4987c5b4 Merge pull request #41574 from frappe/version-15-hotfix
chore: release v15
2024-05-22 14:17:49 +05:30
mergify[bot]
5e0bff3a60 fix: Show acheived amount and variance for parent item groups (backport #41495) (#41551)
fix: Show achieved amount and variance for parent item groups

(cherry picked from commit 8ac11ae88d)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-05-21 18:02:37 +05:30
mergify[bot]
6554f192fb fix: job card time logs overlap issue (backport #41567) (#41571)
* fix: job card time logs overlap issue (#41567)

(cherry picked from commit ac4bcd5ca7)

# Conflicts:
#	erpnext/manufacturing/doctype/job_card_time_log/job_card_time_log.json

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-21 15:01:45 +05:30
mergify[bot]
4ccc426fec fix: correct report name in inner button (backport #41568) (#41572)
fix: correct report name in inner button (#41568)

Previously, the report name was incorrectly listed as "Cash Flow Statement" instead of "Cash Flow". This mismatch caused the "Cash Flow" report to not open correctly in the chart of accounts tree view, as the report ID is "Cash Flow".

(cherry picked from commit d7df2cbdc5)

Co-authored-by: jabir-elat <44110258+jabir-elat@users.noreply.github.com>
2024-05-21 14:44:03 +05:30
mergify[bot]
26c3235bf9 fix: not able to delete line items in the subcontracting receipt (backport #41569) (#41570)
fix: not able to delete line items in the subcontracting receipt (#41569)

(cherry picked from commit 4261c3474b)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-21 14:41:13 +05:30
Nabin Hait
68fa55ca02 fix: create custom field for accounting dimensions only if the field not exists already (#41557) 2024-05-21 12:21:15 +05:30
mergify[bot]
49db19d57a fix: Deadlock on submitting Sales Invoice (backport #41417) (#41562)
fix: Deadlock on submitting Sales Invoice (#41417)

(cherry picked from commit 4e4c1e4bef)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-21 11:10:26 +05:30
mergify[bot]
953de995bc fix: BOM creator validation for parent row no (backport #41413) (#41558)
fix: BOM creator validation for parent row no (#41413)

fix: bom creator valiation for parent row no
(cherry picked from commit ae3f5a38e1)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-20 19:42:54 +05:30
mergify[bot]
0a36139ef4 fix: convert invoice_portion value from str to float (backport #41485) (#41555)
fix: convert invoice_portion value from str to float (#41485)

(cherry picked from commit a1d489195d)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-05-20 18:36:48 +05:30
mergify[bot]
33eb251727 fix: Auto reconcile only after selecting bank account (backport #41489) (#41554)
fix: Auto reconcile only after selecting bank account (#41489)

(cherry picked from commit f24d61daea)

Co-authored-by: Nabin Hait <nabinhait@gmail.com>
2024-05-20 18:36:38 +05:30
mergify[bot]
89ba7a22fb fix: added validation message for low gross purchase amount (backport #41502) (#41553)
fix: added validation message for low gross purchase amount

(cherry picked from commit 8a30701893)

Co-authored-by: Khushi Rawat <142375893+khushi8112@users.noreply.github.com>
2024-05-20 18:36:26 +05:30
Frappe PR Bot
b1d345ba0b chore(release): Bumped to Version 15.24.1
## [15.24.1](https://github.com/frappe/erpnext/compare/v15.24.0...v15.24.1) (2024-05-20)

### Bug Fixes

* valuation rate for legacy serial nos (backport [#41543](https://github.com/frappe/erpnext/issues/41543)) (backport [#41545](https://github.com/frappe/erpnext/issues/41545)) ([#41546](https://github.com/frappe/erpnext/issues/41546)) ([4ddd6e6](4ddd6e685b))
2024-05-20 10:22:57 +00:00
mergify[bot]
4ddd6e685b fix: valuation rate for legacy serial nos (backport #41543) (backport #41545) (#41546)
fix: valuation rate for legacy serial nos (backport #41543) (#41545)

fix: valuation rate for legacy serial nos (#41543)

fix: valuation rate for serial nos
(cherry picked from commit 214b38f7c8)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-20 15:51:42 +05:30
ruthra kumar
a853f6add8 Merge pull request #41547 from frappe/mergify/bp/version-15-hotfix/pr-41492
refactor: For advances booked in Separate account, reconciliation date can be configured (backport #41492)
2024-05-20 15:17:38 +05:30
ruthra kumar
6c455be6a7 test: reconciliation date for advance payments
(cherry picked from commit 30aa4e031d)
2024-05-20 09:30:14 +00:00
ruthra kumar
53e5fc16d5 refactor: enable no-copy on advance payment flags
(cherry picked from commit cafa2f52e5)
2024-05-20 09:30:14 +00:00
ruthra kumar
349caf895b chore: better description
(cherry picked from commit 000c1b49dc)
2024-05-20 09:30:14 +00:00
ruthra kumar
2b307ff526 refactor: advance payments, allow configurable reconciliation date
(cherry picked from commit 070e2d4d26)
2024-05-20 09:30:13 +00:00
mergify[bot]
f121b33e29 fix: valuation rate for legacy serial nos (backport #41543) (#41545)
fix: valuation rate for legacy serial nos (#41543)

fix: valuation rate for serial nos
(cherry picked from commit 214b38f7c8)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-20 13:57:40 +05:30
ruthra kumar
0d55a25e6c Merge pull request #41544 from ruthra-kumar/fix_filters_in_trends_reports
fix: Filters in trend reports
2024-05-20 11:10:24 +05:30
ruthra kumar
52d5d7a4d3 fix: Filters in trend reports 2024-05-20 10:36:42 +05:30
ruthra kumar
e5e1aadc9a Merge pull request #41526 from frappe/mergify/bp/version-15-hotfix/pr-41523
fix: minor Dr and Cr between Purchase Receipt and Purchase Invoice (backport #41523)
2024-05-20 09:17:25 +05:30
ruthra kumar
3872cdc54a fix: minor Dr and Cr between Purchase Receipt and Purchase Invoice 2024-05-20 08:31:12 +05:30
SelenSoft
c609436283 chore: Update turkish translations (#41286) 2024-05-19 15:30:17 +02:00
ruthra kumar
6052e37fc2 Merge pull request #41531 from frappe/mergify/bp/version-15-hotfix/pr-41529
refactor: ignore internal doctypes on Dunning cancellation (backport #41529)
2024-05-18 13:37:35 +05:30
mergify[bot]
7225347387 feat: enter serial range in Serial/Batch Selector (backport #41530) (#41534)
feat: enter serial range in Serial/Batch Selector (#41530)

* feat: util for generating serial nos from range string

* feat: enter serial range in Serial/Batch Selector

(cherry picked from commit 7b9fd394b0)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-05-18 10:39:21 +05:30
mergify[bot]
5fd68f9fcb fix: priority not working for multiple pricing rules (backport #41516) (#41525)
* fix: priority not working for multiple pricing rules (#41516)

(cherry picked from commit 5cf5b18aea)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-18 07:18:06 +05:30
ruthra kumar
97e6415afa refactor: ignore internal doctypes on Dunning cancellation
(cherry picked from commit 63c2cf13fd)
2024-05-17 15:31:36 +00:00
mergify[bot]
fcd9f89dee fix: timeout error while submitting purchase invoice (backport #41520) (#41522)
fix: timeout error while submitting purchase invoice (#41520)

(cherry picked from commit 61a4188440)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-17 16:56:11 +05:30
ruthra kumar
2bac4b1681 Merge pull request #41519 from frappe/mergify/bp/version-15-hotfix/pr-41517
fix: typerror on hide_fields (backport #41517)
2024-05-17 14:52:55 +05:30
ruthra kumar
8ae9da5484 fix: typerror on hide_fields
(cherry picked from commit deb9766f2a)
2024-05-17 09:20:33 +00:00
ruthra kumar
2f2615f9e2 Merge pull request #41513 from frappe/mergify/bp/version-15-hotfix/pr-41511
fix: possible sql error on General Ledger (backport #41511)
2024-05-17 11:11:59 +05:30
Frappe PR Bot
9b7bda958b chore(release): Bumped to Version 15.24.0
# [15.24.0](https://github.com/frappe/erpnext/compare/v15.23.3...v15.24.0) (2024-05-17)

### Features

* Config to enable immutable ledger ([68faf57](68faf575db))
2024-05-17 05:27:58 +00:00
Deepesh Garg
8c8b22bc61 Merge pull request #41509 from frappe/mergify/bp/version-15-hotfix/pr-41451
fix: Demo data clearing (#41451)
2024-05-17 10:57:01 +05:30
ruthra kumar
e0a0cb7b25 fix: possible sql error on General Ledger
(cherry picked from commit 76131f8e10)
2024-05-17 05:26:55 +00:00
Deepesh Garg
00144c92af Merge pull request #41508 from frappe/mergify/bp/version-15/pr-41438
feat: Config to enable immutable ledger
2024-05-17 10:56:45 +05:30
Deepesh Garg
7cbe03174f chore: resolve conflicts 2024-05-17 10:37:32 +05:30
Deepesh Garg
46ec61f0c9 fix: Demo data clearing
(cherry picked from commit d6fe220fab)
2024-05-17 03:47:50 +00:00
Deepesh Garg
e14d4e839f Merge pull request #41505 from frappe/mergify/bp/version-15-hotfix/pr-41504
fix: Unable to add items in POS Invoice (#41504)
2024-05-17 09:15:01 +05:30
Deepesh Garg
ce60b77fa5 chore: Resolve conflicts
(cherry picked from commit 9315607ee7)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
2024-05-17 03:42:44 +00:00
Deepesh Garg
f09a6d76a7 chore: Resolve conflicts
(cherry picked from commit 983c55eca1)
2024-05-17 03:42:43 +00:00
Deepesh Garg
68faf575db feat: Config to enable immutable ledger
(cherry picked from commit d56f52b0ba)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
#	erpnext/accounts/general_ledger.py
(cherry picked from commit 32c935bc30)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
2024-05-17 03:42:43 +00:00
Deepesh Garg
e1f8148129 Merge pull request #41438 from frappe/mergify/bp/version-15-hotfix/pr-41429
feat: Config to enable immutable ledger (#41429)
2024-05-17 09:11:24 +05:30
Deepesh Garg
414a91187f Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-41429 2024-05-16 21:02:55 +05:30
Deepesh Garg
9315607ee7 chore: Resolve conflicts 2024-05-16 20:59:47 +05:30
Deepesh Garg
983c55eca1 chore: Resolve conflicts 2024-05-16 20:27:50 +05:30
Deepesh Garg
a90186f9ae fix: Unable to add items in POS Invoice
(cherry picked from commit 7a3f8a5afb)
2024-05-16 14:02:49 +00:00
mergify[bot]
938888cddd fix: stock levels for batch (backport #41494) (#41501)
fix: stock levels for batch (#41494)

(cherry picked from commit 500c546691)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-16 16:33:02 +05:30
mergify[bot]
7620ae203e chore(BOM Explorer): display items in the same order as in the BOM (backport #41496) (#41498)
chore(BOM Explorer): display items in the same order as in the BOM (#41496)

(cherry picked from commit bd381cc0c6)

Co-authored-by: Samuel Danieli <23150094+scdanieli@users.noreply.github.com>
2024-05-16 15:59:06 +05:30
ruthra kumar
2e6c8632a1 Merge pull request #41499 from frappe/mergify/bp/version-15-hotfix/pr-40072
fix: print format bold for field "total" (backport #40072)
2024-05-16 15:32:17 +05:30
Nihantra C. Patel
e36880da2d fix: print format bold for field "total"
(cherry picked from commit 3c9640df27)
2024-05-16 09:50:48 +00:00
mergify[bot]
8101b51899 fix: bold total in exponential smoothing forecasting (backport #41393) (#41404)
fix: bold total in exponential smoothing forecasting (#41393)

* fix: bold total in exponential smoothing forecasting

* fix: bold total in exponential smoothing forecasting

(cherry picked from commit ba60b5911a)

Co-authored-by: Nihantra C. Patel <141945075+Nihantra-Patel@users.noreply.github.com>
2024-05-16 15:14:43 +05:30
Frappe PR Bot
c1f7d5a2d1 chore(release): Bumped to Version 15.23.3
## [15.23.3](https://github.com/frappe/erpnext/compare/v15.23.2...v15.23.3) (2024-05-15)

### Bug Fixes

* not able to submit landed cost voucher (backport [#41481](https://github.com/frappe/erpnext/issues/41481)) (backport [#41486](https://github.com/frappe/erpnext/issues/41486)) ([#41487](https://github.com/frappe/erpnext/issues/41487)) ([66684e7](66684e7e23))
2024-05-15 13:27:07 +00:00
mergify[bot]
66684e7e23 fix: not able to submit landed cost voucher (backport #41481) (backport #41486) (#41487)
fix: not able to submit landed cost voucher (backport #41481) (#41486)

fix: not able to submit landed cost voucher (#41481)

(cherry picked from commit 81a9521f04)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-15 18:55:40 +05:30
mergify[bot]
a070ad786d fix: not able to submit landed cost voucher (backport #41481) (#41486)
fix: not able to submit landed cost voucher (#41481)

(cherry picked from commit 81a9521f04)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-15 18:05:39 +05:30
mergify[bot]
a1ce514cf3 fix: validate reorder group warehouse (backport #41478) (#41480)
fix: validate reorder group warehouse (#41478)

(cherry picked from commit 0363afcfd0)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-15 15:15:24 +05:30
Frappe PR Bot
7b8b58f8ca chore(release): Bumped to Version 15.23.2
## [15.23.2](https://github.com/frappe/erpnext/compare/v15.23.1...v15.23.2) (2024-05-15)

### Bug Fixes

* 'Bill for Rejected Quantity in Purchase Invoice' feature not working (backport [#41437](https://github.com/frappe/erpnext/issues/41437)) ([#41445](https://github.com/frappe/erpnext/issues/41445)) ([b8db903](b8db903320))
* address filter and quotation to for prospect ([37741b5](37741b5b45))
* address filter and quotation to for prospect ([394b1f4](394b1f499d))
* address filter and quotation to for prospect ([cdbb515](cdbb515379))
* Asset cancelation issue ([e18be9b](e18be9b21e))
* consistent use of "Address & Contact" (backport [#41386](https://github.com/frappe/erpnext/issues/41386)) ([#41388](https://github.com/frappe/erpnext/issues/41388)) ([b6f82a6](b6f82a656f))
* daily prorata based depreciation bug in wdv method ([c335c2c](c335c2c85a))
* data getting override in delivery trip (backport [#41431](https://github.com/frappe/erpnext/issues/41431)) ([#41433](https://github.com/frappe/erpnext/issues/41433)) ([15d2881](15d2881bc8))
* Duplicate party name column in AR/AP report ([55edbec](55edbec6fa))
* incorrect  total days calculation ([01b25b5](01b25b5821))
* **minor:** removed extra parameter ([ce2c6c3](ce2c6c3165))
* pro rata based depreciation with opening accumulated depreciation ([72f3fb2](72f3fb2a2c))
* PSOA ageing ([6590d78](6590d78298))
* removed same named function ([955ce9b](955ce9b670))
* removed unrelated code modification ([0aca1e8](0aca1e8e05))
* resolved conflict ([520e1e9](520e1e9c8f))
* resolved conflict ([3a72f4b](3a72f4bd30))
* resolved conflict ([8cca74d](8cca74d5ef))
* Unknown column 'tabBatch.batch_no' in 'where clause' (backport [#41418](https://github.com/frappe/erpnext/issues/41418)) ([#41444](https://github.com/frappe/erpnext/issues/41444)) ([d988c7b](d988c7bd06))
* update description of Supplier Invoice Number ([a7533ff](a7533ff7f6))
* valuation issue for batch (backport [#41425](https://github.com/frappe/erpnext/issues/41425)) ([#41430](https://github.com/frappe/erpnext/issues/41430)) ([f55a131](f55a131dea))
* **wip:** daily depreciation bug ([1016ec2](1016ec2a14))
* **wip:** depreciation calculation after asset value adjustment ([3eff9c9](3eff9c9779))
* zero valuation rate for batched item (backport [#41446](https://github.com/frappe/erpnext/issues/41446)) ([#41447](https://github.com/frappe/erpnext/issues/41447)) ([5c3a096](5c3a0965bc))
2024-05-15 05:12:37 +00:00
Deepesh Garg
71da5d0928 Merge pull request #41459 from frappe/version-15-hotfix
chore: release v15
2024-05-15 10:41:19 +05:30
Nabin Hait
2569b244e2 Merge pull request #41473 from frappe/mergify/bp/version-15-hotfix/pr-41235
Depreciation based on daily prorata (backport #41235)
2024-05-15 09:10:56 +05:30
Nabin Hait
09aefa96ad Merge pull request #41474 from nabinhait/linter-fix5
style: linter issue
2024-05-15 09:10:08 +05:30
Nabin Hait
fd3efd53be style: linter issue 2024-05-15 09:09:16 +05:30
Nabin Hait
6d43d840db style: new line before function
(cherry picked from commit 7d86881579)
2024-05-15 03:11:37 +00:00
Khushi Rawat
955ce9b670 fix: removed same named function
(cherry picked from commit d22df324ec)
2024-05-15 03:11:37 +00:00
Khushi Rawat
b57919e2ce refactor: code optimization
(cherry picked from commit 7b264e5e11)
2024-05-15 03:11:37 +00:00
Khushi Rawat
72f3fb2a2c fix: pro rata based depreciation with opening accumulated depreciation
(cherry picked from commit c0c8c1bb02)
2024-05-15 03:11:37 +00:00
Khushi Rawat
12f383f252 test: made minor change in existing test
(cherry picked from commit d40b55468c)
2024-05-15 03:11:37 +00:00
Khushi Rawat
01b25b5821 fix: incorrect total days calculation
(cherry picked from commit fccd37d32d)
2024-05-15 03:11:36 +00:00
Khushi Rawat
c335c2c85a fix: daily prorata based depreciation bug in wdv method
(cherry picked from commit b8a98a273b)
2024-05-15 03:11:36 +00:00
Khushi Rawat
1016ec2a14 fix(wip): daily depreciation bug
(cherry picked from commit f337392f3e)
2024-05-15 03:11:36 +00:00
Nabin Hait
8da2841fdd Merge pull request #41471 from frappe/mergify/bp/version-15-hotfix/pr-41467
Asset cancelation issue (backport #41467)
2024-05-15 08:19:23 +05:30
Khushi Rawat
ccda17ede2 style: code optimization
(cherry picked from commit e843683ad1)
2024-05-14 17:12:46 +00:00
Khushi Rawat
e18be9b21e fix: Asset cancelation issue
(cherry picked from commit fa2b6c4490)
2024-05-14 17:12:45 +00:00
Deepesh Garg
53ea9ff102 Merge pull request #41259 from frappe/mergify/bp/version-15-hotfix/pr-41258
fix: PSOA ageing (#41258)
2024-05-14 20:08:45 +05:30
Nabin Hait
cb9df5e171 Merge pull request #41428 from frappe/mergify/bp/version-15-hotfix/pr-40468
fix: update description of Supplier Invoice Number (backport #40468)
2024-05-14 20:04:18 +05:30
Nabin Hait
041bcc96a9 Merge pull request #41449 from frappe/mergify/bp/version-15-hotfix/pr-41412
fix: Duplicate party name column in AR/AP report (backport #41412)
2024-05-14 20:03:22 +05:30
Nabin Hait
230cff583f Merge pull request #41461 from frappe/mergify/bp/version-15-hotfix/pr-41089
Refactor: Rename purchase receipt amount field to purchase amount (backport #41089)
2024-05-14 19:58:15 +05:30
Nabin Hait
b543093bde Merge pull request #41462 from frappe/mergify/bp/version-15-hotfix/pr-41420
Get prorata depreciation based on total days per year (backport #41420)
2024-05-14 19:45:44 +05:30
Nabin Hait
520e1e9c8f fix: resolved conflict 2024-05-14 19:37:34 +05:30
Nabin Hait
3a72f4bd30 fix: resolved conflict 2024-05-14 19:34:29 +05:30
Nabin Hait
8cca74d5ef fix: resolved conflict 2024-05-14 19:29:23 +05:30
Khushi Rawat
ce2c6c3165 fix(minor): removed extra parameter
(cherry picked from commit 98e7dfe97f)
2024-05-14 13:56:25 +00:00
Khushi Rawat
0b21026eef refactor: removed code duplicacies
(cherry picked from commit 6b24143f72)
2024-05-14 13:56:25 +00:00
Khushi Rawat
3eff9c9779 fix(wip): depreciation calculation after asset value adjustment
(cherry picked from commit d3200fb67f)
2024-05-14 13:56:24 +00:00
Khushi Rawat
0aca1e8e05 fix: removed unrelated code modification
(cherry picked from commit 360c3b36ed)
2024-05-14 12:47:53 +00:00
“Khushi
9b3f309598 refactor: renamed purchase receipt amount field to purchase amount
(cherry picked from commit 31841b4ab2)

# Conflicts:
#	erpnext/assets/doctype/asset/asset.json
#	erpnext/assets/doctype/asset/asset.py
#	erpnext/patches.txt
2024-05-14 12:47:53 +00:00
mergify[bot]
5c3a0965bc fix: zero valuation rate for batched item (backport #41446) (#41447)
fix: zero valuation rate for batched item (#41446)

(cherry picked from commit e3a80ebdf3)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-14 14:22:51 +05:30
Deepesh Garg
55edbec6fa fix: Duplicate party name column in AR/AP report
(cherry picked from commit 7501fe8ebd)
2024-05-14 02:53:48 +00:00
mergify[bot]
d988c7bd06 fix: Unknown column 'tabBatch.batch_no' in 'where clause' (backport #41418) (#41444)
fix: Unknown column 'tabBatch.batch_no' in 'where clause' (#41418)

fix: unknown column 'tabBatch.batch_no' in 'where clause'
(cherry picked from commit 6bd13d7452)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-14 05:21:17 +05:30
mergify[bot]
b8db903320 fix: 'Bill for Rejected Quantity in Purchase Invoice' feature not working (backport #41437) (#41445)
fix: 'Bill for Rejected Quantity in Purchase Invoice' feature not working (#41437)

(cherry picked from commit 3309359822)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-14 05:20:02 +05:30
Deepesh Garg
32c935bc30 feat: Config to enable immutable ledger
(cherry picked from commit d56f52b0ba)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
#	erpnext/accounts/general_ledger.py
2024-05-13 12:14:15 +00:00
Frappe PR Bot
1b2c2515bc chore(release): Bumped to Version 15.23.1
## [15.23.1](https://github.com/frappe/erpnext/compare/v15.23.0...v15.23.1) (2024-05-13)

### Bug Fixes

* valuation issue for batch (backport [#41425](https://github.com/frappe/erpnext/issues/41425)) (backport [#41430](https://github.com/frappe/erpnext/issues/41430)) ([#41434](https://github.com/frappe/erpnext/issues/41434)) ([aa2b644](aa2b64476e))
2024-05-13 11:24:52 +00:00
mergify[bot]
aa2b64476e fix: valuation issue for batch (backport #41425) (backport #41430) (#41434)
fix: valuation issue for batch (backport #41425) (#41430)

fix: valuation issue for batch (#41425)

(cherry picked from commit 065163146c)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-13 16:53:35 +05:30
mergify[bot]
15d2881bc8 fix: data getting override in delivery trip (backport #41431) (#41433)
fix: data getting override in delivery trip (#41431)

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

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-13 16:31:49 +05:30
mergify[bot]
f55a131dea fix: valuation issue for batch (backport #41425) (#41430)
fix: valuation issue for batch (#41425)

(cherry picked from commit 065163146c)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-13 16:24:59 +05:30
Deepesh Garg
4036ef8764 chore: better description
(cherry picked from commit eccd5b4c5d)
2024-05-13 09:43:36 +00:00
Nihantra Patel
a7533ff7f6 fix: update description of Supplier Invoice Number
(cherry picked from commit d721de13aa)
2024-05-13 09:43:36 +00:00
mergify[bot]
b6f82a656f fix: consistent use of "Address & Contact" (backport #41386) (#41388)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: consistent use of "Address & Contact" (#41386)
2024-05-10 17:42:05 +02:00
mergify[bot]
4190ffc654 chore: typo in Stock Settings (backport #41396) (#41405)
chore: typo in Stock Settings (#41396)

(cherry picked from commit 628d7e6458)

Co-authored-by: rehanrehman389 <32939507+rehanrehman389@users.noreply.github.com>
2024-05-10 15:45:04 +05:30
ruthra kumar
6b5b3afbca Merge pull request #41395 from frappe/mergify/bp/version-15-hotfix/pr-41040
fix: address filter and quotation to for prospect (backport #41040)
2024-05-09 12:48:30 +05:30
ruthra kumar
f337af9e90 refactor: make use of doc.quotation_to
(cherry picked from commit 754c7f6d1c)
2024-05-09 06:46:01 +00:00
Nihantra Patel
37741b5b45 fix: address filter and quotation to for prospect
(cherry picked from commit 2896e3666c)
2024-05-09 06:46:01 +00:00
Nihantra Patel
394b1f499d fix: address filter and quotation to for prospect
(cherry picked from commit 24a68a79df)
2024-05-09 06:46:00 +00:00
Nihantra Patel
cdbb515379 fix: address filter and quotation to for prospect
(cherry picked from commit fe5b88522e)
2024-05-09 06:46:00 +00:00
Frappe PR Bot
5f376009d0 chore(release): Bumped to Version 15.23.0
# [15.23.0](https://github.com/frappe/erpnext/compare/v15.22.2...v15.23.0) (2024-05-09)

### Bug Fixes

* Add PO reference ([c417b0c](c417b0c15a))
* correct ordered qty on SO when removing PO item - v15 ([#41342](https://github.com/frappe/erpnext/issues/41342)) ([5c1043f](5c1043fe88))
* Cost center not getting saved in PSOA ([fbbc0af](fbbc0af7bc))
* Do not deduct TCS for opening invoices ([1999b7a](1999b7a6c5))
* filter validation for batch-wise balance history report (backport [#41356](https://github.com/frappe/erpnext/issues/41356)) ([#41361](https://github.com/frappe/erpnext/issues/41361)) ([913cea0](913cea0018))
* future subscripition updates ([b27a55e](b27a55e802))
* GL Entries against orders as an advance ([e49a401](e49a401c23))
* incorrect qty picked in the pick list (backport [#41378](https://github.com/frappe/erpnext/issues/41378)) ([#41381](https://github.com/frappe/erpnext/issues/41381)) ([a293ec0](a293ec0db3))
* incorrect query for Purchase Invoice rate in GP ([20daae4](20daae4de9))
* **Item:** allow UOM conversion for non-stock items (backport [#41267](https://github.com/frappe/erpnext/issues/41267)) ([#41346](https://github.com/frappe/erpnext/issues/41346)) ([cd3ca1e](cd3ca1ee25))
* Merge debit and credit in transaction currency while merging gle with similar head ([9a58823](9a58823867))
* missing Item Name on Save for Quotation created from Item (backport [#41233](https://github.com/frappe/erpnext/issues/41233)) ([#41304](https://github.com/frappe/erpnext/issues/41304)) ([6491577](6491577501))
* Patch to fix the incorrect debit and credit in transaction currency ([f7e165b](f7e165b5ff))
* Patch to remove cancelled asset capitalization from asset ([a755540](a755540708))
* pick list with multiple batch issue (backport [#41335](https://github.com/frappe/erpnext/issues/41335)) ([#41338](https://github.com/frappe/erpnext/issues/41338)) ([1b1dfa8](1b1dfa8893))
* pricing rule rounding ([b93828c](b93828cd33))
* Purchase Invoice gain loss gl entry for periodic inventory ([0513481](0513481ec8))
* resolved conflict ([5039f45](5039f45be4))
* resolved conflict ([81afdcf](81afdcf745))
* search for item price in stock UOM (backport [#41075](https://github.com/frappe/erpnext/issues/41075)) ([#41313](https://github.com/frappe/erpnext/issues/41313)) ([112f96b](112f96bae0))
* update project URLs (backport [#41331](https://github.com/frappe/erpnext/issues/41331)) ([#41332](https://github.com/frappe/erpnext/issues/41332)) ([bb619a6](bb619a64fe))

### Features

* **Item Price:** make UOM mandatory (backport [#40588](https://github.com/frappe/erpnext/issues/40588)) ([#41312](https://github.com/frappe/erpnext/issues/41312)) ([cab0e30](cab0e30ceb))

### Performance Improvements

* index on item code for the Pick List Item doctype (backport [#41357](https://github.com/frappe/erpnext/issues/41357)) ([#41364](https://github.com/frappe/erpnext/issues/41364)) ([bba738f](bba738f5f4))
2024-05-09 05:31:55 +00:00
ruthra kumar
2ac0009b87 Merge pull request #41355 from frappe/version-15-hotfix
chore: release v15
2024-05-09 11:00:41 +05:30
rohitwaghchaure
307e394da4 Merge branch 'version-15' into version-15-hotfix 2024-05-09 07:30:20 +05:30
mergify[bot]
a293ec0db3 fix: incorrect qty picked in the pick list (backport #41378) (#41381)
fix: incorrect qty picked in the pick list (#41378)

(cherry picked from commit 5ed1b6b8fb)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-08 23:15:21 +05:30
Nabin Hait
d4aae4f311 Merge pull request #41380 from frappe/mergify/bp/version-15-hotfix/pr-41236
fix: Merge debit and credit in transaction currency while merging gle with similar head (backport #41236)
2024-05-08 19:25:17 +05:30
Nabin Hait
4dd58aba78 Merge branch 'version-15-hotfix' into mergify/bp/version-15-hotfix/pr-41236 2024-05-08 19:02:23 +05:30
Nabin Hait
0b20a5d82e Merge pull request #41383 from frappe/mergify/bp/version-15-hotfix/pr-40121
fix: Patch to remove cancelled asset capitalization from asset (backport #40121)
2024-05-08 19:01:02 +05:30
Nabin Hait
5039f45be4 fix: resolved conflict 2024-05-08 18:23:30 +05:30
Nabin Hait
a755540708 fix: Patch to remove cancelled asset capitalization from asset
(cherry picked from commit 1951f71eeb)
2024-05-08 12:42:57 +00:00
Nabin Hait
81afdcf745 fix: resolved conflict 2024-05-08 17:57:43 +05:30
Nabin Hait
f7e165b5ff fix: Patch to fix the incorrect debit and credit in transaction currency
(cherry picked from commit e0d12ba4d0)

# Conflicts:
#	erpnext/patches.txt
2024-05-08 12:23:49 +00:00
Nabin Hait
9a58823867 fix: Merge debit and credit in transaction currency while merging gle with similar head
(cherry picked from commit e43697d359)
2024-05-08 12:23:48 +00:00
mergify[bot]
bba738f5f4 perf: index on item code for the Pick List Item doctype (backport #41357) (#41364)
* perf: index on item code for the Pick List Item doctype (#41357)

(cherry picked from commit 0887161f2a)

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

* chore: fix conflicts

---------

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-08 11:37:51 +05:30
Nihantra C. Patel
8fb3294674 fix: not allow template item in product bundle item 2024-05-08 10:40:24 +05:30
Nihantra C. Patel
b64f5a4e54 fix: not allow template item in product bundle item 2024-05-08 10:38:58 +05:30
Nihantra C. Patel
9864377b47 fix: not allow template item in product bundle item - v15/v14 2024-05-08 10:32:28 +05:30
mergify[bot]
913cea0018 fix: filter validation for batch-wise balance history report (backport #41356) (#41361)
fix: filter validation for batch-wise balance history report (#41356)

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

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

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

(cherry picked from commit 9bf37426c1)
2024-05-07 04:32:12 +00:00
mergify[bot]
cd3ca1ee25 fix(Item): allow UOM conversion for non-stock items (backport #41267) (#41346)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix(Item): allow UOM conversion for non-stock items (#41267)
2024-05-06 20:51:11 +02:00
mergify[bot]
6491577501 fix: missing Item Name on Save for Quotation created from Item (backport #41233) (#41304)
fix: missing Item Name on Save for Quotation created from Item (#41233)

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

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

(cherry picked from commit c8e92cb1b2)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2024-05-06 21:45:27 +05:30
Nihantra C. Patel
5c1043fe88 fix: correct ordered qty on SO when removing PO item - v15 (#41342) 2024-05-06 21:36:27 +05:30
Frappe PR Bot
78637823c8 chore(release): Bumped to Version 15.22.2
## [15.22.2](https://github.com/frappe/erpnext/compare/v15.22.1...v15.22.2) (2024-05-06)

### Bug Fixes

* pick list with multiple batch issue (backport [#41335](https://github.com/frappe/erpnext/issues/41335)) (backport [#41338](https://github.com/frappe/erpnext/issues/41338)) ([#41340](https://github.com/frappe/erpnext/issues/41340)) ([ee12ec3](ee12ec36cc))
2024-05-06 08:41:26 +00:00
mergify[bot]
ee12ec36cc fix: pick list with multiple batch issue (backport #41335) (backport #41338) (#41340)
fix: pick list with multiple batch issue (backport #41335) (#41338)

fix: pick list with multiple batch issue (#41335)

fix: pick list with batchb issue
(cherry picked from commit ebfbe94aaf)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-06 14:10:08 +05:30
mergify[bot]
1b1dfa8893 fix: pick list with multiple batch issue (backport #41335) (#41338)
fix: pick list with multiple batch issue (#41335)

fix: pick list with batchb issue
(cherry picked from commit ebfbe94aaf)

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-06 13:36:52 +05:30
ruthra kumar
a482ee1fe4 Merge pull request #41337 from frappe/mergify/bp/version-15-hotfix/pr-41334
fix: incorrect query for Purchase Invoice rate in GP (backport #41334)
2024-05-06 13:13:37 +05:30
ruthra kumar
20daae4de9 fix: incorrect query for Purchase Invoice rate in GP
(cherry picked from commit bd8382c592)
2024-05-06 07:24:48 +00:00
mergify[bot]
bb619a64fe fix: update project URLs (backport #41331) (#41332)
fix: update project URLs (#41331)

(cherry picked from commit 6142d07f1a)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-05-06 11:42:25 +05:30
Deepesh Garg
67954a93b2 Merge pull request #41325 from frappe/mergify/bp/version-15-hotfix/pr-41318
fix: Cost center not getting saved in PSOA (#41318)
2024-05-06 11:29:01 +05:30
Deepesh Garg
0b44cebe00 chore: resolve conflicts 2024-05-06 11:12:11 +05:30
Deepesh Garg
21ab8fe89c Merge pull request #41323 from frappe/mergify/bp/version-15-hotfix/pr-41314
fix: Do not deduct TCS for opening invoices (#41314)
2024-05-05 23:19:44 +05:30
Deepesh Garg
fbbc0af7bc fix: Cost center not getting saved in PSOA
(cherry picked from commit 58f7039630)

# Conflicts:
#	erpnext/accounts/doctype/psoa_cost_center/psoa_cost_center.json
2024-05-04 08:27:08 +00:00
Deepesh Garg
1999b7a6c5 fix: Do not deduct TCS for opening invoices
(cherry picked from commit eb9f579b8f)
2024-05-04 08:26:06 +00:00
Frappe PR Bot
fa5462d674 chore(release): Bumped to Version 15.22.1
## [15.22.1](https://github.com/frappe/erpnext/compare/v15.22.0...v15.22.1) (2024-05-03)

### Bug Fixes

* Add PO reference ([44330a6](44330a618b))
* GL Entries against orders as an advance ([4d312cb](4d312cbc65))
2024-05-03 17:32:36 +00:00
Deepesh Garg
b3736d6c6c Merge pull request #41321 from frappe/mergify/bp/version-15-hotfix/pr-41279
fix: GL Entries against orders as an advance (#41279)
2024-05-03 23:01:38 +05:30
Deepesh Garg
031ecb5cb0 Merge pull request #41320 from frappe/mergify/bp/version-15/pr-41279
fix: GL Entries against orders as an advance (#41279)
2024-05-03 23:01:18 +05:30
Deepesh Garg
2faeefb063 test: Add bank account
(cherry picked from commit eac7be2d0f)
2024-05-03 14:12:29 +00:00
Deepesh Garg
d384860c34 test: Update failing tests
(cherry picked from commit 42ef95759d)
2024-05-03 14:12:29 +00:00
Deepesh Garg
c417b0c15a fix: Add PO reference
(cherry picked from commit eb31017058)
2024-05-03 14:12:29 +00:00
Deepesh Garg
e49a401c23 fix: GL Entries against orders as an advance
(cherry picked from commit 8289f3c724)
2024-05-03 14:12:29 +00:00
Deepesh Garg
27f51f1234 test: Add bank account
(cherry picked from commit eac7be2d0f)
2024-05-03 14:12:15 +00:00
Deepesh Garg
ad0f563816 test: Update failing tests
(cherry picked from commit 42ef95759d)
2024-05-03 14:12:14 +00:00
Deepesh Garg
44330a618b fix: Add PO reference
(cherry picked from commit eb31017058)
2024-05-03 14:12:14 +00:00
Deepesh Garg
4d312cbc65 fix: GL Entries against orders as an advance
(cherry picked from commit 8289f3c724)
2024-05-03 14:12:14 +00:00
Deepesh Garg
6bac561789 Merge pull request #41315 from frappe/mergify/bp/version-15-hotfix/pr-41311
fix: future subscription updates (#41311)
2024-05-03 15:57:16 +05:30
Deepesh Garg
31254009cc test: Add posting dates
(cherry picked from commit 7fa22069d8)
2024-05-03 06:35:27 +00:00
Deepesh Garg
b27a55e802 fix: future subscripition updates
(cherry picked from commit 8e30debc10)
2024-05-03 06:35:27 +00:00
mergify[bot]
cab0e30ceb feat(Item Price): make UOM mandatory (backport #40588) (#41312)
* feat(Item Price): make UOM mandatory (#40588)

(cherry picked from commit a61148c464)

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

* chore: `conflicts`

---------

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-05-03 11:17:12 +05:30
mergify[bot]
112f96bae0 fix: search for item price in stock UOM (backport #41075) (#41313)
fix: search for item price in stock UOM (#41075)

(cherry picked from commit e4db0562ac)

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
2024-05-03 10:28:08 +05:30
Deepesh Garg
66b85c96f4 Merge pull request #41310 from frappe/mergify/bp/version-15-hotfix/pr-41260
fix: Purchase Invoice gain loss gl entry for periodic inventory (#41260)
2024-05-03 09:28:18 +05:30
Deepesh Garg
0513481ec8 fix: Purchase Invoice gain loss gl entry for periodic inventory
(cherry picked from commit 2402447568)
2024-05-03 03:25:54 +00:00
Frappe PR Bot
f62762b4d1 chore(release): Bumped to Version 15.22.0
# [15.22.0](https://github.com/frappe/erpnext/compare/v15.21.2...v15.22.0) (2024-05-02)

### Bug Fixes

* added brand column in Warehouse wise Item Balance Age and Value … (backport [#41280](https://github.com/frappe/erpnext/issues/41280)) ([#41282](https://github.com/frappe/erpnext/issues/41282)) ([4bbf0a4](4bbf0a46b5))
* advance account validation in company master ([dd67b0e](dd67b0ee61))
* args when get the delivery note in delivery trip ([61d6838](61d6838b2c))
* args when get the delivery note in delivery trip ([e9acacd](e9acacdd5d))
* basic rate for SABB ([7b79873](7b7987363f))
* compute tree-view parent field name ([#41234](https://github.com/frappe/erpnext/issues/41234)) ([c3077ee](c3077ee067))
* display term name for single term invoices ([a7d1a88](a7d1a88519))
* duplicate column in the stock ledger report ([a62298a](a62298a635))
* enable advance in separate acc only for customer and Supplier ([c3073d6](c3073d6e74))
* expense causing p&l test case to fail ([acfee42](acfee42735))
* handle and receivable accounts based on response type ([f65b28a](f65b28a189))
* handle stock balance unbuffered_cursor error (backport [#41186](https://github.com/frappe/erpnext/issues/41186)) ([#41188](https://github.com/frappe/erpnext/issues/41188)) ([b34582e](b34582e6ba))
* Ignore user perm in Bank Reco Tool for company ([737c480](737c4809e3))
* incorrectly applying TDS when Advance is in previous FY ([08f888a](08f888a326))
* Invoice with no GLEs in deferred report ([44c3ad6](44c3ad6810))
* missing def expense if no exp in first month ([0a65a37](0a65a37eed))
* mode of payment has precedance ([c6145a1](c6145a1101))
* multiple pricing rules with discount amount and discount percentage not working (backport [#41211](https://github.com/frappe/erpnext/issues/41211)) (backport [#41241](https://github.com/frappe/erpnext/issues/41241)) ([#41275](https://github.com/frappe/erpnext/issues/41275)) ([de77894](de77894e59))
* paid amount in bank reconciliation tool ([759c7f5](759c7f5490))
* party and party type label on accounting preview ([ee9822f](ee9822fd42))
* permission issue when user permission restricts on company ([8d70a0e](8d70a0e0bc))
* rendering the email template when user HTML ([3068dad](3068dad410))
* test case for zero deferred expense ([23c3c3c](23c3c3cc0c))
* validation to prevent foreign currency advance accounts in PE ([fb4a75c](fb4a75c5aa))
* validation to prevent overallocation ([ea596eb](ea596eb4a2))
* warehouse type filter for stock reports ([48351d6](48351d6da8))

### Features

* allow to do reposting for all transactions (audit) ([4555f8a](4555f8a9a6))
2024-05-02 04:23:27 +00:00
ruthra kumar
27e0ed30fe Merge pull request #41263 from frappe/version-15-hotfix
chore: release v15
2024-05-02 09:52:07 +05:30
mergify[bot]
4bbf0a46b5 fix: added brand column in Warehouse wise Item Balance Age and Value … (backport #41280) (#41282)
fix: added brand column in Warehouse wise Item Balance Age and Value … (#41280)

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

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
2024-05-01 16:03:37 +05:30
mergify[bot]
de77894e59 fix: multiple pricing rules with discount amount and discount percentage not working (backport #41211) (backport #41241) (#41275)
fix: multiple pricing rules with discount amount and discount percentage not working (backport #41211) (#41241)

fix: multiple pricing rules with discount amount and discount percentage not working (#41211)

(cherry picked from commit 54313b5db9)

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

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2024-05-01 15:46:52 +05:30
ruthra kumar
5a9615a1f2 Merge pull request #41270 from frappe/mergify/bp/version-15-hotfix/pr-41268
fix: validation to prevent overallocation (backport #41268)
2024-04-30 18:40:22 +05:30
Fritz
c3077ee067 fix: compute tree-view parent field name (#41234)
fix: Fixing treeView lookup incompatibility, see : See https://github.com/frappe/frappe/pull/26199
2024-04-30 17:57:58 +05:30
ruthra kumar
ea596eb4a2 fix: validation to prevent overallocation
(cherry picked from commit bf755fab55)
2024-04-30 12:08:48 +00:00
Deepesh Garg
6590d78298 fix: PSOA ageing
(cherry picked from commit fed2d11905)
2024-04-30 07:41:09 +00:00
Deepesh Garg
378605cd00 Merge pull request #41253 from frappe/mergify/bp/version-15-hotfix/pr-41171
fix: Invoice with no GLEs in deferred report (#41171)
2024-04-30 13:10:53 +05:30
ruthra kumar
56e455c745 Merge pull request #41255 from frappe/mergify/bp/version-15-hotfix/pr-41252
fix: permission issue when user permission restricts on company (backport #41252)
2024-04-30 12:40:02 +05:30
ruthra kumar
8d70a0e0bc fix: permission issue when user permission restricts on company 2024-04-30 12:20:10 +05:30
Deepesh Garg
b67e9e4aa8 chore: remove debug flag
(cherry picked from commit ecf07bd128)
2024-04-30 05:46:18 +00:00
Deepesh Garg
44c3ad6810 fix: Invoice with no GLEs in deferred report
(cherry picked from commit 1c613ada6f)
2024-04-30 05:46:17 +00:00
Deepesh Garg
69c05e5843 Merge pull request #41251 from frappe/mergify/bp/version-15-hotfix/pr-41173
fix: paid amount in bank reconciliation tool (#41173)
2024-04-30 11:15:39 +05:30
Deepesh Garg
6ab91a5c88 Merge pull request #41250 from frappe/mergify/bp/version-15-hotfix/pr-41219
fix: Ignore user perm in Bank Reco Tool for company (#41219)
2024-04-30 11:15:19 +05:30
Deepesh Garg
759c7f5490 fix: paid amount in bank reconciliation tool
(cherry picked from commit a48966f08c)
2024-04-30 04:55:51 +00:00
Deepesh Garg
03b4a85825 chore: resolve conflicts 2024-04-30 10:25:51 +05:30
Deepesh Garg
737c4809e3 fix: Ignore user perm in Bank Reco Tool for company
(cherry picked from commit 9f346e7ba0)

# Conflicts:
#	erpnext/accounts/doctype/bank_reconciliation_tool/bank_reconciliation_tool.json
2024-04-30 04:53:24 +00:00
Deepesh Garg
3657badb31 Merge pull request #41239 from frappe/mergify/bp/version-15-hotfix/pr-41237
fix: party and party type label on accounting preview (#41237)
2024-04-30 10:23:17 +05:30
ruthra kumar
ef69a46e6a Merge pull request #41249 from frappe/mergify/bp/version-15-hotfix/pr-41240
fix: display term name for single term invoices in AR/AP (backport #41240)
2024-04-30 07:42:41 +05:30
ruthra kumar
78106836be Merge pull request #41247 from frappe/mergify/bp/version-15-hotfix/pr-41194
fix: TDS incorrectly applied when Advance is in previous FY (backport #41194)
2024-04-30 07:18:04 +05:30
ruthra kumar
a7d1a88519 fix: display term name for single term invoices
(cherry picked from commit 5fa4cfee04)
2024-04-30 01:40:17 +00:00
ruthra kumar
15ac3d8b0b test: TDS deduction across fiscal year
(cherry picked from commit 2f9a144023)
2024-04-30 01:27:55 +00:00
ruthra kumar
08f888a326 fix: incorrectly applying TDS when Advance is in previous FY
(cherry picked from commit b195f519e2)
2024-04-30 01:27:54 +00:00
Nikhil Kothari
ee9822fd42 fix: party and party type label on accounting preview
(cherry picked from commit f7f3b22786)
2024-04-29 13:24:48 +00:00
Deepesh Garg
17eb2f02f4 Merge pull request #41226 from frappe/mergify/bp/version-15-hotfix/pr-40865
fix: missing def expense if no exp in first month (#40865)
2024-04-29 17:25:15 +05:30
Ankush Menat
067419b7cd chore: delete invalid translations (#41227) 2024-04-29 10:31:22 +05:30
Dany Robert
acfee42735 fix: expense causing p&l test case to fail
(cherry picked from commit 01888c98bc)
2024-04-29 04:55:32 +00:00
Dany Robert
62966ac550 chore: semgrep
(cherry picked from commit 581af4eced)
2024-04-29 04:55:32 +00:00
Dany Robert
23c3c3cc0c fix: test case for zero deferred expense
(cherry picked from commit 7ef4dbcaf6)
2024-04-29 04:55:32 +00:00
Dany Robert
0a65a37eed fix: missing def expense if no exp in first month
(cherry picked from commit 5c9ce575f6)
2024-04-29 04:55:31 +00:00
ruthra kumar
0df1005cb2 Merge pull request #41209 from frappe/mergify/bp/version-15-hotfix/pr-41208
fix: set receivable account based on response type (backport #41208)
2024-04-26 20:30:55 +05:30
rohitwaghchaure
807b2d5c0a Merge pull request #41206 from frappe/mergify/bp/version-15-hotfix/pr-41165
feat: allow to do reposting for all stock transactions (audit) (backport #41165)
2024-04-26 14:25:40 +05:30
ruthra kumar
f65b28a189 fix: handle and receivable accounts based on response type
(cherry picked from commit 066859cca0)
2024-04-26 08:43:23 +00:00
rohitwaghchaure
a292e52b34 chore: fix conflicts 2024-04-26 13:47:03 +05:30
Rohit Waghchaure
4555f8a9a6 feat: allow to do reposting for all transactions (audit)
(cherry picked from commit aefbe21b46)

# Conflicts:
#	erpnext/stock/doctype/stock_reposting_settings/stock_reposting_settings.json
2024-04-26 08:15:11 +00:00
rohitwaghchaure
0fea5564b6 Merge pull request #41201 from frappe/mergify/bp/version-15-hotfix/pr-41185
fix: args when get the delivery note in delivery trip (backport #41185)
2024-04-26 13:34:44 +05:30
rohitwaghchaure
476b7f43a2 Merge pull request #41202 from frappe/mergify/bp/version-15-hotfix/pr-41182
fix: rendering the email template when user HTML (backport #41182)
2024-04-26 13:34:27 +05:30
rohitwaghchaure
d5d846f481 Merge pull request #41203 from frappe/mergify/bp/version-15-hotfix/pr-41167
fix: warehouse type filter for stock reports (backport #41167)
2024-04-26 13:34:00 +05:30
rohitwaghchaure
6fd356b654 chore: fix conflicts 2024-04-26 13:13:55 +05:30
Rohit Waghchaure
48351d6da8 fix: warehouse type filter for stock reports
(cherry picked from commit 4250ac821f)
2024-04-26 07:41:48 +00:00
Nihantra C. Patel
3068dad410 fix: rendering the email template when user HTML
(cherry picked from commit 7cb66f7fd3)
2024-04-26 07:41:37 +00:00
Nihantra Patel
61d6838b2c fix: args when get the delivery note in delivery trip
(cherry picked from commit ca577f7aaa)
2024-04-26 07:40:36 +00:00
Nihantra Patel
e9acacdd5d fix: args when get the delivery note in delivery trip
(cherry picked from commit 2f359e201d)

# Conflicts:
#	erpnext/stock/doctype/delivery_note/delivery_note.py
2024-04-26 07:40:36 +00:00
rohitwaghchaure
3bb26fde2b Merge pull request #41199 from frappe/mergify/bp/version-15-hotfix/pr-41195
fix: basic rate for SABB (backport #41195)
2024-04-26 12:54:46 +05:30
Rohit Waghchaure
7b7987363f fix: basic rate for SABB
(cherry picked from commit 7fa94843aa)
2024-04-26 07:21:46 +00:00
rohitwaghchaure
3193ef0a89 Merge pull request #41197 from frappe/mergify/bp/version-15-hotfix/pr-41192
fix: duplicate column in the stock ledger report (backport #41192)
2024-04-26 12:49:25 +05:30
Rohit Waghchaure
a62298a635 fix: duplicate column in the stock ledger report
(cherry picked from commit be7fd6bfb4)
2024-04-26 06:53:14 +00:00
Frappe PR Bot
6a7b6f6262 chore(release): Bumped to Version 15.21.2
## [15.21.2](https://github.com/frappe/erpnext/compare/v15.21.1...v15.21.2) (2024-04-26)

### Bug Fixes

* enable advance in separate acc only for customer and Supplier ([6da927a](6da927a573))
2024-04-26 02:10:51 +00:00
ruthra kumar
5b389bf5ca Merge pull request #41191 from frappe/mergify/bp/version-15/pr-41183
fix: restrict Advance in separate party to customer and supplier (backport #41183)
2024-04-26 07:39:32 +05:30
ruthra kumar
6da927a573 fix: enable advance in separate acc only for customer and Supplier
(cherry picked from commit 3c1af2acf0)
2024-04-26 01:50:34 +00:00
ruthra kumar
e6c7832485 Merge pull request #41189 from frappe/mergify/bp/version-15-hotfix/pr-41183
fix: restrict Advance in separate party to customer and supplier (backport #41183)
2024-04-25 20:35:50 +05:30
ruthra kumar
c3073d6e74 fix: enable advance in separate acc only for customer and Supplier
(cherry picked from commit 3c1af2acf0)
2024-04-25 14:30:58 +00:00
mergify[bot]
b34582e6ba fix: handle stock balance unbuffered_cursor error (backport #41186) (#41188)
fix: handle stock balance unbuffered_cursor error (#41186)

(cherry picked from commit 341fb6d8f3)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2024-04-25 17:26:26 +05:30
ruthra kumar
5136ffd10d Merge pull request #41139 from frappe/mergify/bp/version-15-hotfix/pr-41086
fix: prevent foreign currency  accounts as advance accounts. (backport #41086)
2024-04-25 09:37:49 +05:30
Frappe PR Bot
cacb5bfe03 chore(release): Bumped to Version 15.21.1
## [15.21.1](https://github.com/frappe/erpnext/compare/v15.21.0...v15.21.1) (2024-04-25)

### Bug Fixes

* mode of payment has precedance ([0dfd6fa](0dfd6facc1))
2024-04-25 03:38:33 +00:00
ruthra kumar
88fcb8aebb Merge pull request #41180 from frappe/mergify/bp/version-15/pr-41142
fix: mode of payment has precedance in Payment Entry (backport #41142)
2024-04-25 09:07:05 +05:30
ruthra kumar
0dfd6facc1 fix: mode of payment has precedance
Mode of Payment is given precedence over company/party bank account

(cherry picked from commit 4aef969879)
2024-04-25 03:34:30 +00:00
ruthra kumar
5988941032 Merge pull request #41177 from frappe/mergify/bp/version-15-hotfix/pr-41142
fix: mode of payment has precedance in Payment Entry (backport #41142)
2024-04-25 08:55:20 +05:30
ruthra kumar
c6145a1101 fix: mode of payment has precedance
Mode of Payment is given precedence over company/party bank account

(cherry picked from commit 4aef969879)
2024-04-25 03:13:13 +00:00
Frappe PR Bot
2fb035fe1b chore(release): Bumped to Version 15.21.0
# [15.21.0](https://github.com/frappe/erpnext/compare/v15.20.6...v15.21.0) (2024-04-24)

### Bug Fixes

* account and stock manager read perm ([572e844](572e844a91))
* allow Employee role to select cost center & project (accounting dimensions) (backport [#41160](https://github.com/frappe/erpnext/issues/41160)) ([#41162](https://github.com/frappe/erpnext/issues/41162)) ([90d6e55](90d6e550aa))
* Allow updating cost center and project for repostable doctypes ([e278688](e278688a4b))
* balance qty for stock ledger report ([74ed656](74ed656bb9))
* do not add actual expense twice for validating budget ([c72478c](c72478c74d))
* do not add qty to supplied items (backport [#41061](https://github.com/frappe/erpnext/issues/41061)) ([#41066](https://github.com/frappe/erpnext/issues/41066)) ([1ae447e](1ae447e4fc))
* don't attempt to set gender from salutation (backport [#40997](https://github.com/frappe/erpnext/issues/40997)) ([#41073](https://github.com/frappe/erpnext/issues/41073)) ([ee7aaf0](ee7aaf0ea4))
* duplicate serial and batch bundle in stock entry and stock reco ([c10c211](c10c21157d))
* incorrect stock posting for current qty ([05d5c48](05d5c48d29))
* Missing args while fetching items from delivery note ([3b4575a](3b4575af3d))
* not able to update default supplier from Supplier Quotation Comparison report ([80891da](80891daaed))
* Party type in Payment Order ([83931e8](83931e872b))
* Payment entry against employee ([060d46a](060d46af42))
* Permission for lower dedcution certificate ([d7ddb00](d7ddb00e86))
* search not working for so in the Production Plan ([#36459](https://github.com/frappe/erpnext/issues/36459)) ([544e56a](544e56a71c))
* stock reco negative qty validation ([aee03fe](aee03fe2ef))
* validate uom is integer for PR item (backport [#41074](https://github.com/frappe/erpnext/issues/41074)) ([#41077](https://github.com/frappe/erpnext/issues/41077)) ([93242ca](93242ca883))
* validation for fraction number in Work Order ([ef2553e](ef2553edf9))
* validation for zero qty in SABB ([85796b3](85796b3534))

### Features

* Available batches report as on specific date ([791e426](791e4269d2))
* show expense breakup ([e047e1e](e047e1eb15))
2024-04-24 10:48:02 +00:00
Deepesh Garg
f3be4cd2b3 Merge pull request #41150 from frappe/version-15-hotfix
chore: release v15
2024-04-24 16:16:41 +05:30
Deepesh Garg
15bb41d3c2 Merge pull request #41164 from frappe/mergify/bp/version-15-hotfix/pr-41106
chore: Remove heatmap from party dashboards (#41106)
2024-04-24 13:00:50 +05:30
Deepesh Garg
410990b2a3 chore: Remove heatmap from party dashboards
(cherry picked from commit a8f03e8baa)
2024-04-24 06:32:03 +00:00
Deepesh Garg
51a2b74db9 Merge pull request #41101 from frappe/mergify/bp/version-15-hotfix/pr-41085
fix: Permission for lower deduction certificate (#41085)
2024-04-24 12:00:50 +05:30
Deepesh Garg
bfc34939f2 Merge pull request #41048 from frappe/mergify/bp/version-15-hotfix/pr-40962
fix: Allow updating cost center and project for repostable doctypes (#40962)
2024-04-24 12:00:28 +05:30
mergify[bot]
90d6e550aa fix: allow Employee role to select cost center & project (accounting dimensions) (backport #41160) (#41162)
* fix: allow Employee role to select cost center & project (accounting dimensions)

(cherry picked from commit d0d496a515)

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

* chore: fix conflicts

---------

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2024-04-24 11:43:46 +05:30
Deepesh Garg
4f5af0ff9f chore: Resolve conflicts 2024-04-24 11:32:26 +05:30
rohitwaghchaure
ab21b518e1 Merge pull request #41156 from frappe/mergify/bp/version-15-hotfix/pr-41135
feat: Available batches as on specific date report (backport #41135)
2024-04-24 11:14:16 +05:30
Nabin Hait
d4e2adbdb2 Merge pull request #41141 from frappe/mergify/bp/version-15-hotfix/pr-41136
fix: Missing args while fetching items from delivery note in Installation Note (backport #41136)
2024-04-24 10:58:34 +05:30
ruthra kumar
85e0e8110a Merge pull request #41149 from frappe/mergify/bp/version-15-hotfix/pr-41147
refactor: better description and pop up on Advance accounts (backport #41147)
2024-04-24 07:19:19 +05:30
Rohit Waghchaure
791e4269d2 feat: Available batches report as on specific date
(cherry picked from commit b8f7979794)
2024-04-23 16:48:56 +00:00
rohitwaghchaure
3df5aa04b5 Merge pull request #41153 from frappe/mergify/bp/version-15-hotfix/pr-41145
fix: incorrect stock posting for current qty (backport #41145)
2024-04-23 17:12:03 +05:30
Rohit Waghchaure
05d5c48d29 fix: incorrect stock posting for current qty
(cherry picked from commit d4fe313de2)
2024-04-23 11:21:47 +00:00
ruthra kumar
2b736b52d6 chore: resolve conflicts 2024-04-23 15:35:02 +05:30
ruthra kumar
24954b909b refactor: popup to inform on limited support for Advance accounts
(cherry picked from commit 9dbd321133)
2024-04-23 09:17:00 +00:00
ruthra kumar
ed5affe25a refactor: better description for advance account
(cherry picked from commit de9c8fc9d6)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.json
#	erpnext/setup/doctype/company/company.json
2024-04-23 09:17:00 +00:00
rohitwaghchaure
8591a151de Merge pull request #41143 from frappe/mergify/bp/version-15-hotfix/pr-41098
fix: stock reconciliation negative qty validation (backport #41098)
2024-04-23 13:43:08 +05:30
rohitwaghchaure
b2a0e4b810 chore: fix conflicts 2024-04-23 13:17:23 +05:30
Rohit Waghchaure
aee03fe2ef fix: stock reco negative qty validation
(cherry picked from commit 289495c308)

# Conflicts:
#	erpnext/stock/stock_ledger.py
2024-04-23 07:44:47 +00:00
Deepesh Garg
62702b8bd6 Merge pull request #41134 from frappe/mergify/bp/version-15-hotfix/pr-41104
fix: Payment entry against employee (#41104)
2024-04-23 12:04:13 +05:30
Deepesh Garg
cfb36cc9a8 Merge pull request #41131 from frappe/mergify/bp/version-15-hotfix/pr-40797
fix: Party type in Payment Order (#40797)
2024-04-23 12:03:47 +05:30
Nabin Hait
3b4575af3d fix: Missing args while fetching items from delivery note
(cherry picked from commit bbe323fbb4)
2024-04-23 04:55:06 +00:00
ruthra kumar
dd67b0ee61 fix: advance account validation in company master
(cherry picked from commit 1ad065fc54)
2024-04-23 01:45:45 +00:00
ruthra kumar
fb4a75c5aa fix: validation to prevent foreign currency advance accounts in PE
(cherry picked from commit e3fc5990ee)
2024-04-23 01:45:45 +00:00
Deepesh Garg
060d46af42 fix: Payment entry against employee
(cherry picked from commit 93e6c6ccab)
2024-04-22 06:08:47 +00:00
Deepesh Garg
83931e872b fix: Party type in Payment Order
(cherry picked from commit 91fa41c9ec)
2024-04-22 06:05:12 +00:00
Gursheen Kaur Anand
a8866b61a1 Merge pull request #41124 from frappe/mergify/bp/version-15-hotfix/pr-40769
fix: budget validation for purchase orders (backport #40769)
2024-04-21 18:57:15 +05:30
rohitwaghchaure
f733eddf0b Merge pull request #41122 from frappe/mergify/bp/version-15-hotfix/pr-41120
fix: search not working for so in the Production Plan (backport #36459) (backport #41120)
2024-04-21 17:24:42 +05:30
Gursheen Anand
ba99bc5fff refactor: show list for expense breakup
(cherry picked from commit 9a12376e29)
2024-04-21 11:26:31 +00:00
Gursheen Anand
e047e1eb15 feat: show expense breakup
(cherry picked from commit 59292a09c4)
2024-04-21 11:26:31 +00:00
Gursheen Anand
c72478c74d fix: do not add actual expense twice for validating budget
(cherry picked from commit af26ac96e9)
2024-04-21 11:26:30 +00:00
rohitwaghchaure
544e56a71c fix: search not working for so in the Production Plan (#36459)
fix: search not working for so
(cherry picked from commit 8c57d56240)
(cherry picked from commit 9a6e762b8b)
2024-04-21 11:21:04 +00:00
rohitwaghchaure
bb5096075f Merge pull request #41114 from frappe/mergify/bp/version-15-hotfix/pr-41099
fix: not able to update default supplier from Supplier Quotation Comparison report (backport #41099)
2024-04-20 19:47:01 +05:30
Rohit Waghchaure
80891daaed fix: not able to update default supplier from Supplier Quotation Comparison report
(cherry picked from commit ad8e189c26)
2024-04-20 05:51:36 +00:00
rohitwaghchaure
77a764e5bd Merge pull request #41107 from frappe/mergify/bp/version-15-hotfix/pr-41102
fix: balance qty for stock ledger report (backport #41102)
2024-04-20 11:16:06 +05:30
Rohit Waghchaure
74ed656bb9 fix: balance qty for stock ledger report
(cherry picked from commit f00ae0b92b)
2024-04-19 16:22:16 +00:00
rohitwaghchaure
82ce228433 Merge pull request #41097 from frappe/mergify/bp/version-15-hotfix/pr-41067
fix: validation for zero qty in SABB (backport #41067)
2024-04-19 21:49:55 +05:30
Deepesh Garg
d7ddb00e86 fix: Permission for lower dedcution certificate
(cherry picked from commit f6f118855b)

# Conflicts:
#	erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.json
2024-04-19 10:11:47 +00:00
Rohit Waghchaure
85796b3534 fix: validation for zero qty in SABB
(cherry picked from commit 497f560b4b)
2024-04-19 09:41:27 +00:00
Frappe PR Bot
b582570022 chore(release): Bumped to Version 15.20.6
## [15.20.6](https://github.com/frappe/erpnext/compare/v15.20.5...v15.20.6) (2024-04-19)

### Bug Fixes

* account and stock manager read perm ([6cc7c08](6cc7c08ccf))
2024-04-19 08:40:13 +00:00
Gursheen Kaur Anand
8914bce3d8 Merge pull request #41095 from frappe/mergify/bp/version-15/pr-41093
fix: accounts manager perm for FY (backport #41093)
2024-04-19 14:08:59 +05:30
Gursheen Anand
6cc7c08ccf fix: account and stock manager read perm
(cherry picked from commit 572e844a91)
2024-04-19 08:05:05 +00:00
Gursheen Kaur Anand
a1fb289290 Merge pull request #41093 from GursheenK/fy-accounts-manager-perm
fix: accounts manager perm for FY
2024-04-19 13:28:32 +05:30
Gursheen Anand
572e844a91 fix: account and stock manager read perm 2024-04-19 13:05:25 +05:30
rohitwaghchaure
906b9562de Merge pull request #41084 from frappe/mergify/bp/version-15-hotfix/pr-41083
fix: validation for fraction number in Work Order (backport #41083)
2024-04-18 15:56:07 +05:30
Rohit Waghchaure
ef2553edf9 fix: validation for fraction number in Work Order
(cherry picked from commit f8305c2fc0)
2024-04-18 09:15:49 +00:00
mergify[bot]
93242ca883 fix: validate uom is integer for PR item (backport #41074) (#41077)
fix: validate uom is integer for PR item

(cherry picked from commit 9a290fdfc9)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-04-18 07:53:20 +05:30
mergify[bot]
ee7aaf0ea4 fix: don't attempt to set gender from salutation (backport #40997) (#41073)
Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
fix: don't attempt to set gender from salutation (#40997)
2024-04-17 17:53:43 +02:00
mergify[bot]
1ae447e4fc fix: do not add qty to supplied items (backport #41061) (#41066)
fix: do not add qty to supplied items

(cherry picked from commit 8233c392fb)

Co-authored-by: s-aga-r <sagarsharma.s312@gmail.com>
2024-04-17 17:30:43 +05:30
Frappe PR Bot
5ecb022abc chore(release): Bumped to Version 15.20.5
## [15.20.5](https://github.com/frappe/erpnext/compare/v15.20.4...v15.20.5) (2024-04-17)

### Bug Fixes

* duplicate serial and batch bundle in stock entry and stock reco ([a1db5f0](a1db5f0f0a))
2024-04-17 09:25:54 +00:00
rohitwaghchaure
12ab3972de Merge pull request #41058 from frappe/mergify/bp/version-15/pr-41056
fix: duplicate serial and batch bundle in stock entry and stock reco (backport #41053) (backport #41056)
2024-04-17 14:54:34 +05:30
Rohit Waghchaure
a1db5f0f0a fix: duplicate serial and batch bundle in stock entry and stock reco
(cherry picked from commit 732b6e1417)
(cherry picked from commit c10c21157d)
2024-04-17 09:00:05 +00:00
rohitwaghchaure
5195d8a765 Merge pull request #41056 from frappe/mergify/bp/version-15-hotfix/pr-41053
fix: duplicate serial and batch bundle in stock entry and stock reco (backport #41053)
2024-04-17 14:29:14 +05:30
Rohit Waghchaure
c10c21157d fix: duplicate serial and batch bundle in stock entry and stock reco
(cherry picked from commit 732b6e1417)
2024-04-17 07:50:06 +00:00
Deepesh Garg
116a429c45 chore: resolve conflicts 2024-04-17 12:09:05 +05:30
Deepesh Garg
6c10783823 chore: resolve conflicts 2024-04-17 11:47:52 +05:30
Deepesh Garg
5f41036f4a chore: resolve conflicts 2024-04-17 11:38:13 +05:30
Deepesh Garg
e278688a4b fix: Allow updating cost center and project for repostable doctypes
(cherry picked from commit c3845ac0f1)

# Conflicts:
#	erpnext/accounts/doctype/payment_entry/payment_entry.json
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.json
2024-04-17 05:55:02 +00:00
233 changed files with 5857 additions and 1724 deletions

View File

@@ -59,12 +59,14 @@ repos:
rev: v0.2.0
hooks:
- id: ruff
name: "Run ruff linter and apply fixes"
args: ["--fix"]
name: "Run ruff import sorter"
args: ["--select=I", "--fix"]
- id: ruff
name: "Run ruff linter"
- id: ruff-format
name: "Format Python code"
name: "Run ruff formatter"
ci:
autoupdate_schedule: weekly

View File

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

View File

@@ -360,45 +360,45 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
)
if not amount:
return
gl_posting_date = end_date
prev_posting_date = None
# check if books nor frozen till endate:
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
prev_posting_date = end_date
if via_journal_entry:
book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
gl_posting_date = end_date
prev_posting_date = None
# check if books nor frozen till endate:
if accounts_frozen_upto and getdate(end_date) <= getdate(accounts_frozen_upto):
gl_posting_date = get_last_day(add_days(accounts_frozen_upto, 1))
prev_posting_date = end_date
if via_journal_entry:
book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
submit_journal_entry,
)
else:
make_gl_entries(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
gl_posting_date,
project,
account_currency,
item.cost_center,
item,
deferred_process,
)
# Returned in case of any errors because it tries to submit the same record again and again in case of errors
if frappe.flags.deferred_accounting_error:

View File

@@ -22,8 +22,7 @@ frappe.ui.form.on("Account", {
// hide fields if group
frm.toggle_display(["tax_rate"], cint(frm.doc.is_group) == 0);
// disable fields
frm.toggle_enable(["is_group", "company"], false);
frm.toggle_enable(["is_group", "company", "account_number"], frm.is_new());
if (cint(frm.doc.is_group) == 0) {
frm.toggle_display("freeze_account", frm.doc.__onload && frm.doc.__onload.can_freeze_account);

View File

@@ -55,8 +55,7 @@
"fieldtype": "Data",
"in_list_view": 1,
"in_standard_filter": 1,
"label": "Account Number",
"read_only": 1
"label": "Account Number"
},
{
"default": "0",
@@ -72,7 +71,6 @@
"oldfieldname": "company",
"oldfieldtype": "Link",
"options": "Company",
"read_only": 1,
"remember_last_selected_value": 1,
"reqd": 1
},

View File

@@ -222,7 +222,7 @@ frappe.treeview_settings["Account"] = {
"General Ledger",
"Balance Sheet",
"Profit and Loss Statement",
"Cash Flow Statement",
"Cash Flow",
"Accounts Payable",
"Accounts Receivable",
]) {

View File

@@ -1525,7 +1525,8 @@
"41-Clients et comptes rattach\u00e9s (PASSIF)": {
"Clients cr\u00e9diteurs": {
"Clients - Avances et acomptes re\u00e7us sur commandes": {
"account_number": "4191"
"account_number": "4191",
"account_type": "Income Account"
},
"Clients - Dettes pour emballages et mat\u00e9riels consign\u00e9s": {
"account_number": "4196"
@@ -3141,4 +3142,4 @@
"account_number": "7"
}
}
}
}

View File

@@ -57,9 +57,12 @@ frappe.ui.form.on("Accounting Dimension", {
}
},
label: function (frm) {
frm.set_value("fieldname", frappe.model.scrub(frm.doc.label));
},
document_type: function (frm) {
frm.set_value("label", frm.doc.document_type);
frm.set_value("fieldname", frappe.model.scrub(frm.doc.document_type));
frappe.db.get_value(
"Accounting Dimension",

View File

@@ -3,4 +3,23 @@
frappe.ui.form.on("Accounts Settings", {
refresh: function (frm) {},
enable_immutable_ledger: function (frm) {
if (!frm.doc.enable_immutable_ledger) {
return;
}
let msg = __("Enabling this will change the way how cancelled transactions are handled.");
msg += " ";
msg += __("Please enable only if the understand the effects of enabling this.");
msg += "<br>";
msg += "Do you still want to enable immutable ledger?";
frappe.confirm(
msg,
() => {},
() => {
frm.set_value("enable_immutable_ledger", 0);
}
);
},
});

View File

@@ -12,6 +12,7 @@
"unlink_advance_payment_on_cancelation_of_order",
"column_break_13",
"delete_linked_ledger_entries",
"enable_immutable_ledger",
"invoicing_features_section",
"check_supplier_invoice_uniqueness",
"automatically_fetch_payment_terms",
@@ -105,7 +106,7 @@
},
{
"default": "0",
"description": "Enabling ensure each Purchase Invoice has a unique value in Supplier Invoice No. field",
"description": "Enabling this ensures each Purchase Invoice has a unique value in Supplier Invoice No. field within a particular fiscal year",
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness"
@@ -454,6 +455,13 @@
"fieldname": "remarks_section",
"fieldtype": "Section Break",
"label": "Remarks Column Length"
},
{
"default": "0",
"description": "On enabling this cancellation entries will be posted on the actual cancellation date and reports will consider cancelled entries as well",
"fieldname": "enable_immutable_ledger",
"fieldtype": "Check",
"label": "Enable Immutable Ledger"
}
],
"icon": "icon-cog",
@@ -461,7 +469,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2024-01-30 14:04:26.553554",
"modified": "2024-05-11 23:19:44.673975",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",
@@ -490,4 +498,4 @@
"sort_order": "ASC",
"states": [],
"track_changes": 1
}
}

View File

@@ -39,6 +39,7 @@ class AccountsSettings(Document):
determine_address_tax_category_from: DF.Literal["Billing Address", "Shipping Address"]
enable_common_party_accounting: DF.Check
enable_fuzzy_matching: DF.Check
enable_immutable_ledger: DF.Check
enable_party_matching: DF.Check
frozen_accounts_modifier: DF.Link | None
general_ledger_remarks_length: DF.Int

View File

@@ -59,6 +59,10 @@ frappe.ui.form.on("Bank Reconciliation Tool", {
);
frm.add_custom_button(__("Auto Reconcile"), function () {
if (!frm.doc.bank_account) {
frappe.msgprint(__("Please select Bank Account"));
return;
}
frappe.call({
method: "erpnext.accounts.doctype.bank_reconciliation_tool.bank_reconciliation_tool.auto_reconcile_vouchers",
args: {

View File

@@ -26,6 +26,7 @@
{
"fieldname": "company",
"fieldtype": "Link",
"ignore_user_permissions": 1,
"label": "Company",
"options": "Company"
},
@@ -118,7 +119,7 @@
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2023-03-07 11:02:24.535714",
"modified": "2024-04-28 14:40:50.910884",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Bank Reconciliation Tool",
@@ -139,4 +140,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -495,12 +495,12 @@ def check_matching(
bank_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
document_types=None,
from_date=None,
to_date=None,
filter_by_reference_date=None,
from_reference_date=None,
to_reference_date=None,
):
exact_match = True if "exact_match" in document_types else False
@@ -540,14 +540,14 @@ def get_queries(
bank_account,
company,
transaction,
document_types,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
exact_match,
common_filters,
document_types=None,
from_date=None,
to_date=None,
filter_by_reference_date=None,
from_reference_date=None,
to_reference_date=None,
exact_match=None,
common_filters=None,
):
# get queries to get matching vouchers
account_from_to = "paid_to" if transaction.deposit > 0.0 else "paid_from"
@@ -580,15 +580,15 @@ def get_matching_queries(
bank_account,
company,
transaction,
document_types,
exact_match,
account_from_to,
from_date,
to_date,
filter_by_reference_date,
from_reference_date,
to_reference_date,
common_filters,
document_types=None,
exact_match=None,
account_from_to=None,
from_date=None,
to_date=None,
filter_by_reference_date=None,
from_reference_date=None,
to_reference_date=None,
common_filters=None,
):
queries = []
currency = get_account_currency(bank_account)
@@ -719,7 +719,7 @@ def get_pe_matching_query(
(ref_rank + amount_rank + party_rank + 1).as_("rank"),
ConstantColumn("Payment Entry").as_("doctype"),
pe.name,
pe.paid_amount,
pe.paid_amount_after_tax.as_("paid_amount"),
pe.reference_no,
pe.reference_date,
pe.party,

View File

@@ -68,6 +68,9 @@ class AutoMatchbyAccountIBAN:
party, or_filters=or_filters, pluck="name", limit_page_length=1
)
if "bank_ac_no" in or_filters:
or_filters["bank_account_no"] = or_filters.pop("bank_ac_no")
if party_result:
result = (
party,

View File

@@ -219,12 +219,18 @@ def validate_expense_against_budget(args, expense_amount=0):
def validate_budget_records(args, budget_records, expense_amount):
for budget in budget_records:
if flt(budget.budget_amount):
amount = expense_amount or get_amount(args, budget)
yearly_action, monthly_action = get_actions(args, budget)
args["for_material_request"] = budget.for_material_request
args["for_purchase_order"] = budget.for_purchase_order
if yearly_action in ("Stop", "Warn"):
compare_expense_with_budget(
args, flt(budget.budget_amount), _("Annual"), yearly_action, budget.budget_against, amount
args,
flt(budget.budget_amount),
_("Annual"),
yearly_action,
budget.budget_against,
expense_amount,
)
if monthly_action in ["Stop", "Warn"]:
@@ -240,18 +246,27 @@ def validate_budget_records(args, budget_records, expense_amount):
_("Accumulated Monthly"),
monthly_action,
budget.budget_against,
amount,
expense_amount,
)
def compare_expense_with_budget(args, budget_amount, action_for, action, budget_against, amount=0):
actual_expense = get_actual_expense(args)
total_expense = actual_expense + amount
args.actual_expense, args.requested_amount, args.ordered_amount = get_actual_expense(args), 0, 0
if not amount:
args.requested_amount, args.ordered_amount = get_requested_amount(args), get_ordered_amount(args)
if args.get("doctype") == "Material Request" and args.for_material_request:
amount = args.requested_amount + args.ordered_amount
elif args.get("doctype") == "Purchase Order" and args.for_purchase_order:
amount = args.ordered_amount
total_expense = args.actual_expense + amount
if total_expense > budget_amount:
if actual_expense > budget_amount:
if args.actual_expense > budget_amount:
error_tense = _("is already")
diff = actual_expense - budget_amount
diff = args.actual_expense - budget_amount
else:
error_tense = _("will be")
diff = total_expense - budget_amount
@@ -268,6 +283,8 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
frappe.bold(fmt_money(diff, currency=currency)),
)
msg += get_expense_breakup(args, currency, budget_against)
if frappe.flags.exception_approver_role and frappe.flags.exception_approver_role in frappe.get_roles(
frappe.session.user
):
@@ -279,6 +296,83 @@ def compare_expense_with_budget(args, budget_amount, action_for, action, budget_
frappe.msgprint(msg, indicator="orange", title=_("Budget Exceeded"))
def get_expense_breakup(args, currency, budget_against):
msg = "<hr>Total Expenses booked through - <ul>"
common_filters = frappe._dict(
{
args.budget_against_field: budget_against,
"account": args.account,
"company": args.company,
}
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"General Ledger",
label="Actual Expenses",
filters=common_filters.copy().update(
{
"from_date": frappe.get_cached_value("Fiscal Year", args.fiscal_year, "year_start_date"),
"to_date": frappe.get_cached_value("Fiscal Year", args.fiscal_year, "year_end_date"),
"is_cancelled": 0,
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.actual_expense, currency=currency))
+ "</li>"
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"Material Request",
label="Material Requests",
report_type="Report Builder",
doctype="Material Request",
filters=common_filters.copy().update(
{
"status": [["!=", "Stopped"]],
"docstatus": 1,
"material_request_type": "Purchase",
"schedule_date": [["fiscal year", "2023-2024"]],
"item_code": args.item_code,
"per_ordered": [["<", 100]],
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.requested_amount, currency=currency))
+ "</li>"
)
msg += (
"<li>"
+ frappe.utils.get_link_to_report(
"Purchase Order",
label="Unbilled Orders",
report_type="Report Builder",
doctype="Purchase Order",
filters=common_filters.copy().update(
{
"status": [["!=", "Closed"]],
"docstatus": 1,
"transaction_date": [["fiscal year", "2023-2024"]],
"item_code": args.item_code,
"per_billed": [["<", 100]],
}
),
)
+ " - "
+ frappe.bold(fmt_money(args.ordered_amount, currency=currency))
+ "</li></ul>"
)
return msg
def get_actions(args, budget):
yearly_action = budget.action_if_annual_budget_exceeded
monthly_action = budget.action_if_accumulated_monthly_budget_exceeded
@@ -294,23 +388,9 @@ def get_actions(args, budget):
return yearly_action, monthly_action
def get_amount(args, budget):
amount = 0
if args.get("doctype") == "Material Request" and budget.for_material_request:
amount = (
get_requested_amount(args, budget) + get_ordered_amount(args, budget) + get_actual_expense(args)
)
elif args.get("doctype") == "Purchase Order" and budget.for_purchase_order:
amount = get_ordered_amount(args, budget) + get_actual_expense(args)
return amount
def get_requested_amount(args, budget):
def get_requested_amount(args):
item_code = args.get("item_code")
condition = get_other_condition(args, budget, "Material Request")
condition = get_other_condition(args, "Material Request")
data = frappe.db.sql(
""" select ifnull((sum(child.stock_qty - child.ordered_qty) * rate), 0) as amount
@@ -324,9 +404,9 @@ def get_requested_amount(args, budget):
return data[0][0] if data else 0
def get_ordered_amount(args, budget):
def get_ordered_amount(args):
item_code = args.get("item_code")
condition = get_other_condition(args, budget, "Purchase Order")
condition = get_other_condition(args, "Purchase Order")
data = frappe.db.sql(
f""" select ifnull(sum(child.amount - child.billed_amt), 0) as amount
@@ -340,7 +420,7 @@ def get_ordered_amount(args, budget):
return data[0][0] if data else 0
def get_other_condition(args, budget, for_doc):
def get_other_condition(args, for_doc):
condition = "expense_account = '%s'" % (args.expense_account)
budget_against_field = args.get("budget_against_field")

View File

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

View File

@@ -4,7 +4,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import add_days, format_date, getdate
from frappe.utils import add_days, flt, format_date, getdate
class MainCostCenterCantBeChild(frappe.ValidationError):
@@ -60,7 +60,7 @@ class CostCenterAllocation(Document):
self.validate_child_cost_centers()
def validate_total_allocation_percentage(self):
total_percentage = sum([d.percentage for d in self.get("allocation_percentages", [])])
total_percentage = sum([flt(d.percentage) for d in self.get("allocation_percentages", [])])
if total_percentage != 100:
frappe.throw(_("Total percentage against cost centers should be 100"), WrongPercentageAllocation)

View File

@@ -141,7 +141,19 @@ class Dunning(AccountsController):
def on_cancel(self):
super().on_cancel()
self.ignore_linked_doctypes = ["GL Entry"]
self.ignore_linked_doctypes = [
"GL Entry",
"Stock Ledger Entry",
"Repost Item Valuation",
"Repost Payment Ledger",
"Repost Payment Ledger Items",
"Repost Accounting Ledger",
"Repost Accounting Ledger Items",
"Unreconcile Payment",
"Unreconcile Payment Entries",
"Payment Ledger Entry",
"Serial and Batch Bundle",
]
def resolve_dunning(doc, state):

View File

@@ -82,12 +82,12 @@
"icon": "fa fa-calendar",
"idx": 1,
"links": [],
"modified": "2024-01-30 12:35:38.645968",
"modified": "2024-05-27 17:29:55.560840",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Fiscal Year",
"naming_rule": "By fieldname",
"owner": "Administrator",
"owner": "Administrator",
"permissions": [
{
"create": 1,
@@ -119,6 +119,18 @@
{
"read": 1,
"role": "Employee"
},
{
"read": 1,
"role": "Accounts Manager"
},
{
"read": 1,
"role": "Stock Manager"
},
{
"read": 1,
"role": "Auditor"
}
],
"show_name_in_global_search": 1,

View File

@@ -6,7 +6,7 @@ import json
import frappe
from frappe import _, msgprint, scrub
from frappe.utils import cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
from frappe.utils import comma_and, cstr, flt, fmt_money, formatdate, get_link_to_form, nowdate
import erpnext
from erpnext.accounts.deferred_revenue import get_deferred_booking_accounts
@@ -146,6 +146,7 @@ class JournalEntry(AccountsController):
self.validate_empty_accounts_table()
self.validate_inter_company_accounts()
self.validate_depr_entry_voucher_type()
self.validate_advance_accounts()
if self.docstatus == 0:
self.apply_tax_withholding()
@@ -153,6 +154,20 @@ class JournalEntry(AccountsController):
if not self.title:
self.title = self.get_title()
def validate_advance_accounts(self):
journal_accounts = set([x.account for x in self.accounts])
advance_accounts = set()
advance_accounts.add(
frappe.get_cached_value("Company", self.company, "default_advance_received_account")
)
advance_accounts.add(frappe.get_cached_value("Company", self.company, "default_advance_paid_account"))
if advance_accounts_used := journal_accounts & advance_accounts:
frappe.msgprint(
_(
"Making Journal Entries against advance accounts: {0} is not recommended. These Journals won't be available for Reconciliation."
).format(frappe.bold(comma_and(advance_accounts_used)))
)
def validate_for_repost(self):
validate_docs_for_voucher_types(["Journal Entry"])
validate_docs_for_deferred_accounting([self.name], [])
@@ -439,7 +454,7 @@ class JournalEntry(AccountsController):
self.voucher_type == "Depreciation Entry"
and d.reference_type == "Asset"
and d.reference_name
and d.account_type == "Depreciation"
and frappe.get_cached_value("Account", d.account, "root_type") == "Expense"
and d.debit
):
asset = frappe.get_doc("Asset", d.reference_name)
@@ -1016,6 +1031,17 @@ class JournalEntry(AccountsController):
def build_gl_map(self):
gl_map = []
company_currency = erpnext.get_company_currency(self.company)
if self.multi_currency:
for row in self.get("accounts"):
if row.account_currency != company_currency:
self.currency = row.account_currency
self.conversion_rate = row.exchange_rate
break
else:
self.currency = company_currency
for d in self.get("accounts"):
if d.debit or d.credit or (self.voucher_type == "Exchange Gain Or Loss"):
r = [d.user_remark, self.remark]

View File

@@ -1334,7 +1334,9 @@ frappe.ui.form.on("Payment Entry", {
},
callback: function (r) {
if (r.message) {
frm.set_value(field, r.message.account);
if (!frm.doc.mode_of_payment) {
frm.set_value(field, r.message.account);
}
frm.set_value("bank", r.message.bank);
frm.set_value("bank_account_no", r.message.bank_account_no);
}

View File

@@ -20,6 +20,7 @@
"party",
"party_name",
"book_advance_payments_in_separate_party_account",
"reconcile_on_advance_payment_date",
"column_break_11",
"bank_account",
"party_bank_account",
@@ -88,6 +89,7 @@
"custom_remarks",
"remarks",
"base_in_words",
"is_opening",
"column_break_16",
"letter_head",
"print_heading",
@@ -150,6 +152,7 @@
"reqd": 1
},
{
"allow_on_submit": 1,
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
@@ -476,6 +479,7 @@
"label": "More Information"
},
{
"allow_on_submit": 1,
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
@@ -748,6 +752,7 @@
"fieldtype": "Check",
"hidden": 1,
"label": "Book Advance Payments in Separate Party Account",
"no_copy": 1,
"read_only": 1
},
{
@@ -763,6 +768,26 @@
"label": "In Words",
"print_hide": 1,
"read_only": 1
},
{
"default": "0",
"fetch_from": "company.reconcile_on_advance_payment_date",
"fieldname": "reconcile_on_advance_payment_date",
"fieldtype": "Check",
"hidden": 1,
"label": "Reconcile on Advance Payment Date",
"no_copy": 1,
"read_only": 1
},
{
"default": "No",
"depends_on": "eval: doc.book_advance_payments_in_separate_party_account == 1",
"fieldname": "is_opening",
"fieldtype": "Select",
"label": "Is Opening",
"options": "No\nYes",
"print_hide": 1,
"search_index": 1
}
],
"index_web_pages_for_search": 1,
@@ -776,7 +801,7 @@
"table_fieldname": "payment_entries"
}
],
"modified": "2024-01-03 12:46:41.759121",
"modified": "2024-05-31 17:07:06.197249",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Entry",

View File

@@ -76,6 +76,7 @@ class PaymentEntry(AccountsController):
self.setup_party_account_field()
self.set_missing_values()
self.set_liability_account()
self.validate_advance_account_currency()
self.set_missing_ref_details(force=True)
self.validate_payment_type()
self.validate_party_details()
@@ -113,12 +114,15 @@ class PaymentEntry(AccountsController):
if self.docstatus > 0 or self.payment_type == "Internal Transfer":
return
self.book_advance_payments_in_separate_party_account = False
if self.party_type not in ("Customer", "Supplier"):
self.is_opening = "No"
return
if not frappe.db.get_value(
"Company", self.company, "book_advance_payments_in_separate_party_account"
):
self.is_opening = "No"
return
# Important to set this flag for the gl building logic to work properly
@@ -130,6 +134,7 @@ class PaymentEntry(AccountsController):
if (account_type == "Payable" and self.party_type == "Customer") or (
account_type == "Receivable" and self.party_type == "Supplier"
):
self.is_opening = "No"
return
if self.references:
@@ -139,6 +144,7 @@ class PaymentEntry(AccountsController):
# If there are referencers other than `allowed_types`, treat this as a normal payment entry
if reference_types - allowed_types:
self.book_advance_payments_in_separate_party_account = False
self.is_opening = "No"
return
liability_account = get_party_account(
@@ -157,6 +163,22 @@ class PaymentEntry(AccountsController):
alert=True,
)
def validate_advance_account_currency(self):
if self.book_advance_payments_in_separate_party_account is True:
company_currency = frappe.get_cached_value("Company", self.company, "default_currency")
if self.payment_type == "Receive" and self.paid_from_account_currency != company_currency:
frappe.throw(
_("Booking advances in foreign currency account: {0} ({1}) is not yet supported.").format(
frappe.bold(self.paid_from), frappe.bold(self.paid_from_account_currency)
)
)
if self.payment_type == "Pay" and self.paid_to_account_currency != company_currency:
frappe.throw(
_("Booking advances in foreign currency account: {0} ({1}) is not yet supported.").format(
frappe.bold(self.paid_to), frappe.bold(self.paid_to_account_currency)
)
)
def on_cancel(self):
self.ignore_linked_doctypes = (
"GL Entry",
@@ -1113,88 +1135,71 @@ class PaymentEntry(AccountsController):
)
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
if self.book_advance_payments_in_separate_party_account:
for d in self.get("references"):
# re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
cost_center = self.cost_center
if d.reference_doctype == "Sales Invoice" and not cost_center:
cost_center = frappe.db.get_value(d.reference_doctype, d.reference_name, "cost_center")
gle = party_gl_dict.copy()
if self.payment_type == "Receive":
amount = self.base_paid_amount
else:
amount = self.base_received_amount
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(d)
reverse_dr_or_cr = 0
if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]:
is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return")
payable_party_types = get_party_types_from_account_type("Payable")
receivable_party_types = get_party_types_from_account_type("Receivable")
if (
is_return
and self.party_type in receivable_party_types
and (self.payment_type == "Pay")
):
reverse_dr_or_cr = 1
elif (
is_return
and self.party_type in payable_party_types
and (self.payment_type == "Receive")
):
reverse_dr_or_cr = 1
if is_return and not reverse_dr_or_cr:
dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
exchange_rate = self.get_exchange_rate()
amount_in_account_currency = amount * exchange_rate
gle.update(
{
dr_or_cr: amount,
dr_or_cr + "_in_account_currency": amount_in_account_currency,
"against_voucher_type": "Payment Entry",
"against_voucher": self.name,
"cost_center": self.cost_center,
dr_or_cr: abs(allocated_amount_in_company_currency),
dr_or_cr + "_in_account_currency": abs(d.allocated_amount),
"against_voucher_type": d.reference_doctype,
"against_voucher": d.reference_name,
"cost_center": cost_center,
}
)
gl_entries.append(gle)
else:
for d in self.get("references"):
# re-defining dr_or_cr for every reference in order to avoid the last value affecting calculation of reverse
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
cost_center = self.cost_center
if d.reference_doctype == "Sales Invoice" and not cost_center:
cost_center = frappe.db.get_value(
d.reference_doctype, d.reference_name, "cost_center"
)
gle = party_gl_dict.copy()
if self.unallocated_amount:
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
exchange_rate = self.get_exchange_rate()
base_unallocated_amount = self.unallocated_amount * exchange_rate
allocated_amount_in_company_currency = self.calculate_base_allocated_amount_for_reference(
d
)
reverse_dr_or_cr = 0
if d.reference_doctype in ["Sales Invoice", "Purchase Invoice"]:
is_return = frappe.db.get_value(d.reference_doctype, d.reference_name, "is_return")
payable_party_types = get_party_types_from_account_type("Payable")
receivable_party_types = get_party_types_from_account_type("Receivable")
if (
is_return
and self.party_type in receivable_party_types
and (self.payment_type == "Pay")
):
reverse_dr_or_cr = 1
elif (
is_return
and self.party_type in payable_party_types
and (self.payment_type == "Receive")
):
reverse_dr_or_cr = 1
if is_return and not reverse_dr_or_cr:
dr_or_cr = "debit" if dr_or_cr == "credit" else "credit"
gle = party_gl_dict.copy()
gle.update(
{
dr_or_cr + "_in_account_currency": self.unallocated_amount,
dr_or_cr: base_unallocated_amount,
}
)
if self.book_advance_payments_in_separate_party_account:
gle.update(
{
dr_or_cr: abs(allocated_amount_in_company_currency),
dr_or_cr + "_in_account_currency": abs(d.allocated_amount),
"against_voucher_type": d.reference_doctype,
"against_voucher": d.reference_name,
"cost_center": cost_center,
"against_voucher_type": "Payment Entry",
"against_voucher": self.name,
}
)
gl_entries.append(gle)
if self.unallocated_amount:
dr_or_cr = "credit" if self.payment_type == "Receive" else "debit"
exchange_rate = self.get_exchange_rate()
base_unallocated_amount = self.unallocated_amount * exchange_rate
gle = party_gl_dict.copy()
gle.update(
{
dr_or_cr + "_in_account_currency": self.unallocated_amount,
dr_or_cr: base_unallocated_amount,
}
)
gl_entries.append(gle)
gl_entries.append(gle)
def make_advance_gl_entries(
self, entry: object | dict = None, cancel: bool = 0, update_outstanding: str = "Yes"
@@ -1209,7 +1214,7 @@ class PaymentEntry(AccountsController):
def add_advance_gl_entries(self, gl_entries: list, entry: object | dict | None):
"""
If 'entry' is passed, GL enties only for that reference is added.
If 'entry' is passed, GL entries only for that reference is added.
"""
if self.book_advance_payments_in_separate_party_account:
references = [x for x in self.get("references")]
@@ -1221,8 +1226,6 @@ class PaymentEntry(AccountsController):
"Sales Invoice",
"Purchase Invoice",
"Journal Entry",
"Sales Order",
"Purchase Order",
"Payment Entry",
):
self.add_advance_gl_for_reference(gl_entries, ref)
@@ -1250,13 +1253,16 @@ class PaymentEntry(AccountsController):
"voucher_detail_no": invoice.name,
}
date_field = "posting_date"
if invoice.reference_doctype in ["Sales Order", "Purchase Order"]:
date_field = "transaction_date"
posting_date = frappe.db.get_value(invoice.reference_doctype, invoice.reference_name, date_field)
if getdate(posting_date) < getdate(self.posting_date):
if self.reconcile_on_advance_payment_date:
posting_date = self.posting_date
else:
date_field = "posting_date"
if invoice.reference_doctype in ["Sales Order", "Purchase Order"]:
date_field = "transaction_date"
posting_date = frappe.db.get_value(invoice.reference_doctype, invoice.reference_name, date_field)
if getdate(posting_date) < getdate(self.posting_date):
posting_date = self.posting_date
dr_or_cr, account = self.get_dr_and_account_for_advances(invoice)
args_dict["account"] = account
@@ -2028,6 +2034,8 @@ def get_negative_outstanding_invoices(
@frappe.whitelist()
def get_party_details(company, party_type, party, date, cost_center=None):
bank_account = ""
party_bank_account = ""
if not frappe.db.exists(party_type, party):
frappe.throw(_("{0} {1} does not exist").format(_(party_type), party))
@@ -2039,8 +2047,8 @@ def get_party_details(company, party_type, party, date, cost_center=None):
party_balance = get_balance_on(party_type=party_type, party=party, cost_center=cost_center)
if party_type in ["Customer", "Supplier"]:
party_bank_account = get_party_bank_account(party_type, party)
bank_account = get_default_company_bank_account(company, party_type, party)
bank_account = get_default_company_bank_account(company, party_type, party)
return {
"party_account": party_account,
"party_name": party_name,

View File

@@ -10,6 +10,7 @@ from frappe.utils import add_days, flt, nowdate
from erpnext.accounts.doctype.account.test_account import create_account
from erpnext.accounts.doctype.payment_entry.payment_entry import (
get_outstanding_reference_documents,
get_party_details,
get_payment_entry,
get_reference_details,
)
@@ -1439,6 +1440,68 @@ class TestPaymentEntry(FrappeTestCase):
self.check_gl_entries()
self.check_pl_entries()
def test_advance_as_liability_against_order(self):
from erpnext.buying.doctype.purchase_order.purchase_order import (
make_purchase_invoice as _make_purchase_invoice,
)
from erpnext.buying.doctype.purchase_order.test_purchase_order import create_purchase_order
company = "_Test Company"
advance_account = create_account(
parent_account="Current Liabilities - _TC",
account_name="Advances Paid",
company=company,
account_type="Liability",
)
frappe.db.set_value(
"Company",
company,
{
"book_advance_payments_in_separate_party_account": 1,
"default_advance_paid_account": advance_account,
},
)
po = create_purchase_order(supplier="_Test Supplier")
pe = get_payment_entry("Purchase Order", po.name, bank_account="Cash - _TC")
pe.save().submit()
pre_reconciliation_gle = [
{"account": "Cash - _TC", "debit": 0.0, "credit": 5000.0},
{"account": advance_account, "debit": 5000.0, "credit": 0.0},
]
self.voucher_no = pe.name
self.expected_gle = pre_reconciliation_gle
self.check_gl_entries()
# Make Purchase Invoice against the order
pi = _make_purchase_invoice(po.name)
pi.append(
"advances",
{
"reference_type": pe.doctype,
"reference_name": pe.name,
"reference_row": pe.references[0].name,
"advance_amount": 5000,
"allocated_amount": 5000,
},
)
pi.save().submit()
# # assert General and Payment Ledger entries post partial reconciliation
self.expected_gle = [
{"account": pi.credit_to, "debit": 5000.0, "credit": 0.0},
{"account": "Cash - _TC", "debit": 0.0, "credit": 5000.0},
{"account": advance_account, "debit": 5000.0, "credit": 0.0},
{"account": advance_account, "debit": 0.0, "credit": 5000.0},
]
self.voucher_no = pe.name
self.check_gl_entries()
def check_pl_entries(self):
ple = frappe.qb.DocType("Payment Ledger Entry")
pl_entries = (
@@ -1666,6 +1729,68 @@ class TestPaymentEntry(FrappeTestCase):
self.check_gl_entries()
self.check_pl_entries()
def test_opening_flag_for_advance_as_liability(self):
company = "_Test Company"
advance_account = create_account(
parent_account="Current Assets - _TC",
account_name="Advances Received",
company=company,
account_type="Receivable",
)
# Enable Advance in separate party account
frappe.db.set_value(
"Company",
company,
{
"book_advance_payments_in_separate_party_account": 1,
"default_advance_received_account": advance_account,
},
)
# Advance Payment
adv = create_payment_entry(
party_type="Customer",
party="_Test Customer",
payment_type="Receive",
paid_from="Debtors - _TC",
paid_to="_Test Cash - _TC",
)
adv.is_opening = "Yes"
adv.save() # use save() to trigger set_liability_account()
adv.submit()
gl_with_opening_set = frappe.db.get_all(
"GL Entry", filters={"voucher_no": adv.name, "is_opening": "Yes"}
)
# 'Is Opening' can be 'Yes' for Advances in separate party account
self.assertNotEqual(gl_with_opening_set, [])
# Disable Advance in separate party account
frappe.db.set_value(
"Company",
company,
{
"book_advance_payments_in_separate_party_account": 0,
"default_advance_received_account": None,
},
)
payment = create_payment_entry(
party_type="Customer",
party="_Test Customer",
payment_type="Receive",
paid_from="Debtors - _TC",
paid_to="_Test Cash - _TC",
)
payment.is_opening = "Yes"
payment.save()
payment.submit()
gl_with_opening_set = frappe.db.get_all(
"GL Entry", filters={"voucher_no": payment.name, "is_opening": "Yes"}
)
# 'Is Opening' should always be 'No' for normal advance payments
self.assertEqual(gl_with_opening_set, [])
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")
@@ -1684,6 +1809,10 @@ def create_payment_entry(**args):
payment_entry.reference_no = "Test001"
payment_entry.reference_date = nowdate()
get_party_details(
payment_entry.company, payment_entry.party_type, payment_entry.party, payment_entry.posting_date
)
if args.get("save"):
payment_entry.save()
if args.get("submit"):

View File

@@ -71,6 +71,7 @@ frappe.ui.form.on("Payment Order", {
target: frm,
date_field: "posting_date",
setters: {
party_type: "Supplier",
party: frm.doc.supplier || "",
},
get_query_filters: {
@@ -91,6 +92,7 @@ frappe.ui.form.on("Payment Order", {
source_doctype: "Payment Request",
target: frm,
setters: {
party_type: "Supplier",
party: frm.doc.supplier || "",
},
get_query_filters: {

View File

@@ -176,8 +176,12 @@ erpnext.accounts.PaymentReconciliationController = class PaymentReconciliationCo
},
callback: (r) => {
if (!r.exc && r.message) {
this.frm.set_value("receivable_payable_account", r.message[0]);
this.frm.set_value("default_advance_account", r.message[1]);
if (typeof r.message === "string") {
this.frm.set_value("receivable_payable_account", r.message);
} else if (Array.isArray(r.message)) {
this.frm.set_value("receivable_payable_account", r.message[0]);
this.frm.set_value("default_advance_account", r.message[1]);
}
}
this.frm.refresh();
},

View File

@@ -195,6 +195,8 @@
},
{
"depends_on": "eval:doc.party",
"description": "Only 'Payment Entries' made against this advance account are supported.",
"documentation_url": "https://docs.erpnext.com/docs/user/manual/en/advance-in-separate-party-account",
"fieldname": "default_advance_account",
"fieldtype": "Link",
"label": "Default Advance Account",
@@ -229,7 +231,7 @@
"is_virtual": 1,
"issingle": 1,
"links": [],
"modified": "2023-12-14 13:38:16.264013",
"modified": "2024-04-23 12:38:29.557315",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation",

View File

@@ -1525,6 +1525,55 @@ class TestPaymentReconciliation(FrappeTestCase):
]
self.assertEqual(pl_entries, expected_ple)
def test_advance_payment_reconciliation_date(self):
frappe.db.set_value(
"Company",
self.company,
{
"book_advance_payments_in_separate_party_account": 1,
"default_advance_paid_account": self.advance_payable_account,
"reconcile_on_advance_payment_date": 1,
},
)
self.supplier = "_Test Supplier"
amount = 1500
pe = self.create_payment_entry(amount=amount)
pe.posting_date = add_days(nowdate(), -1)
pe.party_type = "Supplier"
pe.party = self.supplier
pe.payment_type = "Pay"
pe.paid_from = self.cash
pe.paid_to = self.advance_payable_account
pe.save().submit()
pi = self.create_purchase_invoice(qty=10, rate=100)
self.assertNotEqual(pe.posting_date, pi.posting_date)
pr = self.create_payment_reconciliation(party_is_customer=False)
pr.default_advance_account = self.advance_payable_account
pr.from_payment_date = pe.posting_date
pr.get_unreconciled_entries()
self.assertEqual(len(pr.invoices), 1)
self.assertEqual(len(pr.payments), 1)
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}))
pr.reconcile()
# Assert Ledger Entries
gl_entries = frappe.db.get_all(
"GL Entry",
filters={"voucher_no": pe.name, "is_cancelled": 0, "posting_date": pe.posting_date},
)
self.assertEqual(len(gl_entries), 4)
pl_entries = frappe.db.get_all(
"Payment Ledger Entry",
filters={"voucher_no": pe.name, "delinked": 0, "posting_date": pe.posting_date},
)
self.assertEqual(len(pl_entries), 3)
def make_customer(customer_name, currency=None):
if not frappe.db.exists("Customer", customer_name):

View File

@@ -70,7 +70,7 @@ class POSClosingEntry(StatusUpdater):
for key, value in pos_occurences.items():
if len(value) > 1:
error_list.append(
_(f"{frappe.bold(key)} is added multiple times on rows: {frappe.bold(value)}")
_("{0} is added multiple times on rows: {1}").format(frappe.bold(key), frappe.bold(value))
)
if error_list:

View File

@@ -228,6 +228,7 @@ class POSInvoice(SalesInvoice):
self.apply_loyalty_points()
self.check_phone_payments()
self.set_status(update=True)
self.make_bundle_for_sales_purchase_return()
self.submit_serial_batch_bundle()
if self.coupon_code:

View File

@@ -318,29 +318,28 @@ class TestPOSInvoice(unittest.TestCase):
pos.insert()
pos.submit()
pos.reload()
pos_return1 = make_sales_return(pos.name)
# partial return 1
pos_return1.get("items")[0].qty = -1
pos_return1.submit()
pos_return1.reload()
bundle_id = frappe.get_doc(
"Serial and Batch Bundle", pos_return1.get("items")[0].serial_and_batch_bundle
)
bundle_id.remove(bundle_id.entries[1])
bundle_id.save()
bundle_id.load_from_db()
serial_no = bundle_id.entries[0].serial_no
self.assertEqual(serial_no, serial_nos[0])
pos_return1.insert()
pos_return1.submit()
# partial return 2
pos_return2 = make_sales_return(pos.name)
pos_return2.submit()
self.assertEqual(pos_return2.get("items")[0].qty, -1)
serial_no = get_serial_nos_from_bundle(pos_return2.get("items")[0].serial_and_batch_bundle)[0]
self.assertEqual(serial_no, serial_nos[1])

View File

@@ -54,7 +54,7 @@ class POSInvoiceMergeLog(Document):
for key, value in pos_occurences.items():
if len(value) > 1:
error_list.append(
_(f"{frappe.bold(key)} is added multiple times on rows: {frappe.bold(value)}")
_("{0} is added multiple times on rows: {1}").format(frappe.bold(key), frappe.bold(value))
)
if error_list:
@@ -481,7 +481,7 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
if closing_entry:
closing_entry.set_status(update=True, status="Failed")
if isinstance(error_message, list):
error_message = frappe.json.dumps(error_message)
error_message = json.dumps(error_message)
closing_entry.db_set("error_message", error_message)
raise

View File

@@ -74,15 +74,21 @@
"discount_amount",
"discount_percentage",
"for_price_list",
"section_break_13",
"threshold_percentage",
"priority",
"dynamic_condition_tab",
"condition",
"column_break_66",
"section_break_13",
"apply_multiple_pricing_rules",
"apply_discount_on_rate",
"column_break_66",
"threshold_percentage",
"validate_pricing_rule_section",
"validate_applied_rule",
"column_break_texp",
"rule_description",
"priority_section",
"has_priority",
"column_break_sayg",
"priority",
"help_section",
"pricing_rule_help",
"reference_section",
@@ -477,7 +483,7 @@
{
"collapsible": 1,
"fieldname": "section_break_13",
"fieldtype": "Section Break",
"fieldtype": "Tab Break",
"label": "Advanced Settings"
},
{
@@ -487,6 +493,7 @@
"label": "Threshold for Suggestion (In Percentage)"
},
{
"depends_on": "has_priority",
"description": "Higher the number, higher the priority",
"fieldname": "priority",
"fieldtype": "Select",
@@ -513,6 +520,7 @@
{
"default": "0",
"depends_on": "eval:doc.price_or_product_discount == 'Price'",
"description": "If enabled, then system will only validate the pricing rule and not apply automatically. User has to manually set the discount percentage / margin / free items to validate the pricing rule",
"fieldname": "validate_applied_rule",
"fieldtype": "Check",
"label": "Validate Applied Rule"
@@ -525,7 +533,8 @@
},
{
"fieldname": "help_section",
"fieldtype": "Section Break",
"fieldtype": "Tab Break",
"label": "Help Article",
"options": "Simple"
},
{
@@ -603,12 +612,42 @@
"fieldname": "apply_recursion_over",
"fieldtype": "Float",
"label": "Apply Recursion Over (As Per Transaction UOM)"
},
{
"fieldname": "priority_section",
"fieldtype": "Section Break",
"label": "Priority"
},
{
"fieldname": "dynamic_condition_tab",
"fieldtype": "Tab Break",
"label": "Dynamic Condition"
},
{
"fieldname": "validate_pricing_rule_section",
"fieldtype": "Section Break",
"label": "Validate Pricing Rule"
},
{
"fieldname": "column_break_texp",
"fieldtype": "Column Break"
},
{
"fieldname": "column_break_sayg",
"fieldtype": "Column Break"
},
{
"default": "0",
"description": "Enable this checkbox even if you want to set the zero priority",
"fieldname": "has_priority",
"fieldtype": "Check",
"label": "Has Priority"
}
],
"icon": "fa fa-gift",
"idx": 1,
"links": [],
"modified": "2023-02-14 04:53:34.887358",
"modified": "2024-05-17 13:16:34.496704",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Pricing Rule",

View File

@@ -27,9 +27,7 @@ class PricingRule(Document):
from frappe.types import DF
from erpnext.accounts.doctype.pricing_rule_brand.pricing_rule_brand import PricingRuleBrand
from erpnext.accounts.doctype.pricing_rule_item_code.pricing_rule_item_code import (
PricingRuleItemCode,
)
from erpnext.accounts.doctype.pricing_rule_item_code.pricing_rule_item_code import PricingRuleItemCode
from erpnext.accounts.doctype.pricing_rule_item_group.pricing_rule_item_group import (
PricingRuleItemGroup,
)
@@ -67,6 +65,7 @@ class PricingRule(Document):
free_item_rate: DF.Currency
free_item_uom: DF.Link | None
free_qty: DF.Float
has_priority: DF.Check
is_cumulative: DF.Check
is_recursive: DF.Check
item_groups: DF.Table[PricingRuleItemGroup]
@@ -156,6 +155,12 @@ class PricingRule(Document):
frappe.throw(_("Duplicate {0} found in the table").format(self.apply_on))
def validate_mandatory(self):
if self.has_priority and not self.priority:
throw(_("Priority is mandatory"), frappe.MandatoryError, _("Please Set Priority"))
if self.priority and not self.has_priority:
self.has_priority = 1
for apply_on, field in apply_on_dict.items():
if self.apply_on == apply_on and len(self.get(field) or []) < 1:
throw(_("{0} is not added in the table").format(apply_on), frappe.MandatoryError)
@@ -573,6 +578,22 @@ def apply_price_discount_rule(pricing_rule, item_details, args):
if pricing_rule.apply_discount_on_rate and item_details.get("discount_percentage"):
# Apply discount on discounted rate
item_details[field] += (100 - item_details[field]) * (pricing_rule.get(field, 0) / 100)
elif args.price_list_rate:
value = pricing_rule.get(field, 0)
calculate_discount_percentage = False
if field == "discount_percentage":
field = "discount_amount"
value = args.price_list_rate * (value / 100)
calculate_discount_percentage = True
if field not in item_details:
item_details.setdefault(field, 0)
item_details[field] += value if pricing_rule else args.get(field, 0)
if calculate_discount_percentage and args.price_list_rate and item_details.discount_amount:
item_details.discount_percentage = flt(
(flt(item_details.discount_amount) / flt(args.price_list_rate)) * 100
)
else:
if field not in item_details:
item_details.setdefault(field, 0)

View File

@@ -929,6 +929,30 @@ class TestPricingRule(unittest.TestCase):
for doc in [si, si1]:
doc.delete()
def test_pricing_rule_for_transaction_with_condition(self):
make_item("PR Transaction Condition")
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule")
make_pricing_rule(
selling=1,
min_qty=0,
price_or_product_discount="Product",
apply_on="Transaction",
free_item="PR Transaction Condition",
free_qty=1,
free_item_rate=10,
condition="customer=='_Test Customer 1'",
)
si = create_sales_invoice(qty=5, customer="_Test Customer 1", do_not_submit=True)
self.assertEqual(len(si.items), 2)
self.assertEqual(si.items[1].rate, 10)
si1 = create_sales_invoice(qty=5, customer="_Test Customer 2", do_not_submit=True)
self.assertEqual(len(si1.items), 1)
for doc in [si, si1]:
doc.delete()
def test_remove_pricing_rule(self):
item = make_item("Water Flask")
make_item_price("Water Flask", "_Test Price List", 100)
@@ -1102,7 +1126,116 @@ class TestPricingRule(unittest.TestCase):
so.load_from_db()
self.assertEqual(so.items[1].is_free_item, 1)
self.assertEqual(so.items[1].item_code, "_Test Item")
self.assertEqual(so.items[1].qty, 4)
self.assertEqual(so.items[1].qty, 3)
def test_apply_multiple_pricing_rules_for_discount_percentage_and_amount(self):
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule 1",
"name": "_Test Pricing Rule 1",
"apply_on": "Item Code",
"currency": "USD",
"items": [
{
"item_code": "_Test Item",
}
],
"selling": 1,
"price_or_product_discount": "Price",
"rate_or_discount": "Discount Percentage",
"discount_percentage": 10,
"apply_multiple_pricing_rules": 1,
"company": "_Test Company",
}
frappe.get_doc(test_record.copy()).insert()
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule 2",
"name": "_Test Pricing Rule 2",
"apply_on": "Item Code",
"currency": "USD",
"items": [
{
"item_code": "_Test Item",
}
],
"selling": 1,
"price_or_product_discount": "Price",
"rate_or_discount": "Discount Amount",
"discount_amount": 100,
"apply_multiple_pricing_rules": 1,
"company": "_Test Company",
}
frappe.get_doc(test_record.copy()).insert()
so = make_sales_order(item_code="_Test Item", qty=1, price_list_rate=1000, do_not_submit=True)
self.assertEqual(so.items[0].discount_amount, 200)
self.assertEqual(so.items[0].rate, 800)
frappe.delete_doc_if_exists("Sales Order", so.name)
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
def test_priority_of_multiple_pricing_rules(self):
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule 1",
"name": "_Test Pricing Rule 1",
"apply_on": "Item Code",
"currency": "USD",
"items": [
{
"item_code": "_Test Item",
}
],
"selling": 1,
"price_or_product_discount": "Price",
"rate_or_discount": "Discount Percentage",
"discount_percentage": 10,
"has_priority": 1,
"priority": 1,
"company": "_Test Company",
}
frappe.get_doc(test_record.copy()).insert()
test_record = {
"doctype": "Pricing Rule",
"title": "_Test Pricing Rule 2",
"name": "_Test Pricing Rule 2",
"apply_on": "Item Code",
"currency": "USD",
"items": [
{
"item_code": "_Test Item",
}
],
"selling": 1,
"price_or_product_discount": "Price",
"rate_or_discount": "Discount Percentage",
"discount_percentage": 20,
"has_priority": 1,
"priority": 3,
"company": "_Test Company",
}
frappe.get_doc(test_record.copy()).insert()
so = make_sales_order(item_code="_Test Item", qty=1, price_list_rate=1000, do_not_submit=True)
self.assertEqual(so.items[0].discount_percentage, 20)
self.assertEqual(so.items[0].rate, 800)
frappe.delete_doc_if_exists("Sales Order", so.name)
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 1")
frappe.delete_doc_if_exists("Pricing Rule", "_Test Pricing Rule 2")
test_dependencies = ["Campaign"]
@@ -1132,6 +1265,7 @@ def make_pricing_rule(**args):
"priority": args.priority or 1,
"discount_amount": args.discount_amount or 0.0,
"apply_multiple_pricing_rules": args.apply_multiple_pricing_rules or 0,
"has_priority": args.has_priority or 0,
}
)

View File

@@ -6,6 +6,7 @@
import copy
import json
import math
import frappe
from frappe import _, bold
@@ -32,6 +33,9 @@ def get_pricing_rules(args, doc=None):
for apply_on in ["Item Code", "Item Group", "Brand"]:
pricing_rules.extend(_get_pricing_rules(apply_on, args, values))
if pricing_rules and pricing_rules[0].has_priority:
continue
if pricing_rules and not apply_multiple_pricing_rules(pricing_rules):
break
@@ -560,6 +564,7 @@ def apply_pricing_rule_on_transaction(doc):
if pricing_rules:
pricing_rules = filter_pricing_rules_for_qty_amount(doc.total_qty, doc.total, pricing_rules)
pricing_rules = filter_pricing_rule_based_on_condition(pricing_rules, doc)
if not pricing_rules:
remove_free_item(doc)
@@ -653,7 +658,7 @@ def get_product_discount_rule(pricing_rule, item_details, args=None, doc=None):
if transaction_qty:
qty = flt(transaction_qty) * qty / pricing_rule.recurse_for
if pricing_rule.round_free_qty:
qty = round(qty)
qty = math.floor(qty)
free_item_data_args = {
"item_code": free_item,

View File

@@ -1,6 +1,8 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import json
import frappe
from frappe import _, qb
from frappe.model.document import Document
@@ -504,7 +506,7 @@ def is_any_doc_running(for_filter: str | dict | None = None) -> str | None:
running_doc = None
if for_filter:
if isinstance(for_filter, str):
for_filter = frappe.json.loads(for_filter)
for_filter = json.loads(for_filter)
running_doc = frappe.db.get_value(
"Process Payment Reconciliation",

View File

@@ -158,7 +158,7 @@ def set_ageing(doc, entry):
ageing_filters = frappe._dict(
{
"company": doc.company,
"report_date": doc.to_date,
"report_date": doc.posting_date,
"ageing_based_on": doc.ageing_based_on,
"range1": 30,
"range2": 60,

View File

@@ -340,10 +340,11 @@
<table class="table table-bordered">
<thead>
<tr>
<th style="width: 25%">30 Days</th>
<th style="width: 25%">60 Days</th>
<th style="width: 25%">90 Days</th>
<th style="width: 25%">120 Days</th>
<th style="width: 25%">0 - 30 Days</th>
<th style="width: 25%">30 - 60 Days</th>
<th style="width: 25%">60 - 90 Days</th>
<th style="width: 25%">90 - 120 Days</th>
<th style="width: 20%">Above 120 Days</th>
</tr>
</thead>
<tbody>
@@ -352,6 +353,7 @@
<td>{{ frappe.utils.fmt_money(ageing.range2, currency=data[0]["currency"]) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range3, currency=data[0]["currency"]) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range4, currency=data[0]["currency"]) }}</td>
<td>{{ frappe.utils.fmt_money(ageing.range5, currency=filters.presentation_currency) }}</td>
</tr>
</tbody>
</table>

View File

@@ -11,13 +11,15 @@
{
"fieldname": "cost_center_name",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Cost Center",
"options": "Cost Center"
"options": "Cost Center",
"reqd": 1
}
],
"istable": 1,
"links": [],
"modified": "2020-08-03 16:56:45.744905",
"modified": "2024-05-03 17:16:51.666461",
"modified_by": "Administrator",
"module": "Accounts",
"name": "PSOA Cost Center",
@@ -27,4 +29,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}
}

View File

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

View File

@@ -485,10 +485,12 @@ function hide_fields(doc) {
var item_fields_stock = ["warehouse_section", "received_qty", "rejected_qty"];
cur_frm.fields_dict["items"].grid.set_column_disp(
item_fields_stock,
cint(doc.update_stock) == 1 || cint(doc.is_return) == 1 ? true : false
);
if (cur_frm.fields_dict["items"]) {
cur_frm.fields_dict["items"].grid.set_column_disp(
item_fields_stock,
cint(doc.update_stock) == 1 || cint(doc.is_return) == 1 ? true : false
);
}
cur_frm.refresh_fields();
}
@@ -675,7 +677,7 @@ frappe.ui.form.on("Purchase Invoice", {
if (frm.doc.supplier) {
frm.doc.apply_tds = frm.doc.__onload.supplier_tds ? 1 : 0;
}
if (!frm.doc.__onload.supplier_tds) {
if (!frm.doc.__onload.enable_apply_tds) {
frm.set_df_property("apply_tds", "read_only", 1);
}
}

View File

@@ -299,6 +299,7 @@
"remember_last_selected_value": 1
},
{
"allow_on_submit": 1,
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
@@ -1367,6 +1368,7 @@
"read_only": 1
},
{
"allow_on_submit": 1,
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
@@ -1637,7 +1639,7 @@
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2024-03-20 15:57:00.736868",
"modified": "2024-04-11 11:28:42.802211",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",

View File

@@ -3,7 +3,7 @@
import frappe
from frappe import _, throw
from frappe import _, qb, throw
from frappe.model.mapper import get_mapped_doc
from frappe.query_builder.functions import Sum
from frappe.utils import cint, cstr, flt, formatdate, get_link_to_form, getdate, nowdate
@@ -68,15 +68,11 @@ class PurchaseInvoice(BuyingController):
from erpnext.accounts.doctype.purchase_invoice_advance.purchase_invoice_advance import (
PurchaseInvoiceAdvance,
)
from erpnext.accounts.doctype.purchase_invoice_item.purchase_invoice_item import (
PurchaseInvoiceItem,
)
from erpnext.accounts.doctype.purchase_invoice_item.purchase_invoice_item import PurchaseInvoiceItem
from erpnext.accounts.doctype.purchase_taxes_and_charges.purchase_taxes_and_charges import (
PurchaseTaxesandCharges,
)
from erpnext.accounts.doctype.tax_withheld_vouchers.tax_withheld_vouchers import (
TaxWithheldVouchers,
)
from erpnext.accounts.doctype.tax_withheld_vouchers.tax_withheld_vouchers import TaxWithheldVouchers
from erpnext.buying.doctype.purchase_receipt_item_supplied.purchase_receipt_item_supplied import (
PurchaseReceiptItemSupplied,
)
@@ -351,6 +347,22 @@ class PurchaseInvoice(BuyingController):
self.tax_withholding_category = tds_category
self.set_onload("supplier_tds", tds_category)
# If Linked Purchase Order has TDS applied, enable 'apply_tds' checkbox
if purchase_orders := [x.purchase_order for x in self.items if x.purchase_order]:
po = qb.DocType("Purchase Order")
po_with_tds = (
qb.from_(po)
.select(po.name)
.where(
po.docstatus.eq(1)
& (po.name.isin(purchase_orders))
& (po.apply_tds.eq(1))
& (po.tax_withholding_category.notnull())
)
.run()
)
self.set_onload("enable_apply_tds", True if po_with_tds else False)
super().set_missing_values(for_validate)
def validate_credit_to_acc(self):
@@ -452,7 +464,7 @@ class PurchaseInvoice(BuyingController):
stock_not_billed_account = self.get_company_default("stock_received_but_not_billed")
stock_items = self.get_stock_items()
asset_received_but_not_billed = None
self.asset_received_but_not_billed = None
if self.update_stock:
self.validate_item_code()
@@ -535,26 +547,45 @@ class PurchaseInvoice(BuyingController):
frappe.msgprint(msg, title=_("Expense Head Changed"))
item.expense_account = stock_not_billed_account
elif item.is_fixed_asset and item.pr_detail:
if not asset_received_but_not_billed:
asset_received_but_not_billed = self.get_company_default("asset_received_but_not_billed")
item.expense_account = asset_received_but_not_billed
elif item.is_fixed_asset:
account_type = (
"capital_work_in_progress_account"
if is_cwip_accounting_enabled(item.asset_category)
else "fixed_asset_account"
)
asset_category_account = get_asset_category_account(
account_type, item=item.item_code, company=self.company
)
if not asset_category_account:
form_link = get_link_to_form("Asset Category", item.asset_category)
throw(
_("Please set Fixed Asset Account in {} against {}.").format(form_link, self.company),
title=_("Missing Account"),
account = None
if item.pr_detail:
if not self.asset_received_but_not_billed:
self.asset_received_but_not_billed = self.get_company_default(
"asset_received_but_not_billed"
)
# check if 'Asset Received But Not Billed' account is credited in Purchase receipt or not
arbnb_booked_in_pr = frappe.db.get_value(
"GL Entry",
{
"voucher_type": "Purchase Receipt",
"voucher_no": item.purchase_receipt,
"account": self.asset_received_but_not_billed,
},
"name",
)
item.expense_account = asset_category_account
if arbnb_booked_in_pr:
account = self.asset_received_but_not_billed
if not account:
account_type = (
"capital_work_in_progress_account"
if is_cwip_accounting_enabled(item.asset_category)
else "fixed_asset_account"
)
account = get_asset_category_account(
account_type, item=item.item_code, company=self.company
)
if not account:
form_link = get_link_to_form("Asset Category", item.asset_category)
throw(
_("Please set Fixed Asset Account in {} against {}.").format(
form_link, self.company
),
title=_("Missing Account"),
)
item.expense_account = account
elif not item.expense_account and for_validate:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))
@@ -652,6 +683,19 @@ class PurchaseInvoice(BuyingController):
where name=`tabPurchase Invoice Item`.parent and update_stock = 1)""",
}
)
self.status_updater.append(
{
"source_dt": "Purchase Invoice Item",
"target_dt": "Material Request Item",
"join_field": "material_request_item",
"target_field": "received_qty",
"target_parent_dt": "Material Request",
"target_parent_field": "per_received",
"target_ref_field": "stock_qty",
"source_field": "stock_qty",
"percent_join_field": "material_request",
}
)
if cint(self.is_return):
self.status_updater.append(
{
@@ -711,6 +755,7 @@ class PurchaseInvoice(BuyingController):
# Updating stock ledger should always be called after updating prevdoc status,
# because updating ordered qty in bin depends upon updated ordered qty in PO
if self.update_stock == 1:
self.make_bundle_for_sales_purchase_return()
self.make_bundle_using_old_serial_batch_fields()
self.update_stock_ledger()
@@ -1039,10 +1084,10 @@ class PurchaseInvoice(BuyingController):
if provisional_accounting_for_non_stock_items:
if item.purchase_receipt:
provisional_account, pr_qty, pr_base_rate = frappe.get_cached_value(
provisional_account, pr_qty, pr_base_rate, pr_rate = frappe.get_cached_value(
"Purchase Receipt Item",
item.pr_detail,
["provisional_expense_account", "qty", "base_rate"],
["provisional_expense_account", "qty", "base_rate", "rate"],
)
provisional_account = provisional_account or self.get_company_default(
"default_provisional_account"
@@ -1076,7 +1121,10 @@ class PurchaseInvoice(BuyingController):
self.posting_date,
provisional_account,
reverse=1,
item_amount=(min(item.qty, pr_qty) * pr_base_rate),
item_amount=(
(min(item.qty, pr_qty) * pr_rate)
* purchase_receipt_doc.get("conversion_rate")
),
)
if not self.is_internal_transfer():
@@ -1095,7 +1143,7 @@ class PurchaseInvoice(BuyingController):
)
# check if the exchange rate has changed
if item.get("purchase_receipt"):
if item.get("purchase_receipt") and self.auto_accounting_for_stock:
if (
exchange_rate_map[item.purchase_receipt]
and self.conversion_rate != exchange_rate_map[item.purchase_receipt]
@@ -1186,7 +1234,7 @@ class PurchaseInvoice(BuyingController):
asset.name,
{
"gross_purchase_amount": purchase_amount,
"purchase_receipt_amount": purchase_amount,
"purchase_amount": purchase_amount,
},
)

View File

@@ -17,6 +17,8 @@ from erpnext.controllers.buying_controller import QtyMismatchError
from erpnext.exceptions import InvalidCurrency
from erpnext.projects.doctype.project.test_project import make_project
from erpnext.stock.doctype.item.test_item import create_item
from erpnext.stock.doctype.material_request.material_request import make_purchase_order
from erpnext.stock.doctype.material_request.test_material_request import make_material_request
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
make_purchase_invoice as create_purchase_invoice_from_receipt,
)
@@ -72,6 +74,31 @@ class TestPurchaseInvoice(FrappeTestCase, StockTestMixin):
# teardown
pi.delete()
def test_update_received_qty_in_material_request(self):
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
"""
Test if the received_qty in Material Request is updated correctly when
a Purchase Invoice with update_stock=True is submitted.
"""
mr = make_material_request(item_code="_Test Item", qty=10)
mr.save()
mr.submit()
po = make_purchase_order(mr.name)
po.supplier = "_Test Supplier"
po.save()
po.submit()
# Create a Purchase Invoice with update_stock=True
pi = make_purchase_invoice(po.name)
pi.update_stock = True
pi.insert()
pi.submit()
# Check if the received quantity is updated in Material Request
mr.reload()
self.assertEqual(mr.items[0].received_qty, 10)
def test_gl_entries_without_perpetual_inventory(self):
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
pi = frappe.copy_doc(test_records[0])

View File

@@ -105,6 +105,8 @@
"purchase_receipt",
"pr_detail",
"sales_invoice_item",
"material_request",
"material_request_item",
"item_weight_details",
"weight_per_unit",
"total_weight",
@@ -934,12 +936,34 @@
{
"fieldname": "column_break_vbbb",
"fieldtype": "Column Break"
},
{
"fieldname": "material_request",
"fieldtype": "Link",
"label": "Material Request",
"no_copy": 1,
"options": "Material Request",
"print_hide": 1,
"read_only": 1,
"search_index": 1
},
{
"fieldname": "material_request_item",
"fieldtype": "Data",
"hidden": 1,
"label": "Material Request Item",
"no_copy": 1,
"oldfieldname": "pr_detail",
"oldfieldtype": "Data",
"print_hide": 1,
"read_only": 1,
"search_index": 1
}
],
"idx": 1,
"istable": 1,
"links": [],
"modified": "2024-03-19 19:09:47.210965",
"modified": "2024-06-14 11:57:07.171700",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",
@@ -949,4 +973,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -52,6 +52,8 @@ class PurchaseInvoiceItem(Document):
manufacturer_part_no: DF.Data | None
margin_rate_or_amount: DF.Float
margin_type: DF.Literal["", "Percentage", "Amount"]
material_request: DF.Link | None
material_request_item: DF.Data | None
net_amount: DF.Currency
net_rate: DF.Currency
page_break: DF.Check

View File

@@ -1,7 +1,5 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "format:ACC-REPOST-{#####}",
"creation": "2023-07-04 13:07:32.923675",
"default_view": "List",
"doctype": "DocType",
@@ -55,14 +53,15 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-09-26 14:21:27.362567",
"modified": "2024-06-03 17:30:37.012593",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Accounting Ledger",
"naming_rule": "Expression",
"owner": "Administrator",
"permissions": [
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
@@ -71,7 +70,9 @@
"read": 1,
"report": 1,
"role": "System Manager",
"select": 1,
"share": 1,
"submit": 1,
"write": 1
}
],

View File

@@ -17,7 +17,7 @@
"in_create": 1,
"issingle": 1,
"links": [],
"modified": "2023-11-07 14:24:13.321522",
"modified": "2024-06-06 13:56:37.908879",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Accounting Ledger Settings",
@@ -30,13 +30,17 @@
"print": 1,
"read": 1,
"role": "Administrator",
"select": 1,
"share": 1,
"write": 1
},
{
"create": 1,
"delete": 1,
"read": 1,
"role": "System Manager",
"select": 1
"select": 1,
"write": 1
}
],
"sort_field": "modified",

View File

@@ -1,6 +1,5 @@
{
"actions": [],
"allow_rename": 1,
"creation": "2022-10-19 21:59:33.553852",
"doctype": "DocType",
"editable_grid": 1,
@@ -99,13 +98,15 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2023-09-26 14:21:35.719727",
"modified": "2024-06-03 17:31:04.472279",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Repost Payment Ledger",
"owner": "Administrator",
"permissions": [
{
"amend": 1,
"cancel": 1,
"create": 1,
"delete": 1,
"email": 1,
@@ -114,7 +115,9 @@
"read": 1,
"report": 1,
"role": "System Manager",
"select": 1,
"share": 1,
"submit": 1,
"write": 1
},
{

View File

@@ -289,6 +289,7 @@
"read_only": 1
},
{
"allow_on_submit": 1,
"fieldname": "project",
"fieldtype": "Link",
"hide_days": 1,
@@ -354,6 +355,7 @@
"reqd": 1
},
{
"allow_on_submit": 1,
"fieldname": "cost_center",
"fieldtype": "Link",
"hide_days": 1,
@@ -785,6 +787,7 @@
"hide_days": 1,
"hide_seconds": 1,
"label": "Time Sheets",
"no_copy": 1,
"options": "Sales Invoice Timesheet",
"print_hide": 1
},
@@ -2038,7 +2041,7 @@
{
"fieldname": "contact_and_address_tab",
"fieldtype": "Tab Break",
"label": "Contact & Address"
"label": "Address & Contact"
},
{
"fieldname": "payments_tab",
@@ -2185,7 +2188,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2024-03-22 17:50:34.395602",
"modified": "2024-06-07 16:49:32.458402",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",
@@ -2240,4 +2243,4 @@
"title_field": "title",
"track_changes": 1,
"track_seen": 1
}
}

View File

@@ -55,13 +55,9 @@ class SalesInvoice(SellingController):
from erpnext.accounts.doctype.payment_schedule.payment_schedule import PaymentSchedule
from erpnext.accounts.doctype.pricing_rule_detail.pricing_rule_detail import PricingRuleDetail
from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import (
SalesInvoiceAdvance,
)
from erpnext.accounts.doctype.sales_invoice_advance.sales_invoice_advance import SalesInvoiceAdvance
from erpnext.accounts.doctype.sales_invoice_item.sales_invoice_item import SalesInvoiceItem
from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import (
SalesInvoicePayment,
)
from erpnext.accounts.doctype.sales_invoice_payment.sales_invoice_payment import SalesInvoicePayment
from erpnext.accounts.doctype.sales_invoice_timesheet.sales_invoice_timesheet import (
SalesInvoiceTimesheet,
)
@@ -392,6 +388,9 @@ class SalesInvoice(SellingController):
validate_account_head(item.idx, item.income_account, self.company, "Income")
def set_tax_withholding(self):
if self.get("is_opening") == "Yes":
return
tax_withholding_details = get_party_tax_withholding_details(self)
if not tax_withholding_details:
@@ -451,6 +450,7 @@ class SalesInvoice(SellingController):
if not self.get(table_name):
continue
self.make_bundle_for_sales_purchase_return(table_name)
self.make_bundle_using_old_serial_batch_fields(table_name)
self.update_stock_ledger()
@@ -2678,6 +2678,10 @@ def create_dunning(source_name, target_doc=None, ignore_permissions=False):
target.closing_text = letter_text.get("closing_text")
target.language = letter_text.get("language")
# update outstanding
if source.payment_schedule and len(source.payment_schedule) == 1:
target.overdue_payments[0].outstanding = source.get("outstanding_amount")
target.validate()
return get_mapped_doc(

View File

@@ -2,6 +2,7 @@
# License: GNU General Public License v3. See license.txt
import copy
import json
import frappe
from frappe.model.dynamic_links import get_dynamic_link_map
@@ -1766,6 +1767,49 @@ class TestSalesInvoice(FrappeTestCase):
self.assertTrue(gle)
def test_gle_in_transaction_currency(self):
# create multi currency sales invoice with 2 items with same income account
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=50,
do_not_submit=True,
)
# add 2nd item with same income account
si.append(
"items",
{
"item_code": "_Test Item",
"qty": 1,
"rate": 80,
"income_account": "Sales - _TC",
"cost_center": "_Test Cost Center - _TC",
},
)
si.submit()
gl_entries = frappe.db.sql(
"""select transaction_currency, transaction_exchange_rate,
debit_in_transaction_currency, credit_in_transaction_currency
from `tabGL Entry`
where voucher_type='Sales Invoice' and voucher_no=%s and account = 'Sales - _TC'
order by account asc""",
si.name,
as_dict=1,
)
expected_gle = {
"transaction_currency": "USD",
"transaction_exchange_rate": 50,
"debit_in_transaction_currency": 0,
"credit_in_transaction_currency": 180,
}
for gle in gl_entries:
for field in expected_gle:
self.assertEqual(expected_gle[field], gle[field])
def test_invoice_exchange_rate(self):
si = create_sales_invoice(
customer="_Test Customer USD",
@@ -3677,9 +3721,9 @@ class TestSalesInvoice(FrappeTestCase):
map_docs(
method="erpnext.stock.doctype.delivery_note.delivery_note.make_sales_invoice",
source_names=frappe.json.dumps([dn1.name, dn2.name]),
source_names=json.dumps([dn1.name, dn2.name]),
target_doc=si,
args=frappe.json.dumps({"customer": dn1.customer, "merge_taxes": 1, "filtered_children": []}),
args=json.dumps({"customer": dn1.customer, "merge_taxes": 1, "filtered_children": []}),
)
si.save().submit()

View File

@@ -870,7 +870,8 @@
"label": "Purchase Order",
"options": "Purchase Order",
"print_hide": 1,
"read_only": 1
"read_only": 1,
"search_index": 1
},
{
"fieldname": "column_break_92",
@@ -926,7 +927,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2024-02-25 15:56:44.828634",
"modified": "2024-05-23 16:36:18.970862",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",
@@ -936,4 +937,4 @@
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}
}

View File

@@ -112,11 +112,7 @@ class Subscription(Document):
"""
_current_invoice_start = None
if (
self.is_new_subscription()
and self.trial_period_end
and getdate(self.trial_period_end) > getdate(self.start_date)
):
if self.trial_period_end and getdate(self.trial_period_end) > getdate(self.start_date):
_current_invoice_start = add_days(self.trial_period_end, 1)
elif self.trial_period_start and self.is_trialling():
_current_invoice_start = self.trial_period_start
@@ -143,7 +139,7 @@ class Subscription(Document):
else:
billing_cycle_info = self.get_billing_cycle_data()
if billing_cycle_info:
if self.is_new_subscription() and getdate(self.start_date) < getdate(date):
if getdate(self.start_date) < getdate(date):
_current_invoice_end = add_to_date(self.start_date, **billing_cycle_info)
# For cases where trial period is for an entire billing interval
@@ -234,14 +230,14 @@ class Subscription(Document):
self.cancelation_date = getdate(posting_date) if self.status == "Cancelled" else None
elif self.current_invoice_is_past_due() and not self.is_past_grace_period():
self.status = "Past Due Date"
elif not self.has_outstanding_invoice() or self.is_new_subscription():
elif not self.has_outstanding_invoice():
self.status = "Active"
def is_trialling(self) -> bool:
"""
Returns `True` if the `Subscription` is in trial period.
"""
return not self.period_has_passed(self.trial_period_end) and self.is_new_subscription()
return not self.period_has_passed(self.trial_period_end)
@staticmethod
def period_has_passed(
@@ -288,14 +284,6 @@ class Subscription(Document):
def invoice_document_type(self) -> str:
return "Sales Invoice" if self.party_type == "Customer" else "Purchase Invoice"
def is_new_subscription(self) -> bool:
"""
Returns `True` if `Subscription` has never generated an invoice
"""
return self.is_new() or not frappe.db.exists(
{"doctype": self.invoice_document_type, "subscription": self.name}
)
def validate(self) -> None:
self.validate_trial_period()
self.validate_plans_billing_cycle(self.get_billing_cycle_and_interval())
@@ -604,7 +592,7 @@ class Subscription(Document):
return False
if self.generate_invoice_at == "Beginning of the current subscription period" and (
getdate(posting_date) == getdate(self.current_invoice_start) or self.is_new_subscription()
getdate(posting_date) == getdate(self.current_invoice_start)
):
return True
elif self.generate_invoice_at == "Days before the current subscription period" and (

View File

@@ -445,11 +445,11 @@ class TestSubscription(FrappeTestCase):
# Process subscription and create first invoice
# Subscription status will be unpaid since due date has already passed
subscription.process()
subscription.process(posting_date="2018-01-01")
self.assertEqual(len(subscription.invoices), 1)
self.assertEqual(subscription.status, "Unpaid")
subscription.process()
subscription.process(posting_date="2018-04-01")
self.assertEqual(len(subscription.invoices), 1)
def test_multi_currency_subscription(self):
@@ -462,7 +462,7 @@ class TestSubscription(FrappeTestCase):
party=party,
)
subscription.process()
subscription.process(posting_date="2018-01-01")
self.assertEqual(len(subscription.invoices), 1)
self.assertEqual(subscription.status, "Unpaid")

View File

@@ -21,7 +21,7 @@
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
@@ -53,7 +53,7 @@
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_user_permissions": 1,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
@@ -87,7 +87,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
"modified": "2018-04-13 18:44:25.055382",
"modified": "2024-04-30 10:26:48.21829",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Withholding Account",

View File

@@ -9,6 +9,8 @@ from frappe.query_builder import Criterion
from frappe.query_builder.functions import Abs, Sum
from frappe.utils import cint, flt, getdate
from erpnext.controllers.accounts_controller import validate_account_head
class TaxWithholdingCategory(Document):
# begin: auto-generated types
@@ -53,6 +55,7 @@ class TaxWithholdingCategory(Document):
if d.get("account") in existing_accounts:
frappe.throw(_("Account {0} added multiple times").format(frappe.bold(d.get("account"))))
validate_account_head(d.idx, d.get("account"), d.get("company"))
existing_accounts.append(d.get("account"))
def validate_thresholds(self):
@@ -282,6 +285,14 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
if taxable_vouchers:
tax_deducted = get_deducted_tax(taxable_vouchers, tax_details)
# If advance is outside the current tax withholding period (usually a fiscal year), `get_deducted_tax` won't fetch it.
# updating `tax_deducted` with correct advance tax value (from current and previous previous withholding periods), will allow the
# rest of the below logic to function properly
# ---FY 2023-------------||---------------------FY 2024-----------------------||--
# ---Advance-------------||---------Inv_1--------Inv_2------------------------||--
if tax_deducted_on_advances:
tax_deducted += get_advance_tax_across_fiscal_year(tax_deducted_on_advances, tax_details)
tax_amount = 0
if party_type == "Supplier":
@@ -418,7 +429,7 @@ def get_taxes_deducted_on_advances_allocated(inv, tax_details):
frappe.qb.from_(at)
.inner_join(pe)
.on(pe.name == at.parent)
.select(at.parent, at.name, at.tax_amount, at.allocated_amount)
.select(pe.posting_date, at.parent, at.name, at.tax_amount, at.allocated_amount)
.where(pe.tax_withholding_category == tax_details.get("tax_withholding_category"))
.where(at.parent.isin(advances))
.where(at.account_head == tax_details.account_head)
@@ -443,6 +454,16 @@ def get_deducted_tax(taxable_vouchers, tax_details):
return sum(entries)
def get_advance_tax_across_fiscal_year(tax_deducted_on_advances, tax_details):
"""
Only applies for Taxes deducted on Advance Payments
"""
advance_tax_from_across_fiscal_year = sum(
[adv.tax_amount for adv in tax_deducted_on_advances if adv.posting_date < tax_details.from_date]
)
return advance_tax_from_across_fiscal_year
def get_tds_amount(ldc, parties, inv, tax_details, vouchers):
tds_amount = 0
invoice_filters = {"name": ("in", vouchers), "docstatus": 1, "apply_tds": 1}

View File

@@ -1,18 +1,22 @@
# Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import datetime
import unittest
import frappe
from frappe.custom.doctype.custom_field.custom_field import create_custom_fields
from frappe.utils import today
from frappe.tests.utils import FrappeTestCase, change_settings
from frappe.utils import add_days, today
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
from erpnext.accounts.utils import get_fiscal_year
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
test_dependencies = ["Supplier Group", "Customer Group"]
class TestTaxWithholdingCategory(unittest.TestCase):
class TestTaxWithholdingCategory(FrappeTestCase):
@classmethod
def setUpClass(self):
# create relevant supplier, etc
@@ -21,7 +25,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
make_pan_no_field()
def tearDown(self):
cancel_invoices()
frappe.db.rollback()
def test_cumulative_threshold_tds(self):
frappe.db.set_value(
@@ -317,8 +321,6 @@ class TestTaxWithholdingCategory(unittest.TestCase):
d.cancel()
def test_tds_deduction_for_po_via_payment_entry(self):
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry
frappe.db.set_value(
"Supplier", "Test TDS Supplier8", "tax_withholding_category", "Cumulative Threshold TDS"
)
@@ -485,6 +487,133 @@ class TestTaxWithholdingCategory(unittest.TestCase):
pi2.cancel()
pi3.cancel()
def set_previous_fy_and_tax_category(self):
test_company = "_Test Company"
category = "Cumulative Threshold TDS"
def add_company_to_fy(fy, company):
if not [x.company for x in fy.companies if x.company == company]:
fy.append("companies", {"company": company})
fy.save()
# setup previous fiscal year
fiscal_year = get_fiscal_year(today(), company=test_company)
if prev_fiscal_year := get_fiscal_year(add_days(fiscal_year[1], -10)):
self.prev_fy = frappe.get_doc("Fiscal Year", prev_fiscal_year[0])
add_company_to_fy(self.prev_fy, test_company)
else:
# make previous fiscal year
start = datetime.date(fiscal_year[1].year - 1, fiscal_year[1].month, fiscal_year[1].day)
end = datetime.date(fiscal_year[2].year - 1, fiscal_year[2].month, fiscal_year[2].day)
self.prev_fy = frappe.get_doc(
{
"doctype": "Fiscal Year",
"year_start_date": start,
"year_end_date": end,
"companies": [{"company": test_company}],
}
)
self.prev_fy.save()
# setup tax withholding category for previous fiscal year
cat = frappe.get_doc("Tax Withholding Category", category)
cat.append(
"rates",
{
"from_date": self.prev_fy.year_start_date,
"to_date": self.prev_fy.year_end_date,
"tax_withholding_rate": 10,
"single_threshold": 0,
"cumulative_threshold": 30000,
},
)
cat.save()
def test_tds_across_fiscal_year(self):
"""
Advance TDS on previous fiscal year should be properly allocated on Invoices in upcoming fiscal year
--||-----FY 2023-----||-----FY 2024-----||--
--||-----Advance-----||---Inv1---Inv2---||--
"""
self.set_previous_fy_and_tax_category()
supplier = "Test TDS Supplier"
# Cumulative threshold 30000 and tax rate 10%
category = "Cumulative Threshold TDS"
frappe.db.set_value(
"Supplier",
supplier,
{
"tax_withholding_category": category,
"pan": "ABCTY1234D",
},
)
po_and_advance_posting_date = add_days(self.prev_fy.year_end_date, -10)
po = create_purchase_order(supplier=supplier, qty=10, rate=10000)
po.transaction_date = po_and_advance_posting_date
po.taxes = []
po.apply_tds = False
po.tax_withholding_category = None
po.save().submit()
# Partial advance
payment = get_payment_entry(po.doctype, po.name)
payment.posting_date = po_and_advance_posting_date
payment.paid_amount = 60000
payment.apply_tax_withholding_amount = 1
payment.tax_withholding_category = category
payment.references = []
payment.taxes = []
payment.save().submit()
self.assertEqual(len(payment.taxes), 1)
self.assertEqual(payment.taxes[0].tax_amount, 6000)
# Multiple partial invoices
payment.reload()
pi1 = make_purchase_invoice(source_name=po.name)
pi1.apply_tds = True
pi1.tax_withholding_category = category
pi1.items[0].qty = 3
pi1.items[0].rate = 10000
advances = pi1.get_advance_entries()
pi1.append(
"advances",
{
"reference_type": advances[0].reference_type,
"reference_name": advances[0].reference_name,
"advance_amount": advances[0].amount,
"allocated_amount": 30000,
},
)
pi1.save().submit()
pi1.reload()
payment.reload()
self.assertEqual(pi1.taxes, [])
self.assertEqual(payment.taxes[0].tax_amount, 6000)
self.assertEqual(payment.taxes[0].allocated_amount, 3000)
pi2 = make_purchase_invoice(source_name=po.name)
pi2.apply_tds = True
pi2.tax_withholding_category = category
pi2.items[0].qty = 3
pi2.items[0].rate = 10000
advances = pi2.get_advance_entries()
pi2.append(
"advances",
{
"reference_type": advances[0].reference_type,
"reference_name": advances[0].reference_name,
"advance_amount": advances[0].amount,
"allocated_amount": 30000,
},
)
pi2.save().submit()
pi2.reload()
payment.reload()
self.assertEqual(pi2.taxes, [])
self.assertEqual(payment.taxes[0].tax_amount, 6000)
self.assertEqual(payment.taxes[0].allocated_amount, 6000)
def cancel_invoices():
purchase_invoices = frappe.get_all(

View File

@@ -1,6 +1,8 @@
# Copyright (c) 2023, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import json
import frappe
from frappe import _, qb
from frappe.model.document import Document
@@ -161,7 +163,7 @@ def get_linked_payments_for_doc(
@frappe.whitelist()
def create_unreconcile_doc_for_selection(selections=None):
if selections:
selections = frappe.json.loads(selections)
selections = json.loads(selections)
# assuming each row is a unique voucher
for row in selections:
unrecon = frappe.new_doc("Unreconcile Payment")

View File

@@ -238,10 +238,16 @@ def merge_similar_entries(gl_map, precision=None):
same_head.debit_in_account_currency = flt(same_head.debit_in_account_currency) + flt(
entry.debit_in_account_currency
)
same_head.debit_in_transaction_currency = flt(same_head.debit_in_transaction_currency) + flt(
entry.debit_in_transaction_currency
)
same_head.credit = flt(same_head.credit) + flt(entry.credit)
same_head.credit_in_account_currency = flt(same_head.credit_in_account_currency) + flt(
entry.credit_in_account_currency
)
same_head.credit_in_transaction_currency = flt(same_head.credit_in_transaction_currency) + flt(
entry.credit_in_transaction_currency
)
else:
merged_gl_map.append(entry)
@@ -571,6 +577,8 @@ def make_reverse_gl_entries(
and make reverse gl entries by swapping debit and credit
"""
immutable_ledger_enabled = is_immutable_ledger_enabled()
if not gl_entries:
gl_entry = frappe.qb.DocType("GL Entry")
gl_entries = (
@@ -602,7 +610,6 @@ def make_reverse_gl_entries(
for x in gl_entries:
query = (
frappe.qb.update(gle)
.set(gle.is_cancelled, True)
.set(gle.modified, now())
.set(gle.modified_by, frappe.session.user)
.where(
@@ -617,9 +624,14 @@ def make_reverse_gl_entries(
& (gle.voucher_detail_no == x.voucher_detail_no)
)
)
if not immutable_ledger_enabled:
query = query.set(gle.is_cancelled, True)
query.run()
else:
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
if not immutable_ledger_enabled:
set_as_cancel(gl_entries[0]["voucher_type"], gl_entries[0]["voucher_no"])
for entry in gl_entries:
new_gle = copy.deepcopy(entry)
@@ -638,6 +650,10 @@ def make_reverse_gl_entries(
new_gle["remarks"] = "On cancellation of " + new_gle["voucher_no"]
new_gle["is_cancelled"] = 1
if immutable_ledger_enabled:
new_gle["is_cancelled"] = 0
new_gle["posting_date"] = frappe.form_dict.get("posting_date") or getdate()
if new_gle["debit"] or new_gle["credit"]:
make_entry(new_gle, adv_adj, "Yes")
@@ -730,3 +746,7 @@ def validate_allowed_dimensions(gl_entry, dimension_filter_map):
),
InvalidAccountDimensionError,
)
def is_immutable_ledger_enabled():
return frappe.db.get_single_value("Accounts Settings", "enable_immutable_ledger")

View File

@@ -188,7 +188,9 @@ def set_address_details(
*,
ignore_permissions=False,
):
billing_address_field = "customer_address" if party_type == "Lead" else party_type.lower() + "_address"
billing_address_field = (
"customer_address" if party_type in ["Lead", "Prospect"] else party_type.lower() + "_address"
)
party_details[billing_address_field] = party_address or get_default_address(party_type, party.name)
if doctype:
party_details.update(
@@ -751,52 +753,6 @@ def validate_party_frozen_disabled(party_type, party_name):
frappe.msgprint(_("{0} {1} is not active").format(party_type, party_name), alert=True)
def get_timeline_data(doctype, name):
"""returns timeline data for the past one year"""
from frappe.desk.form.load import get_communication_data
out = {}
after = add_years(None, -1).strftime("%Y-%m-%d")
data = get_communication_data(
doctype,
name,
after=after,
group_by="group by communication_date",
fields="C.communication_date as communication_date, count(C.name)",
as_dict=False,
)
# fetch and append data from Activity Log
activity_log = frappe.qb.DocType("Activity Log")
data += (
frappe.qb.from_(activity_log)
.select(activity_log.communication_date, Count(activity_log.name))
.where(
(
((activity_log.reference_doctype == doctype) & (activity_log.reference_name == name))
| ((activity_log.timeline_doctype == doctype) & (activity_log.timeline_name == name))
| (
(activity_log.reference_doctype.isin(["Quotation", "Opportunity"]))
& (activity_log.timeline_name == name)
)
)
& (activity_log.status != "Success")
& (activity_log.creation > after)
)
.groupby(activity_log.communication_date)
.orderby(activity_log.communication_date, order=frappe.qb.desc)
).run()
timeline_items = dict(data)
for date, count in timeline_items.items():
timestamp = get_timestamp(date)
out.update({timestamp: count})
return out
def get_dashboard_info(party_type, party, loyalty_program=None):
current_fiscal_year = get_fiscal_year(nowdate(), as_dict=True)

View File

@@ -49,7 +49,6 @@ def get_conditions(filters):
if filters.account_type:
conditions["account_type"] = filters.account_type
return conditions
if filters.company:
conditions["company"] = filters.company

View File

@@ -501,8 +501,9 @@ class ReceivablePayableReport:
# Deduct that from paid amount pre allocation
row.paid -= flt(payment_terms_details[0].total_advance)
# If no or single payment terms, no need to split the row
if len(payment_terms_details) <= 1:
# If single payment terms, no need to split the row
if len(payment_terms_details) == 1 and payment_terms_details[0].payment_term:
self.append_payment_term(row, payment_terms_details[0], original_row)
return
for d in payment_terms_details:
@@ -1027,20 +1028,6 @@ class ReceivablePayableReport:
fieldtype="Link",
options="Contact",
)
if self.filters.party_type == "Customer":
self.add_column(
_("Customer Name"),
fieldname="customer_name",
fieldtype="Link",
options="Customer",
)
elif self.filters.party_type == "Supplier":
self.add_column(
_("Supplier Name"),
fieldname="supplier_name",
fieldtype="Link",
options="Supplier",
)
self.add_column(label=_("Cost Center"), fieldname="cost_center", fieldtype="Data")
self.add_column(label=_("Voucher Type"), fieldname="voucher_type", fieldtype="Data")

View File

@@ -4,6 +4,7 @@
import frappe
from frappe import _
from frappe.query_builder import DocType
from frappe.utils import cstr, flt
@@ -75,11 +76,24 @@ 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.get(
"opening_accumulated_depreciation"
)
AssetDepreciationSchedule = DocType("Asset Depreciation Schedule")
DepreciationSchedule = DocType("Depreciation Schedule")
query = (
frappe.qb.from_(DepreciationSchedule)
.join(AssetDepreciationSchedule)
.on(DepreciationSchedule.parent == AssetDepreciationSchedule.name)
.select(DepreciationSchedule.accumulated_depreciation_amount)
.where(
(AssetDepreciationSchedule.asset == d.against_voucher)
& (DepreciationSchedule.parenttype == "Asset Depreciation Schedule")
& (DepreciationSchedule.schedule_date == d.posting_date)
)
).run(as_dict=True)
asset_data.accumulated_depreciation_amount = query[0]["accumulated_depreciation_amount"]
else:
asset_data.accumulated_depreciation_amount += d.debit
asset_data.opening_accumulated_depreciation = asset_data.accumulated_depreciation_amount - d.debit
row = frappe._dict(asset_data)
row.update(

View File

@@ -69,48 +69,50 @@ def get_asset_categories_for_grouped_by_category(filters):
condition = ""
if filters.get("asset_category"):
condition += " and asset_category = %(asset_category)s"
# nosemgrep
return frappe.db.sql(
f"""
SELECT asset_category,
ifnull(sum(case when purchase_date < %(from_date)s then
case when ifnull(disposal_date, 0) = 0 or disposal_date >= %(from_date)s then
gross_purchase_amount
SELECT a.asset_category,
ifnull(sum(case when a.purchase_date < %(from_date)s then
case when ifnull(a.disposal_date, 0) = 0 or a.disposal_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_as_on_from_date,
ifnull(sum(case when purchase_date >= %(from_date)s then
gross_purchase_amount
ifnull(sum(case when a.purchase_date >= %(from_date)s then
a.gross_purchase_amount
else
0
end), 0) as cost_of_new_purchase,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Sold" then
gross_purchase_amount
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Sold" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_sold_asset,
ifnull(sum(case when ifnull(disposal_date, 0) != 0
and disposal_date >= %(from_date)s
and disposal_date <= %(to_date)s then
case when status = "Scrapped" then
gross_purchase_amount
ifnull(sum(case when ifnull(a.disposal_date, 0) != 0
and a.disposal_date >= %(from_date)s
and a.disposal_date <= %(to_date)s then
case when a.status = "Scrapped" then
a.gross_purchase_amount
else
0
end
else
0
end), 0) as cost_of_scrapped_asset
from `tabAsset`
from `tabAsset` a
where docstatus=1 and company=%(company)s and purchase_date <= %(to_date)s {condition}
group by asset_category
and not exists(select name from `tabAsset Capitalization Asset Item` where asset = a.name)
group by a.asset_category
""",
{
"to_date": filters.to_date,

View File

@@ -58,9 +58,9 @@ class Deferred_Item:
For a given GL/Journal posting, get balance based on item type
"""
if self.type == "Deferred Sale Item":
return entry.debit - entry.credit
return flt(entry.debit) - flt(entry.credit)
elif self.type == "Deferred Purchase Item":
return -(entry.credit - entry.debit)
return -(flt(entry.credit) - flt(entry.debit))
return 0
def get_item_total(self):
@@ -147,7 +147,7 @@ class Deferred_Item:
actual = 0
for posting in self.gle_entries:
# if period.from_date <= posting.posting_date <= period.to_date:
if period.from_date <= posting.gle_posting_date <= period.to_date:
if period.from_date <= getdate(posting.gle_posting_date) <= period.to_date:
period_sum += self.get_amount(posting)
if posting.posted == "posted":
actual += self.get_amount(posting)
@@ -285,7 +285,7 @@ class Deferred_Revenue_and_Expense_Report:
qb.from_(inv_item)
.join(inv)
.on(inv.name == inv_item.parent)
.join(gle)
.left_join(gle)
.on((inv_item.name == gle.voucher_detail_no) & (deferred_account_field == gle.account))
.select(
inv.name.as_("doc"),

View File

@@ -279,3 +279,79 @@ class TestDeferredRevenueAndExpense(FrappeTestCase, AccountsTestMixin):
{"key": "aug_2021", "total": 0, "actual": 0},
]
self.assertEqual(report.period_total, expected)
@change_settings(
"Accounts Settings",
{"book_deferred_entries_based_on": "Months", "book_deferred_entries_via_journal_entry": 0},
)
def test_zero_amount(self):
self.create_item("_Test Office Desk", 0, self.warehouse, self.company)
item = frappe.get_doc("Item", self.item)
item.enable_deferred_expense = 1
item.item_defaults[0].deferred_expense_account = self.deferred_expense_account
item.no_of_months_exp = 12
item.save()
pi = make_purchase_invoice(
item=self.item,
company=self.company,
supplier=self.supplier,
is_return=False,
update_stock=False,
posting_date=frappe.utils.datetime.date(2021, 12, 30),
parent_cost_center=self.cost_center,
cost_center=self.cost_center,
do_not_save=True,
rate=3910,
price_list_rate=3910,
warehouse=self.warehouse,
qty=1,
)
pi.set_posting_time = True
pi.items[0].enable_deferred_expense = 1
pi.items[0].service_start_date = "2021-12-30"
pi.items[0].service_end_date = "2022-12-30"
pi.items[0].deferred_expense_account = self.deferred_expense_account
pi.items[0].expense_account = self.expense_account
pi.save()
pi.submit()
pda = frappe.get_doc(
doctype="Process Deferred Accounting",
posting_date=nowdate(),
start_date="2022-01-01",
end_date="2022-01-31",
type="Expense",
company=self.company,
)
pda.insert()
pda.submit()
# execute report
fiscal_year = frappe.get_doc("Fiscal Year", get_fiscal_year(date="2022-01-31"))
self.filters = frappe._dict(
{
"company": self.company,
"filter_based_on": "Date Range",
"period_start_date": "2022-01-01",
"period_end_date": "2022-01-31",
"from_fiscal_year": fiscal_year.year,
"to_fiscal_year": fiscal_year.year,
"periodicity": "Monthly",
"type": "Expense",
"with_upcoming_postings": False,
}
)
report = Deferred_Revenue_and_Expense_Report(filters=self.filters)
report.run()
# fetch the invoice from deferred invoices list
inv = [d for d in report.deferred_invoices if d.name == pi.name]
# make sure the list isn't empty
self.assertTrue(inv)
# calculate the total deferred expense for the period
inv = inv[0].calculate_invoice_revenue_expense_for_period()
deferred_exp = sum([inv[idx].actual for idx in range(len(report.period_list))])
# make sure the total deferred expense is greater than 0
self.assertLess(deferred_exp, 0)

View File

@@ -219,7 +219,8 @@ def get_conditions(filters):
if filters.get("account"):
filters.account = get_accounts_with_children(filters.account)
conditions.append("account in %(account)s")
if filters.account:
conditions.append("account in %(account)s")
if filters.get("cost_center"):
filters.cost_center = get_cost_centers_with_children(filters.cost_center)
@@ -329,7 +330,7 @@ def get_accounts_with_children(accounts):
else:
frappe.throw(_("Account: {0} does not exist").format(d))
return list(set(all_accounts))
return list(set(all_accounts)) if all_accounts else None
def get_data_with_opening_closing(filters, account_details, accounting_dimensions, gl_entries):
@@ -420,6 +421,8 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
if filters.get("show_net_values_in_party_account"):
account_type_map = get_account_type_map(filters.get("company"))
immutable_ledger = frappe.db.get_single_value("Accounts Settings", "enable_immutable_ledger")
def update_value_in_dict(data, key, gle):
data[key].debit += gle.debit
data[key].credit += gle.credit
@@ -481,12 +484,17 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
elif group_by_voucher_consolidated:
keylist = [
gle.get("posting_date"),
gle.get("voucher_type"),
gle.get("voucher_no"),
gle.get("account"),
gle.get("party_type"),
gle.get("party"),
]
if immutable_ledger:
keylist.append(gle.get("creation"))
if filters.get("include_dimensions"):
for dim in accounting_dimensions:
keylist.append(gle.get(dim))

View File

@@ -720,20 +720,22 @@ class GrossProfitGenerator:
frappe.qb.from_(purchase_invoice_item)
.inner_join(purchase_invoice)
.on(purchase_invoice.name == purchase_invoice_item.parent)
.select(purchase_invoice_item.base_rate / purchase_invoice_item.conversion_factor)
.select(
purchase_invoice.name,
purchase_invoice_item.base_rate / purchase_invoice_item.conversion_factor,
)
.where(purchase_invoice.docstatus == 1)
.where(purchase_invoice.posting_date <= self.filters.to_date)
.where(purchase_invoice_item.item_code == item_code)
)
if row.project:
query.where(purchase_invoice_item.project == row.project)
query = query.where(purchase_invoice_item.project == row.project)
if row.cost_center:
query.where(purchase_invoice_item.cost_center == row.cost_center)
query = query.where(purchase_invoice_item.cost_center == row.cost_center)
query.orderby(purchase_invoice.posting_date, order=frappe.qb.desc)
query.limit(1)
query = query.orderby(purchase_invoice.posting_date, order=frappe.qb.desc).limit(1)
last_purchase_rate = query.run()
return flt(last_purchase_rate[0][0]) if last_purchase_rate else 0

View File

@@ -5,14 +5,15 @@
import frappe
from frappe import _
from frappe.utils import flt
from pypika import Order
import erpnext
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import (
add_sub_total_row,
add_total_row,
apply_group_by_conditions,
get_grand_total,
get_group_by_and_display_fields,
get_group_by_conditions,
get_tax_accounts,
)
from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns
@@ -29,7 +30,7 @@ def _execute(filters=None, additional_table_columns=None):
company_currency = erpnext.get_company_currency(filters.company)
item_list = get_items(filters, get_query_columns(additional_table_columns))
item_list = get_items(filters, additional_table_columns)
aii_account_map = get_aii_accounts()
if item_list:
itemised_tax, tax_columns = get_tax_accounts(
@@ -287,59 +288,90 @@ def get_columns(additional_table_columns, filters):
return columns
def get_conditions(filters):
conditions = ""
def apply_conditions(query, pi, pii, filters):
for opts in ("company", "supplier", "mode_of_payment"):
if filters.get(opts):
query = query.where(pi[opts] == filters[opts])
for opts in (
("company", " and `tabPurchase Invoice`.company=%(company)s"),
("supplier", " and `tabPurchase Invoice`.supplier = %(supplier)s"),
("item_code", " and `tabPurchase Invoice Item`.item_code = %(item_code)s"),
("from_date", " and `tabPurchase Invoice`.posting_date>=%(from_date)s"),
("to_date", " and `tabPurchase Invoice`.posting_date<=%(to_date)s"),
("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s"),
("item_group", " and ifnull(`tabPurchase Invoice Item`.item_group, '') = %(item_group)s"),
):
if filters.get(opts[0]):
conditions += opts[1]
if filters.get("from_date"):
query = query.where(pi.posting_date >= filters.get("from_date"))
if filters.get("to_date"):
query = query.where(pi.posting_date <= filters.get("to_date"))
if filters.get("item_code"):
query = query.where(pii.item_code == filters.get("item_code"))
if filters.get("item_group"):
query = query.where(pii.item_group == filters.get("item_group"))
if not filters.get("group_by"):
conditions += (
"ORDER BY `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc"
)
query = query.orderby(pi.posting_date, order=Order.desc)
query = query.orderby(pii.item_group, order=Order.desc)
else:
conditions += get_group_by_conditions(filters, "Purchase Invoice")
query = apply_group_by_conditions(filters, "Purchase Invoice")
return conditions
return query
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(
f"""
select
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total,
`tabPurchase Invoice`.unrealized_profit_loss_account,
`tabPurchase Invoice Item`.`item_code`, `tabPurchase Invoice Item`.description,
`tabPurchase Invoice Item`.`item_name` as pi_item_name, `tabPurchase Invoice Item`.`item_group` as pi_item_group,
`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_amount`,
`tabPurchase Invoice`.`supplier_name`, `tabPurchase Invoice`.`mode_of_payment` {additional_query_columns}
from `tabPurchase Invoice`, `tabPurchase Invoice Item`, `tabItem`
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
`tabItem`.name = `tabPurchase Invoice Item`.`item_code` and
`tabPurchase Invoice`.docstatus = 1 {conditions}
""",
filters,
as_dict=1,
def get_items(filters, additional_table_columns):
pi = frappe.qb.DocType("Purchase Invoice")
pii = frappe.qb.DocType("Purchase Invoice Item")
Item = frappe.qb.DocType("Item")
query = (
frappe.qb.from_(pi)
.join(pii)
.on(pi.name == pii.parent)
.left_join(Item)
.on(pii.item_code == Item.name)
.select(
pii.name,
pii.parent,
pi.posting_date,
pi.credit_to,
pi.company,
pi.supplier,
pi.remarks,
pi.base_net_total,
pi.unrealized_profit_loss_account,
pii.item_code,
pii.description,
pii.item_group,
pii.item_name.as_("pi_item_name"),
pii.item_group.as_("pi_item_group"),
Item.item_name.as_("i_item_name"),
Item.item_group.as_("i_item_group"),
pii.project,
pii.purchase_order,
pii.purchase_receipt,
pii.po_detail,
pii.expense_account,
pii.stock_qty,
pii.stock_uom,
pii.base_net_amount,
pi.supplier_name,
pi.mode_of_payment,
)
.where(pi.docstatus == 1)
)
if filters.get("supplier"):
query = query.where(pi.supplier == filters["supplier"])
if filters.get("company"):
query = query.where(pi.company == filters["company"])
if additional_table_columns:
for column in additional_table_columns:
if column.get("_doctype"):
table = frappe.qb.DocType(column.get("_doctype"))
query = query.select(table[column.get("fieldname")])
else:
query = query.select(pi[column.get("fieldname")])
query = apply_conditions(query, pi, pii, filters)
return query.run(as_dict=True)
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))

View File

@@ -41,6 +41,12 @@ frappe.query_reports["Item-wise Sales Register"] = {
label: __("Warehouse"),
fieldtype: "Link",
options: "Warehouse",
get_query: function () {
const company = frappe.query_report.get_filter_value("company");
return {
filters: { company: company },
};
},
},
{
fieldname: "brand",
@@ -48,6 +54,12 @@ frappe.query_reports["Item-wise Sales Register"] = {
fieldtype: "Link",
options: "Brand",
},
{
fieldname: "item_code",
label: __("Item"),
fieldtype: "Link",
options: "Item",
},
{
fieldname: "item_group",
label: __("Item Group"),

View File

@@ -7,6 +7,7 @@ from frappe import _
from frappe.model.meta import get_field_precision
from frappe.utils import cstr, flt
from frappe.utils.xlsxutils import handle_html
from pypika import Order
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
from erpnext.accounts.report.utils import get_query_columns, get_values_for_columns
@@ -26,7 +27,7 @@ def _execute(filters=None, additional_table_columns=None, additional_conditions=
company_currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency")
item_list = get_items(filters, get_query_columns(additional_table_columns), additional_conditions)
item_list = get_items(filters, additional_table_columns, additional_conditions)
if item_list:
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
@@ -83,9 +84,7 @@ def _execute(filters=None, additional_table_columns=None, additional_conditions=
"company": d.company,
"sales_order": d.sales_order,
"delivery_note": d.delivery_note,
"income_account": d.unrealized_profit_loss_account
if d.is_internal_customer == 1
else d.income_account,
"income_account": get_income_account(d),
"cost_center": d.cost_center,
"stock_qty": d.stock_qty,
"stock_uom": d.stock_uom,
@@ -150,6 +149,15 @@ def _execute(filters=None, additional_table_columns=None, additional_conditions=
return columns, data, None, None, None, skip_total_row
def get_income_account(row):
if row.enable_deferred_revenue:
return row.deferred_revenue_account
elif row.is_internal_customer == 1:
return row.unrealized_profit_loss_account
else:
return row.income_account
def get_columns(additional_table_columns, filters):
columns = []
@@ -333,93 +341,143 @@ def get_columns(additional_table_columns, filters):
return columns
def get_conditions(filters, additional_conditions=None):
conditions = ""
def apply_conditions(query, si, sii, filters, additional_conditions=None):
for opts in ("company", "customer"):
if filters.get(opts):
query = query.where(si[opts] == filters[opts])
for opts in (
("company", " and `tabSales Invoice`.company=%(company)s"),
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s"),
):
if filters.get(opts[0]):
conditions += opts[1]
if filters.get("from_date"):
query = query.where(si.posting_date >= filters.get("from_date"))
if additional_conditions:
conditions += additional_conditions
if filters.get("to_date"):
query = query.where(si.posting_date <= filters.get("to_date"))
if filters.get("mode_of_payment"):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
sales_invoice = frappe.db.get_all(
"Sales Invoice Payment", {"mode_of_payment": filters.get("mode_of_payment")}, pluck="parent"
)
query = query.where(si.name.isin(sales_invoice))
if filters.get("warehouse"):
if frappe.db.get_value("Warehouse", filters.get("warehouse"), "is_group"):
lft, rgt = frappe.db.get_all(
"Warehouse", filters={"name": filters.get("warehouse")}, fields=["lft", "rgt"], as_list=True
)[0]
conditions += f"and ifnull(`tabSales Invoice Item`.warehouse, '') in (select name from `tabWarehouse` where lft > {lft} and rgt < {rgt}) "
warehouses = frappe.db.get_all("Warehouse", {"lft": (">", lft), "rgt": ("<", rgt)}, pluck="name")
query = query.where(sii.warehouse.isin(warehouses))
else:
conditions += """and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s"""
query = query.where(sii.warehouse == filters.get("warehouse"))
if filters.get("brand"):
conditions += """and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s"""
query = query.where(sii.brand == filters.get("brand"))
if filters.get("item_code"):
query = query.where(sii.item_code == filters.get("item_code"))
if filters.get("item_group"):
conditions += """and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s"""
query = query.where(sii.item_group == filters.get("item_group"))
if filters.get("income_account"):
query = query.where(
(sii.income_account == filters.get("income_account"))
| (sii.deferred_revenue_account == filters.get("income_account"))
| (si.unrealized_profit_loss_account == filters.get("income_account"))
)
if not filters.get("group_by"):
conditions += "ORDER BY `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_group desc"
query = query.orderby(si.posting_date, order=Order.desc)
query = query.orderby(sii.item_group, order=Order.desc)
else:
conditions += get_group_by_conditions(filters, "Sales Invoice")
query = apply_group_by_conditions(query, si, sii, filters)
return conditions
for key, value in (additional_conditions or {}).items():
query = query.where(si[key] == value)
return query
def get_group_by_conditions(filters, doctype):
def apply_group_by_conditions(query, si, ii, filters):
if filters.get("group_by") == "Invoice":
return f"ORDER BY `tab{doctype} Item`.parent desc"
query = query.orderby(ii.parent, order=Order.desc)
elif filters.get("group_by") == "Item":
return f"ORDER BY `tab{doctype} Item`.`item_code`"
query = query.orderby(ii.item_code)
elif filters.get("group_by") == "Item Group":
return "ORDER BY `tab{} Item`.{}".format(doctype, frappe.scrub(filters.get("group_by")))
query = query.orderby(ii.item_group)
elif filters.get("group_by") in ("Customer", "Customer Group", "Territory", "Supplier"):
return "ORDER BY `tab{}`.{}".format(doctype, frappe.scrub(filters.get("group_by")))
query = query.orderby(si[frappe.scrub(filters.get("group_by"))])
return query
def get_items(filters, additional_query_columns, additional_conditions=None):
conditions = get_conditions(filters, additional_conditions)
si = frappe.qb.DocType("Sales Invoice")
sii = frappe.qb.DocType("Sales Invoice Item")
item = frappe.qb.DocType("Item")
query = (
frappe.qb.from_(si)
.join(sii)
.on(si.name == sii.parent)
.left_join(item)
.on(sii.item_code == item.name)
.select(
sii.name,
sii.parent,
si.posting_date,
si.debit_to,
si.unrealized_profit_loss_account,
si.is_internal_customer,
si.customer,
si.remarks,
si.territory,
si.company,
si.base_net_total,
sii.project,
sii.item_code,
sii.description,
sii.item_name,
sii.item_group,
sii.item_name.as_("si_item_name"),
sii.item_group.as_("si_item_group"),
item.item_name.as_("i_item_name"),
item.item_group.as_("i_item_group"),
sii.sales_order,
sii.delivery_note,
sii.income_account,
sii.cost_center,
sii.enable_deferred_revenue,
sii.deferred_revenue_account,
sii.stock_qty,
sii.stock_uom,
sii.base_net_rate,
sii.base_net_amount,
si.customer_name,
si.customer_group,
sii.so_detail,
si.update_stock,
sii.uom,
sii.qty,
)
.where(si.docstatus == 1)
)
if additional_query_columns:
additional_query_columns = "," + ",".join(additional_query_columns)
return frappe.db.sql(
"""
select
`tabSales Invoice Item`.name, `tabSales Invoice Item`.parent,
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
`tabSales Invoice`.unrealized_profit_loss_account,
`tabSales Invoice`.is_internal_customer,
`tabSales Invoice`.customer, `tabSales Invoice`.remarks,
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
`tabSales Invoice Item`.project,
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.description,
`tabSales Invoice Item`.`item_name`, `tabSales Invoice Item`.`item_group`,
`tabSales Invoice Item`.`item_name` as si_item_name, `tabSales Invoice Item`.`item_group` as si_item_group,
`tabItem`.`item_name` as i_item_name, `tabItem`.`item_group` as i_item_group,
`tabSales Invoice Item`.sales_order, `tabSales Invoice Item`.delivery_note,
`tabSales Invoice Item`.income_account, `tabSales Invoice Item`.cost_center,
`tabSales Invoice Item`.stock_qty, `tabSales Invoice Item`.stock_uom,
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount,
`tabSales Invoice`.customer_name, `tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
`tabSales Invoice`.update_stock, `tabSales Invoice Item`.uom, `tabSales Invoice Item`.qty {}
from `tabSales Invoice`, `tabSales Invoice Item`, `tabItem`
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent and
`tabItem`.name = `tabSales Invoice Item`.`item_code` and
`tabSales Invoice`.docstatus = 1 {}
""".format(additional_query_columns, conditions),
filters,
as_dict=1,
) # nosec
for column in additional_query_columns:
if column.get("_doctype"):
table = frappe.qb.DocType(column.get("_doctype"))
query = query.select(table[column.get("fieldname")])
else:
query = query.select(si[column.get("fieldname")])
if filters.get("customer"):
query = query.where(si.customer == filters["customer"])
if filters.get("customer_group"):
query = query.where(si.customer_group == filters["customer_group"])
query = apply_conditions(query, si, sii, filters, additional_conditions)
return query.run(as_dict=True)
def get_delivery_notes_against_sales_order(item_list):
@@ -427,16 +485,14 @@ def get_delivery_notes_against_sales_order(item_list):
so_item_rows = list(set([d.so_detail for d in item_list]))
if so_item_rows:
delivery_notes = frappe.db.sql(
"""
select parent, so_detail
from `tabDelivery Note Item`
where docstatus=1 and so_detail in (%s)
group by so_detail, parent
"""
% (", ".join(["%s"] * len(so_item_rows))),
tuple(so_item_rows),
as_dict=1,
dn_item = frappe.qb.DocType("Delivery Note Item")
delivery_notes = (
frappe.qb.from_(dn_item)
.select(dn_item.parent, dn_item.so_detail)
.where(dn_item.docstatus == 1)
.where(dn_item.so_detail.isin(so_item_rows))
.groupby(dn_item.so_detail, dn_item.parent)
.run(as_dict=True)
)
for dn in delivery_notes:
@@ -446,15 +502,16 @@ def get_delivery_notes_against_sales_order(item_list):
def get_grand_total(filters, doctype):
return frappe.db.sql(
f""" SELECT
SUM(`tab{doctype}`.base_grand_total)
FROM `tab{doctype}`
WHERE `tab{doctype}`.docstatus = 1
and posting_date between %s and %s
""",
(filters.get("from_date"), filters.get("to_date")),
)[0][0] # nosec
return flt(
frappe.db.get_value(
doctype,
{
"docstatus": 1,
"posting_date": ("between", [filters.get("from_date"), filters.get("to_date")]),
},
"sum(base_grand_total)",
)
)
def get_tax_accounts(

View File

@@ -3,7 +3,9 @@
import frappe
from frappe import _
from frappe import _, qb
from frappe.query_builder import Criterion
from frappe.query_builder.functions import Abs
from frappe.utils import flt, getdate
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
@@ -21,16 +23,12 @@ def execute(filters=None):
data = []
for d in entries:
invoice = invoice_details.get(d.against_voucher) or frappe._dict()
if d.reference_type == "Purchase Invoice":
payment_amount = flt(d.debit) or -1 * flt(d.credit)
else:
payment_amount = flt(d.credit) or -1 * flt(d.debit)
invoice = invoice_details.get(d.against_voucher_no) or frappe._dict()
payment_amount = d.amount
d.update({"range1": 0, "range2": 0, "range3": 0, "range4": 0, "outstanding": payment_amount})
if d.against_voucher:
if d.against_voucher_no:
ReceivablePayableReport(filters).get_ageing_data(invoice.posting_date, d)
row = [
@@ -39,11 +37,10 @@ def execute(filters=None):
d.party_type,
d.party,
d.posting_date,
d.against_voucher,
d.against_voucher_no,
invoice.posting_date,
invoice.due_date,
d.debit,
d.credit,
d.amount,
d.remarks,
d.age,
d.range1,
@@ -111,8 +108,7 @@ def get_columns(filters):
"width": 100,
},
{"fieldname": "due_date", "label": _("Payment Due Date"), "fieldtype": "Date", "width": 100},
{"fieldname": "debit", "label": _("Debit"), "fieldtype": "Currency", "width": 140},
{"fieldname": "credit", "label": _("Credit"), "fieldtype": "Currency", "width": 140},
{"fieldname": "amount", "label": _("Amount"), "fieldtype": "Currency", "width": 140},
{"fieldname": "remarks", "label": _("Remarks"), "fieldtype": "Data", "width": 200},
{"fieldname": "age", "label": _("Age"), "fieldtype": "Int", "width": 50},
{"fieldname": "range1", "label": _("0-30"), "fieldtype": "Currency", "width": 140},
@@ -129,51 +125,68 @@ def get_columns(filters):
def get_conditions(filters):
ple = qb.DocType("Payment Ledger Entry")
conditions = []
if not filters.party_type:
if filters.payment_type == _("Outgoing"):
filters.party_type = "Supplier"
else:
filters.party_type = "Customer"
if filters.party_type:
conditions.append("party_type=%(party_type)s")
conditions.append(ple.delinked.eq(0))
if filters.payment_type == _("Outgoing"):
conditions.append(ple.party_type.eq("Supplier"))
conditions.append(ple.against_voucher_type.eq("Purchase Invoice"))
else:
conditions.append(ple.party_type.eq("Customer"))
conditions.append(ple.against_voucher_type.eq("Sales Invoice"))
if filters.party:
conditions.append("party=%(party)s")
if filters.party_type:
conditions.append("against_voucher_type=%(reference_type)s")
filters["reference_type"] = (
"Sales Invoice" if filters.party_type == "Customer" else "Purchase Invoice"
)
conditions.append(ple.party.eq(filters.party))
if filters.get("from_date"):
conditions.append("posting_date >= %(from_date)s")
conditions.append(ple.posting_date.gte(filters.get("from_date")))
if filters.get("to_date"):
conditions.append("posting_date <= %(to_date)s")
conditions.append(ple.posting_date.lte(filters.get("to_date")))
return "and " + " and ".join(conditions) if conditions else ""
if filters.get("company"):
conditions.append(ple.company.eq(filters.get("company")))
return conditions
def get_entries(filters):
return frappe.db.sql(
"""select
voucher_type, voucher_no, party_type, party, posting_date, debit, credit, remarks, against_voucher
from `tabGL Entry`
where company=%(company)s and voucher_type in ('Journal Entry', 'Payment Entry') and is_cancelled = 0 {}
""".format(get_conditions(filters)),
filters,
as_dict=1,
ple = qb.DocType("Payment Ledger Entry")
conditions = get_conditions(filters)
query = (
qb.from_(ple)
.select(
ple.voucher_type,
ple.voucher_no,
ple.party_type,
ple.party,
ple.posting_date,
Abs(ple.amount).as_("amount"),
ple.remarks,
ple.against_voucher_no,
)
.where(Criterion.all(conditions))
)
res = query.run(as_dict=True)
return res
def get_invoice_posting_date_map(filters):
invoice_details = {}
dt = "Sales Invoice" if filters.get("payment_type") == _("Incoming") else "Purchase Invoice"
for t in frappe.db.sql(f"select name, posting_date, due_date from `tab{dt}`", as_dict=1):
dt = (
qb.DocType("Sales Invoice")
if filters.get("payment_type") == _("Incoming")
else qb.DocType("Purchase Invoice")
)
res = (
qb.from_(dt)
.select(dt.name, dt.posting_date, dt.due_date)
.where((dt.docstatus.eq(1)) & (dt.company.eq(filters.get("company"))))
.run(as_dict=1)
)
for t in res:
invoice_details[t.name] = t
return invoice_details

View File

@@ -1,8 +1,4 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.require("assets/erpnext/js/purchase_trends_filters.js", function () {
frappe.query_reports["Purchase Invoice Trends"] = {
filters: erpnext.get_purchase_trends_filters(),
};
});
frappe.query_reports["Purchase Invoice Trends"] = $.extend({}, erpnext.purchase_trends_filters);

View File

@@ -1,8 +1,4 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.require("assets/erpnext/js/sales_trends_filters.js", function () {
frappe.query_reports["Sales Invoice Trends"] = {
filters: erpnext.get_sales_trends_filters(),
};
});
frappe.query_reports["Sales Invoice Trends"] = $.extend({}, erpnext.sales_trends_filters);

View File

@@ -80,6 +80,7 @@ def _execute(filters, additional_table_columns=None):
delivery_note = list(set(invoice_so_dn_map.get(inv.name, {}).get("delivery_note", [])))
cost_center = list(set(invoice_cc_wh_map.get(inv.name, {}).get("cost_center", [])))
warehouse = list(set(invoice_cc_wh_map.get(inv.name, {}).get("warehouse", [])))
inv_customer_details = customer_details.get(inv.customer, {})
row = {
"voucher_type": inv.doctype,
@@ -88,9 +89,9 @@ def _execute(filters, additional_table_columns=None):
"customer": inv.customer,
"customer_name": inv.customer_name,
**get_values_for_columns(additional_table_columns, inv),
"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"),
"customer_group": inv_customer_details.get("customer_group"),
"territory": inv_customer_details.get("territory"),
"tax_id": inv_customer_details.get("tax_id"),
"receivable_account": inv.debit_to,
"mode_of_payment": ", ".join(mode_of_payments.get(inv.name, [])),
"project": inv.project,

View File

@@ -56,7 +56,7 @@ def get_fiscal_year(
date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False, boolean=False
):
if isinstance(boolean, str):
boolean = frappe.json.loads(boolean)
boolean = loads(boolean)
fiscal_years = get_fiscal_years(
date, fiscal_year, label, verbose, company, as_dict=as_dict, boolean=boolean
@@ -516,6 +516,10 @@ def reconcile_against_document(
doc.make_advance_gl_entries()
else:
gl_map = doc.build_gl_map()
# Make sure there is no overallocation
from erpnext.accounts.general_ledger import process_debit_credit_difference
process_debit_credit_difference(gl_map)
create_payment_ledger_entry(gl_map, update_outstanding="No", cancel=0, adv_adj=1)
# Only update outstanding for newly linked vouchers
@@ -1094,7 +1098,7 @@ def get_companies():
def get_children(doctype, parent, company, is_root=False):
from erpnext.accounts.report.financial_statements import sort_accounts
parent_fieldname = "parent_" + doctype.lower().replace(" ", "_")
parent_fieldname = "parent_" + frappe.scrub(doctype)
fields = ["name as value", "is_group as expandable"]
filters = [["docstatus", "<", 2]]

View File

@@ -652,7 +652,7 @@ frappe.ui.form.on("Asset", {
);
frm.set_value("gross_purchase_amount", purchase_amount);
frm.set_value("purchase_receipt_amount", purchase_amount);
frm.set_value("purchase_amount", purchase_amount);
frm.set_value("asset_quantity", asset_quantity);
frm.set_value("cost_center", item.cost_center || purchase_doc.cost_center);
if (item.asset_location) {

View File

@@ -72,7 +72,7 @@
"status",
"booked_fixed_asset",
"column_break_51",
"purchase_receipt_amount",
"purchase_amount",
"default_finance_book",
"depr_entry_posting_status",
"amended_from",
@@ -408,15 +408,6 @@
"options": "Purchase Receipt",
"print_hide": 1
},
{
"fieldname": "purchase_receipt_amount",
"fieldtype": "Currency",
"hidden": 1,
"label": "Purchase Receipt Amount",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
},
{
"depends_on": "eval:!doc.is_composite_asset && !doc.is_existing_asset",
"fieldname": "purchase_invoice",
@@ -546,6 +537,15 @@
"label": "Additional Asset Cost",
"options": "Company:company:default_currency",
"read_only": 1
},
{
"fieldname": "purchase_amount",
"fieldtype": "Currency",
"hidden": 1,
"label": "Purchase Amount",
"no_copy": 1,
"print_hide": 1,
"read_only": 1
}
],
"idx": 72,
@@ -589,7 +589,7 @@
"link_fieldname": "target_asset"
}
],
"modified": "2024-01-15 17:35:49.226603",
"modified": "2024-04-18 16:45:47.306032",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
@@ -633,4 +633,4 @@
"states": [],
"title_field": "asset_name",
"track_changes": 1
}
}

View File

@@ -92,10 +92,10 @@ class Asset(AccountsController):
number_of_depreciations_booked: DF.Int
opening_accumulated_depreciation: DF.Currency
policy_number: DF.Data | None
purchase_amount: DF.Currency
purchase_date: DF.Date | None
purchase_invoice: DF.Link | None
purchase_receipt: DF.Link | None
purchase_receipt_amount: DF.Currency
split_from: DF.Link | None
status: DF.Literal[
"Draft",
@@ -354,7 +354,7 @@ class Asset(AccountsController):
if self.is_existing_asset:
return
if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_receipt_amount:
if self.gross_purchase_amount and self.gross_purchase_amount != self.purchase_amount:
error_message = _(
"Gross Purchase Amount should be <b>equal</b> to purchase amount of one single Asset."
)
@@ -696,7 +696,7 @@ class Asset(AccountsController):
purchase_document = self.get_purchase_document()
fixed_asset_account, cwip_account = self.get_fixed_asset_account(), self.get_cwip_account()
if purchase_document and self.purchase_receipt_amount and self.available_for_use_date <= nowdate():
if purchase_document and self.purchase_amount and getdate(self.available_for_use_date) <= getdate():
gl_entries.append(
self.get_gl_dict(
{
@@ -704,8 +704,8 @@ class Asset(AccountsController):
"against": fixed_asset_account,
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date,
"credit": self.purchase_receipt_amount,
"credit_in_account_currency": self.purchase_receipt_amount,
"credit": self.purchase_amount,
"credit_in_account_currency": self.purchase_amount,
"cost_center": self.cost_center,
},
item=self,
@@ -719,8 +719,8 @@ class Asset(AccountsController):
"against": cwip_account,
"remarks": self.get("remarks") or _("Accounting Entry for Asset"),
"posting_date": self.available_for_use_date,
"debit": self.purchase_receipt_amount,
"debit_in_account_currency": self.purchase_receipt_amount,
"debit": self.purchase_amount,
"debit_in_account_currency": self.purchase_amount,
"cost_center": self.cost_center,
},
item=self,
@@ -1116,8 +1116,8 @@ def create_new_asset_after_split(asset, split_qty):
)
new_asset.gross_purchase_amount = new_gross_purchase_amount
if asset.purchase_receipt_amount:
new_asset.purchase_receipt_amount = new_gross_purchase_amount
if asset.purchase_amount:
new_asset.purchase_amount = new_gross_purchase_amount
new_asset.opening_accumulated_depreciation = opening_accumulated_depreciation
new_asset.asset_quantity = split_qty
new_asset.split_from = asset.name
@@ -1140,6 +1140,8 @@ def create_new_asset_after_split(asset, split_qty):
for row in new_asset.get("finance_books"):
current_asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, "Active", row.finance_book)
if not current_asset_depr_schedule_doc:
continue
new_asset_depr_schedule_doc = frappe.copy_doc(current_asset_depr_schedule_doc)
new_asset_depr_schedule_doc.set_draft_asset_depr_schedule_details(new_asset, row)

View File

@@ -1000,7 +1000,7 @@ class TestDepreciationBasics(AssetSetup):
asset_depr_schedule_doc = get_asset_depr_schedule_doc(asset.name, "Active")
depreciation_amount = get_depreciation_amount(
depreciation_amount, prev_per_day_depr = get_depreciation_amount(
asset_depr_schedule_doc, asset, 100000, 100000, asset.finance_books[0]
)
self.assertEqual(depreciation_amount, 30000)
@@ -1698,7 +1698,7 @@ def create_asset(**args):
"opening_accumulated_depreciation": args.opening_accumulated_depreciation or 0,
"number_of_depreciations_booked": args.number_of_depreciations_booked or 0,
"gross_purchase_amount": args.gross_purchase_amount or 100000,
"purchase_receipt_amount": args.purchase_receipt_amount or 100000,
"purchase_amount": args.purchase_amount or 100000,
"maintenance_required": args.maintenance_required or 0,
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"available_for_use_date": args.available_for_use_date or "2020-06-06",
@@ -1723,6 +1723,7 @@ def create_asset(**args):
"depreciation_start_date": args.depreciation_start_date,
"daily_prorata_based": args.daily_prorata_based or 0,
"shift_based": args.shift_based or 0,
"rate_of_depreciation": args.rate_of_depreciation or 0,
},
)

View File

@@ -143,6 +143,10 @@ class AssetCapitalization(StockController):
self.make_gl_entries()
self.restore_consumed_asset_items()
def on_trash(self):
frappe.db.set_value("Asset", self.target_asset, "capitalized_in", None)
super().on_trash()
def cancel_target_asset(self):
if self.entry_type == "Capitalization" and self.target_asset:
asset_doc = frappe.get_doc("Asset", self.target_asset)
@@ -612,8 +616,7 @@ class AssetCapitalization(StockController):
asset_doc.available_for_use_date = self.posting_date
asset_doc.purchase_date = self.posting_date
asset_doc.gross_purchase_amount = total_target_asset_value
asset_doc.purchase_receipt_amount = total_target_asset_value
asset_doc.purchase_receipt_amount = total_target_asset_value
asset_doc.purchase_amount = total_target_asset_value
asset_doc.capitalized_in = self.name
asset_doc.flags.ignore_validate = True
asset_doc.flags.asset_created_via_asset_capitalization = True
@@ -649,7 +652,7 @@ class AssetCapitalization(StockController):
asset_doc = frappe.get_doc("Asset", self.target_asset)
asset_doc.gross_purchase_amount = total_target_asset_value
asset_doc.purchase_receipt_amount = total_target_asset_value
asset_doc.purchase_amount = total_target_asset_value
asset_doc.capitalized_in = self.name
asset_doc.flags.ignore_validate = True
asset_doc.save()

View File

@@ -89,7 +89,7 @@ class TestAssetCapitalization(unittest.TestCase):
# Test Target Asset values
target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset)
self.assertEqual(target_asset.gross_purchase_amount, total_amount)
self.assertEqual(target_asset.purchase_receipt_amount, total_amount)
self.assertEqual(target_asset.purchase_amount, total_amount)
# Test Consumed Asset values
self.assertEqual(consumed_asset.db_get("status"), "Capitalized")
@@ -179,7 +179,7 @@ class TestAssetCapitalization(unittest.TestCase):
# Test Target Asset values
target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset)
self.assertEqual(target_asset.gross_purchase_amount, total_amount)
self.assertEqual(target_asset.purchase_receipt_amount, total_amount)
self.assertEqual(target_asset.purchase_amount, total_amount)
# Test Consumed Asset values
self.assertEqual(consumed_asset.db_get("status"), "Capitalized")
@@ -256,7 +256,7 @@ class TestAssetCapitalization(unittest.TestCase):
# Test Target Asset values
target_asset = frappe.get_doc("Asset", asset_capitalization.target_asset)
self.assertEqual(target_asset.gross_purchase_amount, total_amount)
self.assertEqual(target_asset.purchase_receipt_amount, total_amount)
self.assertEqual(target_asset.purchase_amount, total_amount)
# Test General Ledger Entries
expected_gle = {
@@ -526,7 +526,7 @@ def create_depreciation_asset(**args):
asset.available_for_use_date = args.available_for_use_date or asset.purchase_date
asset.gross_purchase_amount = args.asset_value or 100000
asset.purchase_receipt_amount = asset.gross_purchase_amount
asset.purchase_amount = asset.gross_purchase_amount
finance_book = asset.append("finance_books")
finance_book.depreciation_start_date = args.depreciation_start_date or "2020-12-31"

View File

@@ -285,6 +285,7 @@ class AssetDepreciationSchedule(Document):
number_of_pending_depreciations = final_number_of_depreciations - start
yearly_opening_wdv = value_after_depreciation
current_fiscal_year_end_date = None
prev_per_day_depr = True
for n in range(start, final_number_of_depreciations):
# If depreciation is already completed (for double declining balance)
if skip_row:
@@ -301,8 +302,7 @@ class AssetDepreciationSchedule(Document):
prev_depreciation_amount = self.get("depreciation_schedule")[n - 1].depreciation_amount
else:
prev_depreciation_amount = 0
depreciation_amount = get_depreciation_amount(
depreciation_amount, prev_per_day_depr = get_depreciation_amount(
self,
asset_doc,
value_after_depreciation,
@@ -312,6 +312,7 @@ class AssetDepreciationSchedule(Document):
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
number_of_pending_depreciations,
prev_per_day_depr,
)
if not has_pro_rata or (
n < (cint(final_number_of_depreciations) - 1) or final_number_of_depreciations == 2
@@ -362,6 +363,16 @@ class AssetDepreciationSchedule(Document):
row.depreciation_start_date,
has_wdv_or_dd_non_yearly_pro_rata,
)
if flt(depreciation_amount, asset_doc.precision("gross_purchase_amount")) <= 0:
frappe.throw(
_(
"Gross Purchase Amount Too Low: {0} cannot be depreciated over {1} cycles with a frequency of {2} depreciations."
).format(
frappe.bold(asset_doc.gross_purchase_amount),
frappe.bold(row.total_number_of_depreciations),
frappe.bold(row.frequency_of_depreciation),
)
)
elif n == 0 and has_wdv_or_dd_non_yearly_pro_rata and self.opening_accumulated_depreciation:
if not is_first_day_of_the_month(getdate(asset_doc.available_for_use_date)):
from_date = get_last_day(
@@ -599,11 +610,12 @@ def get_depreciation_amount(
prev_depreciation_amount=0,
has_wdv_or_dd_non_yearly_pro_rata=False,
number_of_pending_depreciations=0,
prev_per_day_depr=0,
):
if fb_row.depreciation_method in ("Straight Line", "Manual"):
return get_straight_line_or_manual_depr_amount(
asset_depr_schedule, asset, fb_row, schedule_idx, number_of_pending_depreciations
)
), None
else:
return get_wdv_or_dd_depr_amount(
asset,
@@ -614,6 +626,7 @@ def get_depreciation_amount(
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
)
@@ -637,49 +650,14 @@ def get_straight_line_or_manual_depr_amount(
elif asset.flags.decrease_in_asset_value_due_to_value_adjustment:
if row.daily_prorata_based:
amount = flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
total_days = (
date_diff(
get_last_day(
add_months(
row.depreciation_start_date,
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
* row.frequency_of_depreciation,
)
),
add_days(
get_last_day(
add_months(
row.depreciation_start_date,
flt(
row.total_number_of_depreciations
- asset.number_of_depreciations_booked
- number_of_pending_depreciations
- 1
)
* row.frequency_of_depreciation,
)
),
1,
),
)
+ 1
)
daily_depr_amount = amount / total_days
to_date = get_last_day(
add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
return get_daily_prorata_based_straight_line_depr(
asset,
row,
schedule_idx,
number_of_pending_depreciations,
amount,
)
from_date = add_days(
get_last_day(
add_months(
row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
)
),
1,
)
return daily_depr_amount * (date_diff(to_date, from_date) + 1)
else:
return (
flt(row.value_after_depreciation) - flt(row.expected_value_after_useful_life)
@@ -692,40 +670,9 @@ def get_straight_line_or_manual_depr_amount(
- flt(asset.opening_accumulated_depreciation)
- flt(row.expected_value_after_useful_life)
)
total_days = (
date_diff(
get_last_day(
add_months(
row.depreciation_start_date,
flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked - 1)
* row.frequency_of_depreciation,
)
),
add_days(
get_last_day(
add_months(row.depreciation_start_date, -1 * row.frequency_of_depreciation)
),
1,
),
)
+ 1
return get_daily_prorata_based_straight_line_depr(
asset, row, schedule_idx, number_of_pending_depreciations, amount
)
daily_depr_amount = amount / total_days
to_date = get_last_day(
add_months(row.depreciation_start_date, schedule_idx * row.frequency_of_depreciation)
)
from_date = add_days(
get_last_day(
add_months(
row.depreciation_start_date, (schedule_idx - 1) * row.frequency_of_depreciation
)
),
1,
)
return daily_depr_amount * (date_diff(to_date, from_date) + 1)
else:
return (
flt(asset.gross_purchase_amount)
@@ -734,6 +681,23 @@ def get_straight_line_or_manual_depr_amount(
) / flt(row.total_number_of_depreciations - asset.number_of_depreciations_booked)
def get_daily_prorata_based_straight_line_depr(
asset, row, schedule_idx, number_of_pending_depreciations, amount
):
total_years = flt(number_of_pending_depreciations * row.frequency_of_depreciation) / 12
every_year_depr = amount / total_years
year_start_date = add_years(
row.depreciation_start_date, (row.frequency_of_depreciation * schedule_idx) // 12
)
year_end_date = add_days(add_years(year_start_date, 1), -1)
daily_depr_amount = every_year_depr / (date_diff(year_end_date, year_start_date) + 1)
from_date, total_depreciable_days = _get_total_days(
row.depreciation_start_date, schedule_idx, row.frequency_of_depreciation
)
return daily_depr_amount * total_depreciable_days
def get_shift_depr_amount(asset_depr_schedule, asset, row, schedule_idx):
if asset_depr_schedule.get("__islocal") and not asset.flags.shift_allocation:
return (
@@ -779,6 +743,7 @@ def get_wdv_or_dd_depr_amount(
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
):
return get_default_wdv_or_dd_depr_amount(
asset,
@@ -788,6 +753,7 @@ def get_wdv_or_dd_depr_amount(
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
)
@@ -799,6 +765,39 @@ def get_default_wdv_or_dd_depr_amount(
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
):
if not fb_row.daily_prorata_based or cint(fb_row.frequency_of_depreciation) == 12:
return _get_default_wdv_or_dd_depr_amount(
asset,
fb_row,
depreciable_value,
schedule_idx,
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
), None
else:
return _get_daily_prorata_based_default_wdv_or_dd_depr_amount(
asset,
fb_row,
depreciable_value,
schedule_idx,
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
)
def _get_default_wdv_or_dd_depr_amount(
asset,
fb_row,
depreciable_value,
schedule_idx,
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
):
if cint(fb_row.frequency_of_depreciation) == 12:
return flt(depreciable_value) * (flt(fb_row.rate_of_depreciation) / 100)
@@ -825,6 +824,75 @@ def get_default_wdv_or_dd_depr_amount(
return prev_depreciation_amount
def _get_daily_prorata_based_default_wdv_or_dd_depr_amount(
asset,
fb_row,
depreciable_value,
schedule_idx,
prev_depreciation_amount,
has_wdv_or_dd_non_yearly_pro_rata,
asset_depr_schedule,
prev_per_day_depr,
):
if has_wdv_or_dd_non_yearly_pro_rata: # If applicable days for ther first month is less than full month
if schedule_idx == 0:
return flt(depreciable_value) * (flt(fb_row.rate_of_depreciation) / 100), None
elif schedule_idx % (12 / cint(fb_row.frequency_of_depreciation)) == 1: # Year changes
return get_monthly_depr_amount(fb_row, schedule_idx, depreciable_value)
else:
return get_monthly_depr_amount_based_on_prev_per_day_depr(fb_row, schedule_idx, prev_per_day_depr)
else:
if schedule_idx % (12 / cint(fb_row.frequency_of_depreciation)) == 0: # year changes
return get_monthly_depr_amount(fb_row, schedule_idx, depreciable_value)
else:
return get_monthly_depr_amount_based_on_prev_per_day_depr(fb_row, schedule_idx, prev_per_day_depr)
def get_monthly_depr_amount(fb_row, schedule_idx, depreciable_value):
""" "
Returns monthly depreciation amount when year changes
1. Calculate per day depr based on new year
2. Calculate monthly amount based on new per day amount
"""
from_date, days_in_month = _get_total_days(
fb_row.depreciation_start_date, schedule_idx, cint(fb_row.frequency_of_depreciation)
)
per_day_depr = get_per_day_depr(fb_row, depreciable_value, from_date)
return (per_day_depr * days_in_month), per_day_depr
def get_monthly_depr_amount_based_on_prev_per_day_depr(fb_row, schedule_idx, prev_per_day_depr):
""" "
Returns monthly depreciation amount based on prev per day depr
Calculate per day depr only for the first month
"""
from_date, days_in_month = _get_total_days(
fb_row.depreciation_start_date, schedule_idx, cint(fb_row.frequency_of_depreciation)
)
return (prev_per_day_depr * days_in_month), prev_per_day_depr
def get_per_day_depr(
fb_row,
depreciable_value,
from_date,
):
to_date = add_days(add_years(from_date, 1), -1)
total_days = date_diff(to_date, from_date) + 1
per_day_depr = (flt(depreciable_value) * (flt(fb_row.rate_of_depreciation) / 100)) / total_days
return per_day_depr
def _get_total_days(depreciation_start_date, schedule_idx, frequency_of_depreciation):
from_date = add_months(depreciation_start_date, (schedule_idx - 1) * frequency_of_depreciation)
to_date = add_months(from_date, frequency_of_depreciation)
if is_last_day_of_the_month(depreciation_start_date):
to_date = get_last_day(to_date)
from_date = add_days(get_last_day(from_date), 1)
return from_date, date_diff(to_date, from_date) + 1
def make_draft_asset_depr_schedules_if_not_present(asset_doc):
asset_depr_schedules_names = []

View File

@@ -3,10 +3,12 @@
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import cstr
from erpnext.assets.doctype.asset.test_asset import create_asset, create_asset_data
from erpnext.assets.doctype.asset_depreciation_schedule.asset_depreciation_schedule import (
get_asset_depr_schedule_doc,
get_depr_schedule,
)
@@ -25,3 +27,136 @@ class TestAssetDepreciationSchedule(FrappeTestCase):
)
self.assertRaises(frappe.ValidationError, second_asset_depr_schedule.insert)
def test_daily_prorata_based_depr_on_sl_methond(self):
asset = create_asset(
calculate_depreciation=1,
depreciation_method="Straight Line",
daily_prorata_based=1,
available_for_use_date="2020-01-01",
depreciation_start_date="2020-01-31",
frequency_of_depreciation=1,
total_number_of_depreciations=24,
)
expected_schedules = [
["2020-01-31", 4234.97, 4234.97],
["2020-02-29", 3961.75, 8196.72],
["2020-03-31", 4234.97, 12431.69],
["2020-04-30", 4098.36, 16530.05],
["2020-05-31", 4234.97, 20765.02],
["2020-06-30", 4098.36, 24863.38],
["2020-07-31", 4234.97, 29098.35],
["2020-08-31", 4234.97, 33333.32],
["2020-09-30", 4098.36, 37431.68],
["2020-10-31", 4234.97, 41666.65],
["2020-11-30", 4098.36, 45765.01],
["2020-12-31", 4234.97, 49999.98],
["2021-01-31", 4246.58, 54246.56],
["2021-02-28", 3835.62, 58082.18],
["2021-03-31", 4246.58, 62328.76],
["2021-04-30", 4109.59, 66438.35],
["2021-05-31", 4246.58, 70684.93],
["2021-06-30", 4109.59, 74794.52],
["2021-07-31", 4246.58, 79041.1],
["2021-08-31", 4246.58, 83287.68],
["2021-09-30", 4109.59, 87397.27],
["2021-10-31", 4246.58, 91643.85],
["2021-11-30", 4109.59, 95753.44],
["2021-12-31", 4246.56, 100000.0],
]
schedules = [
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
for d in get_depr_schedule(asset.name, "Draft")
]
self.assertEqual(schedules, expected_schedules)
# Test for Written Down Value Method
# Frequency of deprciation = 3
def test_for_daily_prorata_based_depreciation_wdv_method_frequency_3_months(self):
asset = create_asset(
item_code="Macbook Pro",
calculate_depreciation=1,
depreciation_method="Written Down Value",
daily_prorata_based=1,
available_for_use_date="2021-02-20",
depreciation_start_date="2021-03-31",
frequency_of_depreciation=3,
total_number_of_depreciations=6,
rate_of_depreciation=40,
)
expected_schedules = [
["2021-03-31", 4383.56, 4383.56],
["2021-06-30", 9535.45, 13919.01],
["2021-09-30", 9640.23, 23559.24],
["2021-12-31", 9640.23, 33199.47],
["2022-03-31", 9430.66, 42630.13],
["2022-06-30", 5721.27, 48351.4],
["2022-08-20", 51648.6, 100000.0],
]
schedules = [
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
for d in get_depr_schedule(asset.name, "Draft")
]
self.assertEqual(schedules, expected_schedules)
# Frequency of deprciation = 6
def test_for_daily_prorata_based_depreciation_wdv_method_frequency_6_months(self):
asset = create_asset(
item_code="Macbook Pro",
calculate_depreciation=1,
depreciation_method="Written Down Value",
daily_prorata_based=1,
available_for_use_date="2020-02-20",
depreciation_start_date="2020-02-29",
frequency_of_depreciation=6,
total_number_of_depreciations=6,
rate_of_depreciation=40,
)
expected_schedules = [
["2020-02-29", 1092.90, 1092.90],
["2020-08-31", 19944.01, 21036.91],
["2021-02-28", 19618.83, 40655.74],
["2021-08-31", 11966.4, 52622.14],
["2022-02-28", 11771.3, 64393.44],
["2022-08-31", 7179.84, 71573.28],
["2023-02-20", 28426.72, 100000.0],
]
schedules = [
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
for d in get_depr_schedule(asset.name, "Draft")
]
self.assertEqual(schedules, expected_schedules)
# Frequency of deprciation = 12
def test_for_daily_prorata_based_depreciation_wdv_method_frequency_12_months(self):
asset = create_asset(
item_code="Macbook Pro",
calculate_depreciation=1,
depreciation_method="Written Down Value",
daily_prorata_based=1,
available_for_use_date="2020-02-20",
depreciation_start_date="2020-03-31",
frequency_of_depreciation=12,
total_number_of_depreciations=4,
rate_of_depreciation=40,
)
expected_schedules = [
["2020-03-31", 4480.87, 4480.87],
["2021-03-31", 38207.65, 42688.52],
["2022-03-31", 22924.59, 65613.11],
["2023-03-31", 13754.76, 79367.87],
["2024-02-20", 20632.13, 100000],
]
schedules = [
[cstr(d.schedule_date), d.depreciation_amount, d.accumulated_depreciation_amount]
for d in get_depr_schedule(asset.name, "Draft")
]
self.assertEqual(schedules, expected_schedules)

View File

@@ -305,6 +305,7 @@ def create_asset_repair(**args):
"serial_nos": args.serial_no,
"posting_date": today(),
"posting_time": nowtime(),
"do_not_submit": 1,
}
)
).name

View File

@@ -159,8 +159,9 @@ def prepare_chart_data(data, filters):
if filters.filter_based_on not in ("Date Range", "Fiscal Year"):
filters_filter_based_on = "Date Range"
date_field = "purchase_date"
filters_from_date = min(data, key=lambda a: a.get(date_field)).get(date_field)
filters_to_date = max(data, key=lambda a: a.get(date_field)).get(date_field)
filtered_data = [d for d in data if d.get(date_field)]
filters_from_date = min(filtered_data, key=lambda a: a.get(date_field)).get(date_field)
filters_to_date = max(filtered_data, key=lambda a: a.get(date_field)).get(date_field)
else:
filters_filter_based_on = filters.filter_based_on
date_field = frappe.scrub(filters.date_based_on)

View File

@@ -12,6 +12,7 @@ erpnext.buying.setup_buying_controller();
frappe.ui.form.on("Purchase Order", {
setup: function (frm) {
frm.ignore_doctypes_on_cancel_all = ["Unreconcile Payment", "Unreconcile Payment Entries"];
if (frm.doc.is_old_subcontracting_flow) {
frm.set_query("reserve_warehouse", "supplied_items", function () {
return {

View File

@@ -484,7 +484,13 @@ class PurchaseOrder(BuyingController):
self.auto_create_subcontracting_order()
def on_cancel(self):
self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry")
self.ignore_linked_doctypes = (
"GL Entry",
"Payment Ledger Entry",
"Unreconcile Payment",
"Unreconcile Payment Entries",
)
super().on_cancel()
if self.is_against_so():
@@ -612,6 +618,20 @@ class PurchaseOrder(BuyingController):
return result
def update_ordered_qty_in_so_for_removed_items(self, removed_items):
"""
Updates ordered_qty in linked SO when item rows are removed using Update Items
"""
if not self.is_against_so():
return
for item in removed_items:
prev_ordered_qty = frappe.get_cached_value(
"Sales Order Item", item.get("sales_order_item"), "ordered_qty"
)
frappe.db.set_value(
"Sales Order Item", item.get("sales_order_item"), "ordered_qty", prev_ordered_qty - item.qty
)
def auto_create_subcontracting_order(self):
if self.is_subcontracted and not self.is_old_subcontracting_flow:
if frappe.db.get_single_value("Buying Settings", "auto_create_subcontracting_order"):
@@ -780,6 +800,8 @@ def get_mapped_purchase_invoice(source_name, target_doc=None, ignore_permissions
"field_map": {
"name": "po_detail",
"parent": "purchase_order",
"material_request": "material_request",
"material_request_item": "material_request_item",
"wip_composite_asset": "wip_composite_asset",
},
"postprocess": update_item,
@@ -888,12 +910,12 @@ def get_mapped_subcontracting_order(source_name, target_doc=None):
)
target_doc.populate_items_table()
source_doc = frappe.get_doc("Purchase Order", source_name)
if target_doc.set_warehouse:
for item in target_doc.items:
item.warehouse = target_doc.set_warehouse
else:
source_doc = frappe.get_doc("Purchase Order", source_name)
if source_doc.set_warehouse:
for item in target_doc.items:
item.warehouse = source_doc.set_warehouse

View File

@@ -764,12 +764,7 @@ class TestPurchaseOrder(FrappeTestCase):
}
).insert()
else:
account = frappe.db.get_value(
"Account",
filters={"account_name": account_name, "company": company},
fieldname="name",
pluck=True,
)
account = frappe.get_doc("Account", {"account_name": account_name, "company": company})
return account
@@ -800,22 +795,6 @@ class TestPurchaseOrder(FrappeTestCase):
from erpnext.buying.doctype.purchase_order.purchase_order import make_purchase_invoice
pi = make_purchase_invoice(po_doc.name)
pi.append(
"advances",
{
"reference_type": pe.doctype,
"reference_name": pe.name,
"reference_row": pe.references[0].name,
"advance_amount": 5000,
"allocated_amount": 5000,
},
)
pi.save().submit()
pe.reload()
po_doc.reload()
self.assertEqual(po_doc.advance_paid, 0)
company_doc.book_advance_payments_in_separate_party_account = False
company_doc.save()

View File

@@ -513,7 +513,7 @@ erpnext.buying.RequestforQuotationController = class RequestforQuotationControll
method: "frappe.desk.doctype.tag.tag.get_tagged_docs",
args: {
doctype: "Supplier",
tag: args.tag,
tag: "%" + args.tag + "%",
},
callback: load_suppliers,
});

View File

@@ -406,7 +406,7 @@
{
"fieldname": "contact_and_address_tab",
"fieldtype": "Tab Break",
"label": "Contact & Address"
"label": "Address & Contact"
},
{
"fieldname": "accounting_tab",
@@ -485,7 +485,7 @@
"link_fieldname": "party"
}
],
"modified": "2024-03-13 11:14:06.516519",
"modified": "2024-05-08 18:02:57.342931",
"modified_by": "Administrator",
"module": "Buying",
"name": "Supplier",

View File

@@ -3,10 +3,6 @@ from frappe import _
def get_data():
return {
"heatmap": True,
"heatmap_message": _(
"This is based on transactions against this Supplier. See timeline below for details"
),
"fieldname": "supplier",
"non_standard_fieldnames": {"Payment Entry": "party", "Bank Account": "party"},
"transactions": [

View File

@@ -1,8 +1,4 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// License: GNU General Public License v3. See license.txt
frappe.require("assets/erpnext/js/purchase_trends_filters.js", function () {
frappe.query_reports["Purchase Order Trends"] = {
filters: erpnext.get_purchase_trends_filters(),
};
});
frappe.query_reports["Purchase Order Trends"] = $.extend({}, erpnext.purchase_trends_filters);

View File

@@ -133,6 +133,13 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
return row.supplier_name;
});
let items = [];
report.data.forEach((d) => {
if (!items.includes(d.item_code)) {
items.push(d.item_code);
}
});
// Create a dialog window for the user to pick their supplier
let dialog = new frappe.ui.Dialog({
title: __("Select Default Supplier"),
@@ -151,20 +158,34 @@ frappe.query_reports["Supplier Quotation Comparison"] = {
};
},
},
{
reqd: 1,
label: "Item",
fieldtype: "Link",
options: "Item",
fieldname: "item_code",
get_query: () => {
return {
filters: {
name: ["in", items],
},
};
},
},
],
});
dialog.set_primary_action(__("Set Default Supplier"), () => {
let values = dialog.get_values();
if (values) {
// Set the default_supplier field of the appropriate Item to the selected supplier
frappe.call({
method: "frappe.client.set_value",
method: "erpnext.buying.report.supplier_quotation_comparison.supplier_quotation_comparison.set_default_supplier",
args: {
doctype: "Item",
name: item_code,
fieldname: "default_supplier",
value: values.supplier,
item_code: values.item_code,
supplier: values.supplier,
company: filters.company,
},
freeze: true,
callback: (r) => {

View File

@@ -292,3 +292,13 @@ def get_message():
<span class="indicator red">
Expires today / Already Expired
</span>"""
@frappe.whitelist()
def set_default_supplier(item_code, supplier, company):
frappe.db.set_value(
"Item Default",
{"parent": item_code, "company": company},
"default_supplier",
supplier,
)

View File

@@ -2183,10 +2183,10 @@ class AccountsController(TransactionBase):
for d in self.get("payment_schedule"):
if d.invoice_portion:
d.payment_amount = flt(
grand_total * flt(d.invoice_portion / 100), d.precision("payment_amount")
grand_total * flt(d.invoice_portion) / 100, d.precision("payment_amount")
)
d.base_payment_amount = flt(
base_grand_total * flt(d.invoice_portion / 100), d.precision("base_payment_amount")
base_grand_total * flt(d.invoice_portion) / 100, d.precision("base_payment_amount")
)
d.outstanding = d.payment_amount
elif not d.invoice_portion:
@@ -3158,6 +3158,9 @@ def validate_and_delete_children(parent, data) -> bool:
d.cancel()
d.delete()
if parent.doctype == "Purchase Order":
parent.update_ordered_qty_in_so_for_removed_items(deleted_children)
# need to update ordered qty in Material Request first
# bin uses Material Request Items to recalculate & update
parent.update_prevdoc_status()

View File

@@ -8,6 +8,7 @@ from frappe.contacts.doctype.address.address import render_address
from frappe.utils import cint, flt, getdate
from frappe.utils.data import nowtime
import erpnext
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
from erpnext.accounts.party import get_party_details
from erpnext.buying.utils import update_last_purchase_rate, validate_for_items
@@ -332,6 +333,8 @@ class BuyingController(SubcontractingController):
else:
item.valuation_rate = 0.0
update_regional_item_valuation_rate(self)
def set_incoming_rate(self):
if self.doctype not in ("Purchase Receipt", "Purchase Invoice", "Purchase Order"):
return
@@ -787,7 +790,7 @@ class BuyingController(SubcontractingController):
"supplier": self.supplier,
"purchase_date": self.posting_date,
"calculate_depreciation": 0,
"purchase_receipt_amount": purchase_amount,
"purchase_amount": purchase_amount,
"gross_purchase_amount": purchase_amount,
"asset_quantity": asset_quantity,
"purchase_receipt": self.name if self.doctype == "Purchase Receipt" else None,
@@ -935,3 +938,8 @@ def validate_item_type(doc, fieldname, message):
).format(items, message)
frappe.throw(error_message)
@erpnext.allow_regional
def update_regional_item_valuation_rate(doc):
pass

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