Compare commits

..

584 Commits

Author SHA1 Message Date
Frappe PR Bot
7ba029b140 chore(release): Bumped to Version 13.40.2
## [13.40.2](https://github.com/frappe/erpnext/compare/v13.40.1...v13.40.2) (2022-10-19)

### Bug Fixes

* `Brand Defaults` filters ([b1c70af](b1c70af4db))
* don't try to update youtube data if disabled in settings (backport [#32588](https://github.com/frappe/erpnext/issues/32588)) ([#32590](https://github.com/frappe/erpnext/issues/32590)) ([7e7122b](7e7122b668))
* Ignore linked purchase invoice on cancel ([eec770a](eec770a4a8))
* Party account for multi-order invoices ([0ae2a4f](0ae2a4f1c4))
* pricing rule item code UOM apply & conversions (backport [#32566](https://github.com/frappe/erpnext/issues/32566)) ([#32636](https://github.com/frappe/erpnext/issues/32636)) ([b8d97b8](b8d97b82b8))
2022-10-19 03:57:46 +00:00
Deepesh Garg
cf74d24400 Merge pull request #32634 from frappe/version-13-hotfix
chore: release v13
2022-10-19 09:24:40 +05:30
mergify[bot]
b8d97b82b8 fix: pricing rule item code UOM apply & conversions (backport #32566) (#32636)
* fix: pricing rule for non stock UOM and conversions

* fix: pricing rule for non stock UOM and conversions

(cherry picked from commit 96b4211ea1)

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

* chore: resolve conflicts

Co-authored-by: Maharshi Patel <39730881+maharshivpatel@users.noreply.github.com>
Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2022-10-18 23:31:31 +05:30
Deepesh Garg
56c4c3186b Merge pull request #32624 from frappe/mergify/bp/version-13-hotfix/pr-32622
fix: Ignore linked purchase invoice on cancel (backport #32622)
2022-10-18 14:49:36 +05:30
Deepesh Garg
015a221d8d chore: Resolve conflicts 2022-10-18 09:11:58 +05:30
Deepesh Garg
eec770a4a8 fix: Ignore linked purchase invoice on cancel
(cherry picked from commit faadf78332)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
2022-10-17 14:09:12 +00:00
Deepesh Garg
44f5ccc9dc Merge pull request #32605 from frappe/mergify/bp/version-13-hotfix/pr-32594
fix: Party account for multi-order invoices (backport #32594)
2022-10-15 18:25:25 +05:30
Deepesh Garg
0ae2a4f1c4 fix: Party account for multi-order invoices
(cherry picked from commit fd49503ba2)
2022-10-15 11:29:21 +00:00
mergify[bot]
5fdaddad86 chore: drop dead code (backport #32595) (#32597)
chore: drop dead code (#32595)

[skip ci]

(cherry picked from commit 50e9698932)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-10-13 15:27:09 +05:30
Sagar Sharma
03ccddc1cc Merge pull request #32587 from frappe/mergify/bp/version-13-hotfix/pr-32576
fix: `Brand Defaults` filters (backport #32576)
2022-10-13 14:42:29 +05:30
Sagar Sharma
e00ebcd9e5 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32576 2022-10-13 14:38:26 +05:30
mergify[bot]
7e7122b668 fix: don't try to update youtube data if disabled in settings (backport #32588) (#32590)
* fix: don't try to update youtube data if disabled in settings (#32588)

fix: cast value from db

[skip ci]

(cherry picked from commit e543dca6a0)

* chore: qualified path

not imported 

[skip ci]

Co-authored-by: Raffael Meyer <14891507+barredterra@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-10-13 11:57:08 +05:30
Sagar Sharma
b1c70af4db fix: Brand Defaults filters
(cherry picked from commit 7da32c7db3)
2022-10-12 13:53:56 +00:00
Frappe PR Bot
1609129e1e chore(release): Bumped to Version 13.40.1
## [13.40.1](https://github.com/frappe/erpnext/compare/v13.40.0...v13.40.1) (2022-10-12)

### Bug Fixes

* conflct in test purchase receipt ([6ae2f90](6ae2f90683))
* conflict ([cb7aef5](cb7aef505d))
* consider outgoingrate while valuation rate calculate ([6f43133](6f43133c04))
* consider sales rate as incoming rate for transit warehouse in purchase flow ([f72602e](f72602ebf3))
* Hanlde rounding loss for internal transfer ([dd26ef9](dd26ef96e0))
* Incoming rate precision fixes for intra company transfer ([227ce5f](227ce5f8a2))
* incorrect import ([8238b89](8238b89907))
* linter issue ([aa0552d](aa0552d788))
* test case ([acd64ba](acd64ba7c1))
* value error on pos submit ([4383980](4383980bcc))
2022-10-12 12:34:41 +00:00
Deepesh Garg
9b02455c09 Merge pull request #32585 from frappe/version-13-hotfix
chore: version 13 release
2022-10-12 18:03:01 +05:30
Deepesh Garg
ff3bfb060a Merge pull request #32584 from frappe/mergify/bp/version-13-hotfix/pr-32557
fix: Value error on validation of POS invoices with Serial Nos (backport #32557)
2022-10-12 17:17:01 +05:30
rohitwaghchaure
63e087d31e Merge pull request #32580 from frappe/mergify/bp/version-13-hotfix/pr-32563
fix: consider sales rate as incoming rate for transit warehouse in purchase flow (backport #32563)
2022-10-12 17:08:33 +05:30
Deepesh Garg
b62a397397 Merge pull request #32581 from frappe/mergify/bp/version-13-hotfix/pr-32272
fix: Incoming rate precision fixes for intra company transfer (backport #32272)
2022-10-12 17:04:52 +05:30
ruthra kumar
48efcc82b6 test: value error on serial no validation on pos
(cherry picked from commit 9e2bd10d03)
2022-10-12 11:12:09 +00:00
ruthra kumar
4383980bcc fix: value error on pos submit
(cherry picked from commit 4b908ebcd6)
2022-10-12 11:12:08 +00:00
rohitwaghchaure
aa0552d788 fix: linter issue 2022-10-12 16:33:53 +05:30
Deepesh Garg
3b5889ef85 chore: resolve conflicts 2022-10-12 16:30:23 +05:30
rohitwaghchaure
8238b89907 fix: incorrect import 2022-10-12 16:28:31 +05:30
rohitwaghchaure
6ae2f90683 fix: conflct in test purchase receipt 2022-10-12 16:26:52 +05:30
rohitwaghchaure
cb7aef505d fix: conflict 2022-10-12 16:24:50 +05:30
Deepesh Garg
4a8c42d62b chore: check only for inter-company transfers
(cherry picked from commit 9aa5e20ef7)
2022-10-12 10:54:15 +00:00
Deepesh Garg
c67bdcf3c6 chore: fix precision condition
(cherry picked from commit 49601558c6)
2022-10-12 10:54:14 +00:00
Deepesh Garg
7a9e7b66ac chore: Use proper accounts
(cherry picked from commit 1c05c004cd)
2022-10-12 10:54:13 +00:00
Deepesh Garg
151b9d4d7b chore: Increase precision for other doc fields
(cherry picked from commit c8d2181498)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice_item/purchase_invoice_item.json
#	erpnext/stock/doctype/delivery_note_item/delivery_note_item.json
2022-10-12 10:54:13 +00:00
Deepesh Garg
b966f10711 chore: GL Entries for SLE diff
(cherry picked from commit df2a0e265b)
2022-10-12 10:54:11 +00:00
Deepesh Garg
0b48f13873 test: Internal tranfer precision loss test
(cherry picked from commit dc20b21fb5)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2022-10-12 10:54:10 +00:00
Deepesh Garg
b531a38efe chore: Increase incoming_rate field precision to 6
(cherry picked from commit b31c3bd35d)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
2022-10-12 10:54:08 +00:00
Deepesh Garg
dd26ef96e0 fix: Hanlde rounding loss for internal transfer
(cherry picked from commit 6e47fd54a0)
2022-10-12 10:54:07 +00:00
Deepesh Garg
227ce5f8a2 fix: Incoming rate precision fixes for intra company transfer
(cherry picked from commit 083309c056)
2022-10-12 10:54:06 +00:00
Rohit Waghchaure
acd64ba7c1 fix: test case
(cherry picked from commit 98bf8e1304)
2022-10-12 10:51:22 +00:00
Rohit Waghchaure
6f43133c04 fix: consider outgoingrate while valuation rate calculate
(cherry picked from commit 3266e54e33)
2022-10-12 10:51:22 +00:00
Rohit Waghchaure
f72602ebf3 fix: consider sales rate as incoming rate for transit warehouse in purchase flow
(cherry picked from commit 683a47f7a1)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
#	erpnext/stock/stock_ledger.py
2022-10-12 10:51:21 +00:00
Frappe PR Bot
49c9c68e14 chore(release): Bumped to Version 13.40.0
# [13.40.0](https://github.com/frappe/erpnext/compare/v13.39.5...v13.40.0) (2022-10-12)

### Bug Fixes

* Do not add tax withheld vouchers post tax withheding in one document ([e1c41b9](e1c41b9195))
* future attendance marking ([cb4fbd5](cb4fbd5432))
* make readings status mandatory in Quality Inspection ([257a2a3](257a2a3d71))
* mark attendance issue with joining date ([6f8d620](6f8d62088e))
* mark attendance issue with relieving date ([a9546dd](a9546dd01f))
* PO cancel post advance payment cancel against PO ([41599cf](41599cf29f))
* set Quality Inspection status based on readings status ([d67b44f](d67b44fcec))
* Tax withholding related fixes ([32a9575](32a9575f07))
* **test:** `test_rejected_qi_validation` ([2763d06](2763d06307))
* TooManyWritesError during reposting of stock ([476175b](476175b307))

### Features

* cst ux improvement ([552c595](552c5951bd))
* **JE:** trigger account field when fetched from template ([baa4fec](baa4fec611)), closes [#32409](https://github.com/frappe/erpnext/issues/32409)
2022-10-12 07:21:47 +00:00
Ankush Menat
9ce765b268 Merge pull request #32561 from frappe/version-13-hotfix
chore: release v13
2022-10-12 12:49:45 +05:30
Ankush Menat
002ae8ae13 ci: disable test orchestrator v13 (#32574) 2022-10-12 12:13:51 +05:30
Deepesh Garg
558dc57b94 Merge pull request #32539 from frappe/mergify/bp/version-13-hotfix/pr-32536
fix: PO cancel post advance payment cancel against PO (backport #32536)
2022-10-11 13:58:24 +05:30
Deepesh Garg
cd942d36a8 chore: resolve conflicts 2022-10-11 10:16:31 +05:30
Sagar Sharma
3257533ee3 Merge pull request #32544 from frappe/mergify/bp/version-13-hotfix/pr-32497
chore: set `Quality Inspection` status based on readings status (backport #32497)
2022-10-10 12:10:29 +05:30
Sagar Sharma
2763d06307 fix(test): test_rejected_qi_validation
(cherry picked from commit 4992e4a2b8)
2022-10-10 05:21:09 +00:00
Sagar Sharma
a0772ea8d7 test: add test cases for Quality Inspection status
(cherry picked from commit fcc1272d42)
2022-10-10 05:21:08 +00:00
Sagar Sharma
d67b44fcec fix: set Quality Inspection status based on readings status
(cherry picked from commit 2657ece2cd)
2022-10-10 05:21:08 +00:00
Sagar Sharma
257a2a3d71 fix: make readings status mandatory in Quality Inspection
(cherry picked from commit d7c3b7633a)
2022-10-10 05:21:07 +00:00
Sagar Sharma
e6abbd1c83 chore: add Manual Inspection field in Quality Inspection DocType
(cherry picked from commit 39707757a6)
2022-10-10 05:21:06 +00:00
Deepesh Garg
41599cf29f fix: PO cancel post advance payment cancel against PO
(cherry picked from commit d806e32030)

# Conflicts:
#	erpnext/buying/doctype/purchase_order/purchase_order.py
2022-10-09 13:05:46 +00:00
Frappe PR Bot
c66ebcdf9a chore(release): Bumped to Version 13.39.5
## [13.39.5](https://github.com/frappe/erpnext/compare/v13.39.4...v13.39.5) (2022-10-07)

### Bug Fixes

* Do not add tax withheld vouchers post tax withheding in one document ([be404b7](be404b77a1))
* Tax withholding related fixes ([6e9b52d](6e9b52d268))
2022-10-07 13:08:29 +00:00
Deepesh Garg
4623b986a3 Merge pull request #32526 from frappe/mergify/bp/version-13/pr-32523
fix: Tax withholding related fixes (backport #32522) (backport #32523)
2022-10-07 18:36:57 +05:30
Deepesh Garg
611dd5c073 chore: resolve conflicts
(cherry picked from commit 2bf76f64bd)
2022-10-07 12:39:14 +00:00
Deepesh Garg
be404b77a1 fix: Do not add tax withheld vouchers post tax withheding in one document
(cherry picked from commit 781d160c68)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
(cherry picked from commit e1c41b9195)
2022-10-07 12:39:13 +00:00
Deepesh Garg
6e9b52d268 fix: Tax withholding related fixes
(cherry picked from commit abf5b6be3e)
(cherry picked from commit 32a9575f07)
2022-10-07 12:39:13 +00:00
Deepesh Garg
997990c69f Merge pull request #32523 from frappe/mergify/bp/version-13-hotfix/pr-32522
fix: Tax withholding related fixes (backport #32522)
2022-10-07 18:08:31 +05:30
Deepesh Garg
2bf76f64bd chore: resolve conflicts 2022-10-07 17:33:03 +05:30
Deepesh Garg
e1c41b9195 fix: Do not add tax withheld vouchers post tax withheding in one document
(cherry picked from commit 781d160c68)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2022-10-07 11:03:16 +00:00
Deepesh Garg
32a9575f07 fix: Tax withholding related fixes
(cherry picked from commit abf5b6be3e)
2022-10-07 11:03:15 +00:00
Deepesh Garg
e031e095dd Merge pull request #32521 from FHenry/13_fr_translation
chore: fr translation (backport #32385)
2022-10-07 08:48:43 +05:30
Florian HENRY
39ce3756c8 chore: fr translation 2022-10-06 22:39:40 +02:00
Deepesh Garg
f2515d9c9c Merge pull request #32449 from rtdany10/cst-ux-improvement
feat(ux): improved course scheduling tool
2022-10-05 18:44:05 +05:30
Deepesh Garg
27fe9c9179 Merge pull request #32426 from AnandBaburajan/fix_mark_attendance_joining_date_and_future
fix: mark attendance issue with joining and relieving date, and fix future attendance marking
2022-10-05 18:34:31 +05:30
Deepesh Garg
503183cb0b Merge pull request #32502 from frappe/mergify/bp/version-13-hotfix/pr-32499
fix: TooManyWritesError during reposting of stock (backport #32499)
2022-10-05 17:29:25 +05:30
Deepesh Garg
f1ea5de022 Merge pull request #32504 from frappe/mergify/bp/version-13-hotfix/pr-32478
feat(JE): trigger account field when fetched from template (backport #32478)
2022-10-05 17:29:05 +05:30
Dany Robert
baa4fec611 feat(JE): trigger account field when fetched from template
Closes #32409

(cherry picked from commit c35adcf5a1)
2022-10-05 10:38:21 +00:00
Rohit Waghchaure
476175b307 fix: TooManyWritesError during reposting of stock
(cherry picked from commit aaabba9b1e)
2022-10-05 10:35:55 +00:00
Frappe PR Bot
de584535e9 chore(release): Bumped to Version 13.39.4
## [13.39.4](https://github.com/frappe/erpnext/compare/v13.39.3...v13.39.4) (2022-10-04)

### Bug Fixes

* asset requiring maintenance sold status ([14ab9d9](14ab9d9158))
* conflict ([0f8e34e](0f8e34e972))
* Disbursement Account in patch to update old loans ([b4a511c](b4a511cbb4))
* e-Way bill JSON for Intra-state internal transfers ([b7fbf75](b7fbf75e10))
* fetch swift_number in payment_request ([6074570](60745705a8))
* Incorrect TCS amount deducted in Sales Invoice ([32456bf](32456bff30))
* Item details fetching on making transaction from item dashboard ([1aed76f](1aed76f778))
* linter issue ([4757a65](4757a65863))
* not able to return sold expired batches ([2fd4485](2fd4485f2f))
* payment reconciliation tool consider cost_center for JV ([9f98891](9f988910b5))
* payment request make bank field Link instead of Read Only ([299175e](299175e6fe))
* pick list picked-qty for batch item ([96a6db0](96a6db0422))
* SEZ Without Payment of Tax don't add tax rows ([a13eecc](a13eecc961))
* show `Make Purchase Invoice` button based on permission ([7124328](7124328640))
* typo in sales_register's filter mode_of_payment (backport [#32371](https://github.com/frappe/erpnext/issues/32371)) ([#32447](https://github.com/frappe/erpnext/issues/32447)) ([cdc8297](cdc8297083))
* update with new Frappe color. fix [#32455](https://github.com/frappe/erpnext/issues/32455) ([#32456](https://github.com/frappe/erpnext/issues/32456)) ([ad43b18](ad43b18ace))

### Reverts

* Revert "fix: fetch swift_number in payment_request" ([8251b84](8251b843ec))
2022-10-04 12:14:27 +00:00
Deepesh Garg
d95d234aa4 Merge pull request #32494 from frappe/version-13-hotfix
chore: release v13
2022-10-04 17:41:06 +05:30
rohitwaghchaure
3648745e5e Merge pull request #32470 from frappe/mergify/bp/version-13-hotfix/pr-32466
fix: not able to return sold expired batches (backport #32466)
2022-10-04 07:35:10 +05:30
Deepesh Garg
8e1e6a194b Merge pull request #32467 from frappe/mergify/bp/version-13-hotfix/pr-32394
fix: fetch swift number in payment request from bank doctype (backport #32394)
2022-10-03 21:54:05 +05:30
Ankush Menat
663e9b403f chore: codeowners 2022-10-03 16:27:32 +05:30
Ankush Menat
3219b7c766 chore: codeowners 2022-10-03 16:27:13 +05:30
Sagar Sharma
3a6e4c8da7 Merge pull request #32474 from frappe/mergify/bp/version-13-hotfix/pr-32472
fix: pick list picked-qty for batch item (backport #32472)
2022-10-03 15:24:02 +05:30
Sagar Sharma
96a6db0422 fix: pick list picked-qty for batch item
(cherry picked from commit ba02209f1d)
2022-10-03 09:17:03 +00:00
rohitwaghchaure
4757a65863 fix: linter issue 2022-10-03 13:27:38 +05:30
rohitwaghchaure
0f8e34e972 fix: conflict 2022-10-03 13:18:58 +05:30
Rohit Waghchaure
2fd4485f2f fix: not able to return sold expired batches
(cherry picked from commit 0b1727cf79)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
2022-10-03 07:46:13 +00:00
Maharshi Patel
299175e6fe fix: payment request make bank field Link instead of Read Only
(cherry picked from commit dc8d49260c)
2022-10-03 07:26:06 +00:00
Maharshi Patel
8251b843ec Revert "fix: fetch swift_number in payment_request"
This reverts commit f42a8e4e03.

(cherry picked from commit 9245d3b5cd)
2022-10-03 07:26:05 +00:00
Maharshi Patel
60745705a8 fix: fetch swift_number in payment_request
There isn't direct link between payment_request and bank so swift_number wasn't fetched using Fetch form. I fixed it by fetching swift_number on_change of bank_account.

(cherry picked from commit f42a8e4e03)
2022-10-03 07:26:04 +00:00
Deepesh Garg
caedc9f6ad Merge pull request #32462 from frappe/mergify/bp/version-13-hotfix/pr-32456
fix: update with new Frappe color. fix #32455 (backport #32456)
2022-10-03 09:15:21 +05:30
Deepesh Garg
fbeb86b9c0 Merge pull request #32453 from deepeshgarg007/intra_state_transfer_eway_bill_v13
fix: e-Way bill JSON for Intra-state internal transfers
2022-10-03 09:07:26 +05:30
Muvuk
ad43b18ace fix: update with new Frappe color. fix #32455 (#32456)
* Update with new Frappe color.

* refactor: use css variables

Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
(cherry picked from commit 73e5a7d671)
2022-10-02 17:02:25 +00:00
Frappe PR Bot
34284216cd chore(release): Bumped to Version 13.39.3
## [13.39.3](https://github.com/frappe/erpnext/compare/v13.39.2...v13.39.3) (2022-10-02)

### Bug Fixes

* asset requiring maintenance sold status ([a668d4e](a668d4e789))
2022-10-02 15:39:08 +00:00
Deepesh Garg
5c6c9812c0 Merge pull request #32458 from frappe/mergify/bp/version-13/pr-32413
fix: status of assets with maintenance_required changing back to 'Partially Depreciated' some time after being sold [v13] (backport #32413)
2022-10-02 21:07:00 +05:30
anandbaburajan
4afd2b7470 chore: refactor by just using a filter
(cherry picked from commit 6b21deedae)
2022-10-02 12:14:41 +00:00
anandbaburajan
bc21ce412b chore: refactor by creating is_sold
(cherry picked from commit 430a4c98a0)
2022-10-02 12:14:41 +00:00
anandbaburajan
a668d4e789 fix: asset requiring maintenance sold status
(cherry picked from commit 14ab9d9158)
2022-10-02 12:14:40 +00:00
Deepesh Garg
9f8d3e43ea Merge pull request #32413 from AnandBaburajan/fix_asset_sold_status_v13
fix: status of assets with maintenance_required changing back to 'Partially Depreciated' some time after being sold [v13]
2022-10-02 17:43:09 +05:30
Deepesh Garg
9dbb2bf512 Merge pull request #32369 from maharshivpatel/fix-taxes-sez-without-payment-of-tax
fix: SEZ Without Payment of Tax don't add tax rows
2022-10-01 16:13:11 +05:30
Deepesh Garg
8c52c71299 Merge pull request #32344 from maharshivpatel/fix-payment-reconciliation-jv-cost-center
fix: consider cost center for journal entry in payment reconciliation tool
2022-10-01 16:12:30 +05:30
Deepesh Garg
c4c52c1cd3 chore: Linting Issues 2022-10-01 16:06:31 +05:30
Deepesh Garg
b7fbf75e10 fix: e-Way bill JSON for Intra-state internal transfers 2022-10-01 15:58:31 +05:30
Dany Robert
6dabfbedf1 Merge branch 'version-13-hotfix' into cst-ux-improvement 2022-10-01 14:19:31 +05:30
Dany Robert
68c592377b chore: pre-commit 2022-09-30 23:41:01 -07:00
Deepesh Garg
d69d2217f6 Merge pull request #32431 from frappe/mergify/bp/version-13-hotfix/pr-32402
fix: Item details fetching on making transaction from item dashboard (backport #32402)
2022-10-01 12:05:26 +05:30
mergify[bot]
cdc8297083 fix: typo in sales_register's filter mode_of_payment (backport #32371) (#32447)
fix: typo in sales_register's filter mode_of_payment (#32371)
2022-10-01 12:04:40 +05:30
Dany Robert
f24f71f387 Merge branch 'version-13-hotfix' into cst-ux-improvement 2022-10-01 12:03:05 +05:30
Dany Robert
552c5951bd feat: cst ux improvement 2022-09-30 23:25:55 -07:00
Deepesh Garg
562025eb45 Merge branch 'version-13-hotfix' into fix-payment-reconciliation-jv-cost-center 2022-10-01 11:10:21 +05:30
Deepesh Garg
f0a37f545a chore: resolve conflicts 2022-10-01 11:02:40 +05:30
Deepesh Garg
001afb96ba Merge pull request #32435 from frappe/mergify/bp/version-13-hotfix/pr-32412
fix: Incorrect TCS amount deducted in Sales Invoice (backport #32412)
2022-10-01 11:01:05 +05:30
Deepesh Garg
61d3370527 chore: Remove print statements
(cherry picked from commit bff3cd9068)
2022-09-30 10:36:20 +00:00
Deepesh Garg
32456bff30 fix: Incorrect TCS amount deducted in Sales Invoice
(cherry picked from commit 08443c6421)
2022-09-30 10:36:20 +00:00
Deepesh Garg
1aed76f778 fix: Item details fetching on making transaction from item dashboard
(cherry picked from commit 0439e41a44)

# Conflicts:
#	erpnext/stock/doctype/item/item.js
2022-09-30 10:27:36 +00:00
anandbaburajan
308c400c6a chore: make linter happy 2022-09-30 15:33:34 +05:30
anandbaburajan
a9546dd01f fix: mark attendance issue with relieving date 2022-09-30 15:27:03 +05:30
anandbaburajan
cb4fbd5432 fix: future attendance marking 2022-09-30 14:48:30 +05:30
anandbaburajan
6f8d62088e fix: mark attendance issue with joining date 2022-09-30 14:46:57 +05:30
Anand Baburajan
5d66646fcd Merge branch 'version-13-hotfix' into fix_asset_sold_status_v13 2022-09-29 22:49:10 +05:30
Sagar Sharma
6a58d15497 Merge pull request #32419 from frappe/mergify/bp/version-13-hotfix/pr-32404
fix(ux): show `Make Purchase Invoice` button based on permission (backport #32404)
2022-09-29 17:16:15 +05:30
anandbaburajan
6b21deedae chore: refactor by just using a filter 2022-09-29 15:37:04 +05:30
Sagar Sharma
7124328640 fix: show Make Purchase Invoice button based on permission
(cherry picked from commit 80080a3d7b)
2022-09-29 09:27:03 +00:00
anandbaburajan
430a4c98a0 chore: refactor by creating is_sold 2022-09-29 08:59:49 +05:30
Anand Baburajan
c65fb64578 Merge branch 'version-13-hotfix' into fix_asset_sold_status_v13 2022-09-28 21:36:48 +05:30
anandbaburajan
14ab9d9158 fix: asset requiring maintenance sold status 2022-09-28 21:25:42 +05:30
Deepesh Garg
1095052479 Merge pull request #32410 from frappe/mergify/bp/version-13-hotfix/pr-32403
fix: Disbursement Account in patch to update old loans (backport #32403)
2022-09-28 20:13:45 +05:30
Deepesh Garg
b4a511cbb4 fix: Disbursement Account in patch to update old loans
(cherry picked from commit be623ce8e8)
2022-09-28 14:06:42 +00:00
Frappe PR Bot
a77388d520 chore(release): Bumped to Version 13.39.2
## [13.39.2](https://github.com/frappe/erpnext/compare/v13.39.1...v13.39.2) (2022-09-28)

### Bug Fixes

* `For Quantity` error msg in `Stock Entry` ([a194d28](a194d28b69))
* Add return against indexes for POS Invoice ([9e8e7aa](9e8e7aab70))
* Add return against indexes for POS Invoice ([6c528d4](6c528d469d))
* allow to return expired batches using purchase return ([02468a9](02468a902f))
* consider overproduction percentage for WO finish button ([ed4ac10](ed4ac100ba))
* difference amount calculation on payment reconciliation ([d68cdb4](d68cdb4f5e))
* don't count half day in absent days in Monthly Attendance Sheet summarized view ([#32399](https://github.com/frappe/erpnext/issues/32399)) ([255aa7a](255aa7a84a))
* **e-invoicing:** local variable 'res' referenced before assignment ([#32352](https://github.com/frappe/erpnext/issues/32352)) ([8f961ab](8f961abe8b))
* get amount in words for debit note ([0cd1cac](0cd1cacc29))
* GST Itemised Sales Register GSTIN filter ([#32367](https://github.com/frappe/erpnext/issues/32367)) ([988c5b9](988c5b95e6))
* item_code key error in production plan ([638d5e9](638d5e9dc3))
* Move subscription process to hourly long quque ([447c553](447c553954))
* opening entry causing discepancy between stock and trial balance ([70c68f0](70c68f011a))
* POS only validate QTY if is_stock_item ([ac8100f](ac8100f1e5))
* POS properly validate stock for bundle products ([96fa14b](96fa14be88))
* Reduce font size for Process Statement of accounts print/pdf ([1cfeb93](1cfeb9371c))
* remove no_copy for ignore_pricing_rule ([8abfdb6](8abfdb6598))
* total value in all keys ([80d046a](80d046a38c))
2022-09-28 10:10:58 +00:00
Deepesh Garg
eda6076a43 Merge pull request #32374 from frappe/version-13-hotfix
chore: release v13
2022-09-28 15:39:01 +05:30
Deepesh Garg
0b2405bbdf Merge pull request #32395 from frappe/mergify/bp/version-13-hotfix/pr-32379
fix: POS only validate QTY if is_stock_item (backport #32379)
2022-09-28 15:12:47 +05:30
Rucha Mahabal
255aa7a84a fix: don't count half day in absent days in Monthly Attendance Sheet summarized view (#32399) 2022-09-28 15:02:21 +05:30
Deepesh Garg
a604eed1b9 chore: Resolve conflicts 2022-09-28 14:49:25 +05:30
Maharshi Patel
96fa14be88 fix: POS properly validate stock for bundle products
Stock availability was not calculated properly for Product Bundle with non stock item so i have added logic to properly calculate that as well.

(cherry picked from commit e392ea1104)

# Conflicts:
#	erpnext/selling/page/point_of_sale/pos_item_details.js
2022-09-28 08:16:02 +00:00
Maharshi Patel
ac8100f1e5 fix: POS only validate QTY if is_stock_item
POS invoice raised " Item not available " validation error even though item is non_stock.

(cherry picked from commit e39e088f18)
2022-09-28 08:16:00 +00:00
Deepesh Garg
07cc05785e Merge pull request #32386 from frappe/mergify/bp/version-13-hotfix/pr-32382
fix: Move subscription process to hourly long queue (backport #32382)
2022-09-28 10:39:08 +05:30
Deepesh Garg
f03fbc0e6d chore: Resolve conflicts 2022-09-28 08:10:37 +05:30
Deepesh Garg
447c553954 fix: Move subscription process to hourly long quque
(cherry picked from commit 82a2f31ada)

# Conflicts:
#	erpnext/hooks.py
2022-09-27 18:09:32 +00:00
Deepesh Garg
b2e9dccc8c Merge pull request #32384 from frappe/mergify/bp/version-13-hotfix/pr-32378
fix: Add return against indexes for POS Invoice (backport #32378)
2022-09-27 23:34:50 +05:30
Deepesh Garg
9e8e7aab70 fix: Add return against indexes for POS Invoice
(cherry picked from commit cbfe28286a)
2022-09-27 16:52:59 +00:00
Deepesh Garg
6c528d469d fix: Add return against indexes for POS Invoice
(cherry picked from commit 1f6205e1ea)
2022-09-27 16:52:59 +00:00
Maharshi Patel
988c5b95e6 fix: GST Itemised Sales Register GSTIN filter (#32367)
fix: GST Itemised Sales Register GSTIN filte
2022-09-27 22:21:14 +05:30
Sagar Sharma
1f2887d601 Merge pull request #32381 from frappe/mergify/bp/version-13-hotfix/pr-32377
fix: consider overproduction percentage for WO finish button (backport #32377)
2022-09-27 18:51:37 +05:30
Sagar Sharma
ed4ac100ba fix: consider overproduction percentage for WO finish button
(cherry picked from commit 05392e0918)
2022-09-27 12:15:43 +00:00
Sagar Sharma
a194d28b69 fix: For Quantity error msg in Stock Entry
(cherry picked from commit 9049db41ae)
2022-09-27 12:15:42 +00:00
rohitwaghchaure
3217924242 Merge pull request #32373 from frappe/mergify/bp/version-13-hotfix/pr-32370
fix: Not allowing to return expired batches using purchase return (backport #32370)
2022-09-27 14:44:30 +05:30
Rohit Waghchaure
02468a902f fix: allow to return expired batches using purchase return
(cherry picked from commit a4a86ee23f)
2022-09-27 08:51:26 +00:00
Maharshi Patel
a13eecc961 fix: SEZ Without Payment of Tax don't add tax rows
taxes were added even when gst_category was SEZ and export_type was Without Payment of Tax
2022-09-27 13:40:04 +05:30
rohitwaghchaure
776ee53a25 Merge pull request #32358 from frappe/mergify/bp/version-13-hotfix/pr-32346
refactor: rewrite `Item Price Stock Report` queries in `QB` (backport #32346)
2022-09-27 10:44:05 +05:30
rohitwaghchaure
ddf5565c67 Merge pull request #32366 from frappe/mergify/bp/version-13-hotfix/pr-32339
fix: opening entry causing discrepancy between stock and trial balance (backport #32339)
2022-09-27 09:57:01 +05:30
Maharshi Patel
4152a9f026 Merge branch 'version-13-hotfix' into fix-payment-reconciliation-jv-cost-center 2022-09-26 23:03:39 +05:30
Saqib Ansari
8f961abe8b fix(e-invoicing): local variable 'res' referenced before assignment (#32352) 2022-09-26 22:42:07 +05:30
Rohit Waghchaure
70c68f011a fix: opening entry causing discepancy between stock and trial balance
(cherry picked from commit bc3ab45af2)
2022-09-26 15:03:48 +00:00
Sagar Sharma
9066009e89 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32346 2022-09-26 18:18:41 +05:30
Sagar Sharma
9332e7f96f Merge pull request #32360 from frappe/mergify/bp/version-13-hotfix/pr-32347
refactor: rewrite `Incorrect Stock Value Report` queries in `QB` (backport #32347)
2022-09-26 18:18:01 +05:30
Sagar Sharma
d6a335e59f refactor: rewrite Incorrect Stock Value Report queries in QB
(cherry picked from commit b93331e844)
2022-09-26 11:40:21 +00:00
Sagar Sharma
a66002f774 refactor: rewrite Item Price Stock Report queries in QB
(cherry picked from commit 22299d2382)
2022-09-26 11:39:24 +00:00
ruthra kumar
6eb3428f8e Merge pull request #32348 from frappe/mergify/bp/version-13-hotfix/pr-32303
fix: difference amount calculation and popup on payment reconciliation (backport #32303)
2022-09-26 14:18:09 +05:30
ruthra kumar
d158784472 Merge pull request #32350 from frappe/mergify/bp/version-13-hotfix/pr-32310
fix: total value in all keys (backport #32310)
2022-09-26 12:05:04 +05:30
nishibakabeer
80d046a38c fix: total value in all keys
Gross and net profit report showing wrong values in monthly quarterly and half yearly filters which is the total value
@ruthra-kumar added in develop branch as suggested ( https://github.com/frappe/erpnext/pull/32020)

(cherry picked from commit 6919f389aa)
2022-09-26 06:03:15 +00:00
ruthra kumar
d68cdb4f5e fix: difference amount calculation on payment reconciliation
(cherry picked from commit 122d5f2729)
2022-09-26 10:36:08 +05:30
Maharshi Patel
9f988910b5 fix: payment reconciliation tool consider cost_center for JV
We need to consider cost center in all four cases of get_conditions. I have removed check in if statement for get_invoices, get_payments, get_return_invoices as it is not required.
2022-09-25 23:24:59 +05:30
Deepesh Garg
09cd480c81 Merge pull request #32333 from frappe/mergify/bp/version-13-hotfix/pr-32117
fix: Reduce font size for Process Statement of accounts print/pdf (backport #32117)
2022-09-25 17:20:57 +05:30
Sagar Sharma
4777991a74 Merge pull request #32338 from frappe/mergify/bp/version-13-hotfix/pr-32324
refactor: rewrite `Production Planning Report` queries in `QB` (backport #32324)
2022-09-23 10:38:20 +05:30
Sagar Sharma
1301a6ff7f refactor: rewrite Production Planning Report queries in QB
(cherry picked from commit 8417b9b99c)
2022-09-23 04:20:42 +00:00
Sagar Sharma
a6a5f63af2 Merge pull request #32328 from s-aga-r/backport/v13-h/32309
fix: item_code key error in production plan (backport #32309)
2022-09-23 09:48:25 +05:30
Deepesh Garg
1cfeb9371c fix: Reduce font size for Process Statement of accounts print/pdf
(cherry picked from commit 6bfd193b0d)
2022-09-22 19:38:55 +00:00
Rohit Waghchaure
638d5e9dc3 fix: item_code key error in production plan 2022-09-22 18:09:12 +05:30
Sagar Sharma
b4ee72e15e Merge pull request #32316 from s-aga-r/backport/v13-h/32304
refactor: rewrite `Exponential Smoothing Forecasting` queries in `QB` (backport #32304)
2022-09-22 11:16:22 +05:30
Sagar Sharma
2a9b519773 Merge branch 'version-13-hotfix' into backport/v13-h/32304 2022-09-22 01:32:20 +05:30
Sagar Sharma
57136fa921 Merge pull request #32315 from s-aga-r/backport/v13-h/32153
refactor: rewrite Work Order Stock Report queries in QB (backport #32153)
2022-09-22 01:31:18 +05:30
Sagar Sharma
882542c2d5 Merge branch 'version-13-hotfix' into backport/v13-h/32153 2022-09-22 01:31:04 +05:30
Sagar Sharma
0a4025e7e0 Merge pull request #32314 from s-aga-r/backport/v13-h/32161
refactor: rewrite Process Loss Report queries in QB (backport #32161)
2022-09-22 01:30:40 +05:30
Sagar Sharma
54dfd50391 refactor: rewrite Exponential Smoothing Forecasting queries in QB 2022-09-21 21:27:04 +05:30
Sagar Sharma
45d02ceb4e refactor: rewrite Work Order Stock Report queries in QB 2022-09-21 21:20:03 +05:30
Sagar Sharma
f72bb18da7 refactor: rewrite Process Loss Report queries in QB 2022-09-21 21:13:10 +05:30
Deepesh Garg
f371008cd9 Merge pull request #32293 from frappe/mergify/bp/version-13-hotfix/pr-32284
fix: remove no_copy for ignore_pricing_rule (backport #32284)
2022-09-21 16:41:25 +05:30
Deepesh Garg
82e5a784cb Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32284 2022-09-21 13:08:41 +05:30
Deepesh Garg
d267372334 Merge pull request #32299 from frappe/mergify/bp/version-13-hotfix/pr-32296
fix: get amount in words for debit note (backport #32296)
2022-09-21 13:07:39 +05:30
Sagar Sharma
92c7d074dd Merge pull request #32307 from s-aga-r/backport/13/refactor/report/exponential-smoothing-forecasting
refactor: rewrite `BOM Variance Report` queries in `QB` (backport #32297)
2022-09-21 12:42:10 +05:30
Sagar Sharma
cedc8d28e4 refactor: rewrite BOM Variance Report queries in QB 2022-09-21 12:13:05 +05:30
Frappe PR Bot
be4fdca6c7 chore(release): Bumped to Version 13.39.1
## [13.39.1](https://github.com/frappe/erpnext/compare/v13.39.0...v13.39.1) (2022-09-20)

### Bug Fixes

* Add child table for tax withheld vouchers ([4165fee](4165fee6a7))
* Change Department fieldtype to Link in Leave Balance Report ([#32252](https://github.com/frappe/erpnext/issues/32252)) ([e2e69dc](e2e69dced7))
* dont show zero qty available items in stock ageing report ([37dbc70](37dbc7043a))
* fetch description only if empty on the payment schedule ([07a7fdb](07a7fdbe6c))
* Fetch vouchers to show in Invoice ([51d7c0b](51d7c0bfe4))
* incorrect gl if tax on multi currency payment entry ([d9d6a07](d9d6a07bbb))
* item wise sales register taxes and charges ([e65990e](e65990eb34))
* make `po_detail` or `sco_rm_detail` mandatory for SE `Send to Subcontractor` ([0329642](0329642116))
* Parent Level project linkning on creating PO from project ([3c3e3cf](3c3e3cfcf8))
* pending accrual entries ([ef86b43](ef86b437cb))
* production plan pending-qty ([2dcb35d](2dcb35da33))
* remove return pos from pos reconciliation tool ([e9bf74e](e9bf74e589))
* TDS deduction via journal entry ([ca0cce7](ca0cce7599))
* use default supplier currency if default supplier is enabled ([3c10e50](3c10e5066a))
* warehouse filter in `BOM Stock Calculated Report` ([96bf1e2](96bf1e2a0a))
2022-09-20 19:12:47 +00:00
Deepesh Garg
2694438163 Merge pull request #32291 from frappe/version-13-hotfix
chore: release v13
2022-09-21 00:41:03 +05:30
Deepesh Garg
d0bd78ddcd Merge pull request #32289 from frappe/mergify/bp/version-13-hotfix/pr-32204
fix(UX): More predictable tax withholding application in invoices (backport #32204)
2022-09-21 00:11:37 +05:30
Deepesh Garg
e2912caeae chore: Handle edge cases 2022-09-20 23:50:16 +05:30
Sagar Sharma
6f9c2e6c80 Merge pull request #32302 from frappe/mergify/bp/version-13-hotfix/pr-32295
refactor: rewrite `BOM Stock Report` queries in `QB` (backport #32295)
2022-09-20 23:10:19 +05:30
Sagar Sharma
96bf1e2a0a fix: warehouse filter in BOM Stock Calculated Report
(cherry picked from commit 390ce5719d)
2022-09-20 17:37:41 +00:00
Sagar Sharma
1f633b293d refactor: rewrite BOM Stock Report queries in QB
(cherry picked from commit 8fd7c04920)
2022-09-20 17:37:40 +00:00
ruthra kumar
0cd1cacc29 fix: get amount in words for debit note
(cherry picked from commit 70f6484d9d)
2022-09-20 12:43:45 +00:00
Deepesh Garg
21154c8bee chore: fix tests 2022-09-20 17:52:37 +05:30
ruthra kumar
9270e58969 Merge pull request #32277 from frappe/remove_return_pos_from_reconciliation_tool
fix: remove return pos from pos reconciliation tool
2022-09-20 17:20:25 +05:30
Deepesh Garg
de8f44bbff chore: Resolve conflicts 2022-09-20 16:42:30 +05:30
ruthra kumar
e9bf74e589 fix: remove return pos from pos reconciliation tool 2022-09-20 16:41:28 +05:30
Maharshi Patel
8abfdb6598 fix: remove no_copy for ignore_pricing_rule
(cherry picked from commit 8c5b420aea)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
#	erpnext/buying/doctype/purchase_order/purchase_order.json
#	erpnext/selling/doctype/quotation/quotation.json
#	erpnext/stock/doctype/purchase_receipt/purchase_receipt.json
2022-09-20 10:49:59 +00:00
Nabin Hait
305693b562 Merge pull request #32281 from maharshivpatel/fix-item-wise-sales-register-v13
fix: item wise sales register taxes and charges
2022-09-20 14:56:23 +05:30
Deepesh Garg
794eeebabc chore: resolve conflicts 2022-09-20 14:48:06 +05:30
Deepesh Garg
75768d780f Merge pull request #32282 from frappe/mergify/bp/version-13-hotfix/pr-32217
fix: incorrect gl if tax on multi currency payment entry (backport #32217)
2022-09-20 14:39:37 +05:30
Deepesh Garg
fe252b48f7 chore: fix tests
(cherry picked from commit 9aa1f84d45)
2022-09-20 09:07:06 +00:00
Deepesh Garg
ca0cce7599 fix: TDS deduction via journal entry
(cherry picked from commit 36d0906ea2)
2022-09-20 09:07:05 +00:00
Deepesh Garg
e07fd46a46 test: Add tests
(cherry picked from commit b6184ce471)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2022-09-20 09:07:04 +00:00
Deepesh Garg
51d7c0bfe4 fix: Fetch vouchers to show in Invoice
(cherry picked from commit 3fb1595a4e)
2022-09-20 09:07:03 +00:00
Deepesh Garg
4165fee6a7 fix: Add child table for tax withheld vouchers
(cherry picked from commit 246c1a9380)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.json
2022-09-20 09:07:02 +00:00
Deepesh Garg
d251ef9ce5 Merge pull request #32279 from frappe/mergify/bp/version-13-hotfix/pr-32235
fix: fetch description only if empty on the payment schedule (backport #32235)
2022-09-20 14:35:35 +05:30
Sagar Sharma
afda4bdb17 Merge pull request #32286 from frappe/mergify/bp/version-13-hotfix/pr-32280
refactor: rewrite `Item Shortage Report` queries in QB (backport #32280)
2022-09-20 11:43:41 +05:30
Sagar Sharma
c4452360da test: add test cases for Item Shortage Report
(cherry picked from commit 3dc754cac2)
2022-09-20 05:45:29 +00:00
Sagar Sharma
13527d6154 refactor: rewrite Item Shortage Report queries in QB
(cherry picked from commit f0a78aa559)
2022-09-20 05:45:28 +00:00
ruthra kumar
5c0a46110e test: gl entries of payments with advance tax
(cherry picked from commit 5bd5dd7262)
2022-09-20 11:09:37 +05:30
ruthra kumar
d9d6a07bbb fix: incorrect gl if tax on multi currency payment entry
(cherry picked from commit f0ae77b23b)
2022-09-20 04:30:42 +00:00
Maharshi Patel
e65990eb34 fix: item wise sales register taxes and charges
I have added a separate column for other charges. Instead of adding all values to tax_total, it checks if account_type is tax, and then only it adds to total_tax otherwise it adds to the total_other_charges.
2022-09-20 09:47:47 +05:30
Maharshi Patel
07a7fdbe6c fix: fetch description only if empty on the payment schedule
added fetch_if_empty on description field of payment_schedule.

(cherry picked from commit f4b64686ae)
2022-09-20 03:44:50 +00:00
Sagar Sharma
2fca8b541e Merge pull request #32261 from frappe/mergify/bp/version-13-hotfix/pr-32250
fix: make `po_detail` or `sco_rm_detail` mandatory for SE Send to Subcontractor (backport #32250)
2022-09-19 19:53:57 +05:30
Sagar Sharma
7fc460bb32 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32250 2022-09-19 19:22:31 +05:30
Solufyin
e2e69dced7 fix: Change Department fieldtype to Link in Leave Balance Report (#32252)
Co-authored-by: Nihantra C. Patel <n.patel.serpentcs@gmail.com>
2022-09-19 15:42:05 +05:30
Deepesh Garg
5e49b6ea0f Merge pull request #32269 from frappe/mergify/bp/version-13-hotfix/pr-32251
fix: use default supplier currency if default supplier is enabled (backport #32251)
2022-09-19 15:20:44 +05:30
Ritwik Puri
2e3445fad9 chore: patch for removing stale values in Naming Series (#32271) 2022-09-19 13:35:08 +05:30
ruthra kumar
3c10e5066a fix: use default supplier currency if default supplier is enabled
(cherry picked from commit 77fdc37cb7)
2022-09-19 07:32:58 +00:00
Sagar Sharma
e8d2e49155 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32250 2022-09-18 20:30:21 +05:30
Deepesh Garg
5690e9771a Merge pull request #32256 from frappe/mergify/bp/version-13-hotfix/pr-32244
fix: Parent Level project linkning on creating PO from project (backport #32244)
2022-09-18 19:41:57 +05:30
Sagar Sharma
ec6cac8043 chore: conflicts 2022-09-18 16:38:09 +05:30
Sagar Sharma
0329642116 fix: make po_detail or sco_rm_detail mandatory for SE Send to Subcontractor
(cherry picked from commit b90875575c)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/stock_entry.py
2022-09-18 09:25:10 +00:00
Deepesh Garg
3c3e3cfcf8 fix: Parent Level project linkning on creating PO from project
(cherry picked from commit 93e134aab0)
2022-09-17 15:00:56 +00:00
Sagar Sharma
7c4f5fa5c5 Merge pull request #32241 from frappe/mergify/bp/version-13-hotfix/pr-32236
fix: production plan pending-qty (backport #32236)
2022-09-16 20:43:28 +05:30
Sagar Sharma
367e05f808 test: update test case for production plan pending-qty
(cherry picked from commit bd6af7c613)
2022-09-16 13:00:59 +00:00
Sagar Sharma
2dcb35da33 fix: production plan pending-qty
(cherry picked from commit 5be7d42dfd)
2022-09-16 13:00:58 +00:00
Sagar Sharma
94732479f5 Merge pull request #32237 from frappe/mergify/bp/version-13-hotfix/pr-32233
refactor: rewrite Production Plan queries in QB (backport #32233)
2022-09-16 17:35:38 +05:30
Sagar Sharma
b4dec4630d chore: conflicts 2022-09-16 17:08:35 +05:30
Sagar Sharma
c415a47d25 refactor: rewrite Production Plan queries in QB
(cherry picked from commit b8cf3b4c77)

# Conflicts:
#	erpnext/manufacturing/doctype/production_plan/production_plan.py
2022-09-16 09:30:11 +00:00
rohitwaghchaure
1e0cc65c61 Merge pull request #32220 from frappe/mergify/bp/version-13-hotfix/pr-31681
fix: dont show zero qty available items in stock ageing report (backport #31681)
2022-09-15 12:39:22 +05:30
Rohit Waghchaure
37dbc7043a fix: dont show zero qty available items in stock ageing report
(cherry picked from commit 5da7e01db2)
2022-09-15 06:01:10 +00:00
Deepesh Garg
0e88496607 Merge pull request #32209 from frappe/mergify/bp/version-13-hotfix/pr-32208
fix: Loans pending accrual entries (backport #32208)
2022-09-14 15:34:10 +05:30
Abhinav Raut
ef86b437cb fix: pending accrual entries
(cherry picked from commit f2209045f8)
2022-09-14 08:45:27 +00:00
Frappe PR Bot
47aa191004 chore(release): Bumped to Version 13.39.0
# [13.39.0](https://github.com/frappe/erpnext/compare/v13.38.0...v13.39.0) (2022-09-13)

### Bug Fixes

* add missing warehouse filter in BOM Stock Calculated report ([ab32c09](ab32c09ff9))
* calculate amount based on payment days for statistical components too ([3f99522](3f99522764))
* conflict ([6f2a567](6f2a567c95))
* linter ([e177f1e](e177f1e51b))
* Loan amount post write off ([e78a767](e78a7679a4))
* option to start reposting from repost item valuation ([a1826f2](a1826f215a))
* pick_list - picked qty getting set to 1 ([3256e2b](3256e2b8b7))
* Purchase Order creation from Sales Order ([d79aacd](d79aacd1cb))
* Rate for internal PI have non stock UOM items ([638d6b7](638d6b7177))
* reposting not working for internal transferred purchase receipt ([bb41d8b](bb41d8bc47))
* require barcode item barcode ([#32112](https://github.com/frappe/erpnext/issues/32112)) ([44c3a32](44c3a322d3)), closes [#31957](https://github.com/frappe/erpnext/issues/31957)
* required_qty in BOM Stock Calculated report ([f2e63bc](f2e63bc491))
* **Salary Slip:** set default amount to 0 if None ([#32184](https://github.com/frappe/erpnext/issues/32184)) ([d29a033](d29a033c09))

### Features

* Ability to manually update loan amount in Salary Slips ([ac320e4](ac320e4d55))
2022-09-13 11:15:15 +00:00
Deepesh Garg
5840913320 Merge pull request #32200 from frappe/version-13-hotfix
chore: release v13
2022-09-13 16:43:21 +05:30
Deepesh Garg
b7b0076743 Merge pull request #32194 from deepeshgarg007/loan_amount_post_write_off
fix: Loan amount post write off
2022-09-13 13:41:21 +05:30
Deepesh Garg
ef5dd1d693 Merge pull request #32165 from frappe/mergify/bp/version-13-hotfix/pr-32144
fix: Rate for internal PI have non stock UOM items (backport #32144)
2022-09-13 12:02:12 +05:30
Deepesh Garg
a53b40ba93 chore: Remove print 2022-09-13 12:00:06 +05:30
Deepesh Garg
e78a7679a4 fix: Loan amount post write off 2022-09-13 11:53:11 +05:30
Deepesh Garg
6a5beecb36 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-32144 2022-09-13 09:39:37 +05:30
Rucha Mahabal
2b900e2f0e Merge pull request #32187 from ruchamahabal/stat-comp-pd
fix: calculate amount based on payment days for statistical components too
2022-09-13 02:09:39 +05:30
Rucha Mahabal
bc14dbbcad refactor(tests): add a test utility file for commonly used functions in tests 2022-09-13 01:42:27 +05:30
Rucha Mahabal
f4e53a5c91 test: statistical component based on payment days 2022-09-13 00:59:59 +05:30
Rucha Mahabal
3f99522764 fix: calculate amount based on payment days for statistical components too 2022-09-13 00:59:03 +05:30
Sagar Sharma
81dd9722fe Merge pull request #32179 from Havenir/fix-picklist-picked-qty
fix: pick_list - picked qty getting set to 1
2022-09-12 22:19:26 +05:30
Sagar Sharma
9c5d335360 Merge pull request #32186 from frappe/mergify/bp/version-13-hotfix/pr-32150
refactor: BOM Stock Calculated report, fix required-qty (backport #32150)
2022-09-12 19:48:38 +05:30
Sagar Sharma
c5c28615f5 test: add test cases for BOM Stock Calculated report
(cherry picked from commit e1a98c1ff7)
2022-09-12 13:52:31 +00:00
Sagar Sharma
ab32c09ff9 fix: add missing warehouse filter in BOM Stock Calculated report
(cherry picked from commit 7a968a5f0d)
2022-09-12 13:52:30 +00:00
Sagar Sharma
f2e63bc491 fix: required_qty in BOM Stock Calculated report
(cherry picked from commit 56192daabf)
2022-09-12 13:52:30 +00:00
Sagar Sharma
882aa96973 refactor: BOM Stock Calculated report
(cherry picked from commit 723fa9eebc)
2022-09-12 13:52:29 +00:00
Rucha Mahabal
d29a033c09 fix(Salary Slip): set default amount to 0 if None (#32184) 2022-09-12 19:21:58 +05:30
Deepesh Garg
b3125a56ed Merge pull request #32178 from deepeshgarg007/manual_update_loan_amount
feat: Ability to manually update loan amount in Salary Slips
2022-09-12 17:41:02 +05:30
rohitwaghchaure
adfc57487b Merge pull request #32167 from frappe/mergify/bp/version-13-hotfix/pr-32118
fix: option to start reposting from repost item valuation (backport #32118)
2022-09-12 16:16:26 +05:30
Deepesh Garg
ac320e4d55 feat: Ability to manually update loan amount in Salary Slips 2022-09-12 15:05:42 +05:30
Ahmad
3256e2b8b7 fix: pick_list - picked qty getting set to 1 2022-09-12 14:23:44 +05:00
mergify[bot]
b4ec4ccc56 chore: correct license text for GPLv3 (backport #32170) (#32172)
* chore: correct license text for GPLv3 (#32170)

[skip ci]



Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-09-12 14:00:14 +05:30
Rohit Waghchaure
a1826f215a fix: option to start reposting from repost item valuation
(cherry picked from commit f1c4aea7b5)
2022-09-12 06:44:59 +00:00
Deepesh Garg
181c0acf99 Merge pull request #32127 from SolufyPrivateLimited/Solufy-so-to-po-v13
fix: Purchase Order creation from Sales Order
2022-09-12 09:25:24 +05:30
Deepesh Garg
638d6b7177 fix: Rate for internal PI have non stock UOM items
(cherry picked from commit 0f655e4430)
2022-09-12 03:40:23 +00:00
rohitwaghchaure
f5132411eb Merge pull request #32152 from frappe/mergify/bp/version-13-hotfix/pr-32135
fix: reposting not working for internal transferred purchase receipt (backport #32135)
2022-09-10 23:29:56 +05:30
rohitwaghchaure
e177f1e51b fix: linter 2022-09-10 23:01:48 +05:30
rohitwaghchaure
6f2a567c95 fix: conflict 2022-09-10 16:41:39 +05:30
Rohit Waghchaure
bb41d8bc47 fix: reposting not working for internal transferred purchase receipt
(cherry picked from commit a03b4ce213)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2022-09-09 17:13:21 +00:00
Nihantra C. Patel
d79aacd1cb fix: Purchase Order creation from Sales Order 2022-09-08 13:51:11 +05:30
Sagar Sharma
44c3a322d3 fix: require barcode item barcode (#32112)
fix: require barcode item barcode. (#31957)

* fix: require barcode item barcode.

* fix: make supplier mandatory in Item Supplier DocType

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>

Co-authored-by: Devin Slauenwhite <devin.slauenwhite@gmail.com>
2022-09-07 14:24:53 +05:30
Frappe PR Bot
2af489d69d chore(release): Bumped to Version 13.38.0
# [13.38.0](https://github.com/frappe/erpnext/compare/v13.37.0...v13.38.0) (2022-09-06)

### Bug Fixes

* consider Stock Entry purpose while getting total supplied qty ([8964612](8964612b8e))
* force delete old report docs (backport [#32026](https://github.com/frappe/erpnext/issues/32026)) ([#32028](https://github.com/frappe/erpnext/issues/32028)) ([0f1f67d](0f1f67dcae))
* incorrect import parameter for cancel PDA ([814dd36](814dd36a3e))
* key error on consolidated financial report ([20919c8](20919c8626))
* KSA VAT report multi currency amount issue ([56d8962](56d8962e40))
* Loan Interest accruals for 0 rated loans ([a369852](a3698524ca))
* lost quotation not to expired ([ea995de](ea995de4a3))
* Naming series in Journal Entry Template ([66cb3fd](66cb3fd63f))
* **pos:** error while consolidating pos invoices ([0527393](0527393b09))
* QR Code multi currency issue ([b10a2b8](b10a2b87b6))

### Features

* better Item Price list view ([#31954](https://github.com/frappe/erpnext/issues/31954)) ([25d2847](25d2847881))
2022-09-06 16:05:26 +00:00
Deepesh Garg
bb1c450c33 Merge pull request #32104 from frappe/version-13-hotfix
chore: release v13
2022-09-06 21:33:13 +05:30
Sagar Sharma
5707118d58 Merge pull request #32099 from s-aga-r/fix/stock-entry/send-to-subcontractor
fix: consider Stock Entry purpose while getting total supplied qty
2022-09-06 15:49:38 +05:30
Sagar Sharma
8964612b8e fix: consider Stock Entry purpose while getting total supplied qty 2022-09-06 13:04:03 +05:30
Deepesh Garg
514d280ee7 Merge pull request #32086 from Havenir/qr_code_multi_currency_issue
fix: QR Code multi currency issue
2022-09-05 12:42:43 +05:30
hamzaali15
b10a2b87b6 fix: QR Code multi currency issue
When try to scan qr code on app it is showing correct values for multi currencies because it is not getting base amount
2022-09-05 11:15:43 +05:00
Deepesh Garg
3664a12bb9 Merge pull request #32078 from frappe/mergify/bp/version-13-hotfix/pr-31954
feat: better Item Price list view (backport #31954)
2022-09-04 18:15:13 +05:30
Deepesh Garg
0605cbf26b Merge pull request #32076 from frappe/mergify/bp/version-13-hotfix/pr-32045
fix: Naming series in Journal Entry Template (backport #32045)
2022-09-04 18:14:40 +05:30
HENRY Florian
25d2847881 feat: better Item Price list view (#31954)
* feat: better Item Price list view

(cherry picked from commit 86395c6adb)
2022-09-04 12:38:43 +00:00
Solufyin
66cb3fd63f fix: Naming series in Journal Entry Template
(cherry picked from commit 2085626390)
2022-09-04 11:04:44 +00:00
Deepesh Garg
d22104ad40 Merge pull request #32072 from frappe/mergify/bp/version-13-hotfix/pr-31822
fix(pos): error while consolidating pos invoices (backport #31822)
2022-09-04 15:57:37 +05:30
Saqib Ansari
0527393b09 fix(pos): error while consolidating pos invoices
(cherry picked from commit 33762dbbac)
2022-09-04 07:56:06 +00:00
Deepesh Garg
741d6fcb9a Merge pull request #32053 from Havenir/version-13-hotfix
fix: KSA VAT report multi currency amount issue
2022-09-04 13:12:21 +05:30
ruthra kumar
1870dbf9a8 Merge pull request #32059 from frappe/mergify/bp/version-13-hotfix/pr-32054
fix: type error on cancellation of Process Deferred Accounting (backport #32054)
2022-09-02 17:10:01 +05:30
ruthra kumar
69a9724422 test: pda document submission and cancellation
(cherry picked from commit 1c385541fa)
2022-09-02 11:15:13 +00:00
ruthra kumar
814dd36a3e fix: incorrect import parameter for cancel PDA
(cherry picked from commit 08f2e4edc3)
2022-09-02 11:15:12 +00:00
ruthra kumar
17ad96998e Merge pull request #32057 from frappe/mergify/bp/version-13-hotfix/pr-32052
fix: key error on consolidated financial report (backport #32052)
2022-09-02 16:41:56 +05:30
ruthra kumar
20919c8626 fix: key error on consolidated financial report
accounts with same name but different account number will throw key
error on consolidated report

(cherry picked from commit 6e8395cccd)
2022-09-02 10:46:23 +00:00
hamzaali15
56d8962e40 fix: KSA VAT report multi currency amount issue
In KSA VAT report amount is not showing correctly for multi currencies because net_amount field is fetched instead of base_net_amount
2022-09-01 15:02:21 +05:00
Deepesh Garg
0a3ac82232 Merge pull request #32031 from frappe/mergify/bp/version-13-hotfix/pr-32030
fix: Loan Interest accruals for 0 rated loans (backport #32030)
2022-08-31 21:04:27 +05:30
Deepesh Garg
b736df3f0b Merge pull request #32036 from niyazrazak/patch-5
fix: lost quotation not to expired
2022-08-31 21:03:31 +05:30
MOHAMMED NIYAS
ea995de4a3 fix: lost quotation not to expired
code is merged in version-14 and conflict in version 13
2022-08-31 15:31:07 +05:30
Deepesh Garg
b7c94e38a6 chore: Add check for principal amount
(cherry picked from commit a76d3827ec)
2022-08-30 15:46:39 +00:00
Deepesh Garg
a3698524ca fix: Loan Interest accruals for 0 rated loans
(cherry picked from commit eefc9b7172)
2022-08-30 15:46:38 +00:00
mergify[bot]
0f1f67dcae fix: force delete old report docs (backport #32026) (#32028)
fix: force delete old report docs (#32026)

(cherry picked from commit ffa3071d36)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-08-30 15:45:47 +05:30
Frappe PR Bot
11b04acf8b chore(release): Bumped to Version 13.37.0
# [13.37.0](https://github.com/frappe/erpnext/compare/v13.36.5...v13.37.0) (2022-08-30)

### Bug Fixes

* Add docstatus filter for voucher_no in Repost Item Valuation ([2cf2885](2cf2885470))
* Cash and non trade discount calculation ([20e9599](20e9599fc1))
* do not clear promotion/transfer details if doc is amended ([#32000](https://github.com/frappe/erpnext/issues/32000)) ([074d484](074d484d3c))
* filter leave types and render leave application dashboard w/o from date ([#32001](https://github.com/frappe/erpnext/issues/32001)) ([7686c9e](7686c9e450))
* Loan Write-off for term loans ([e64e812](e64e812679))
* **minor:** don't print tax rate if its '0' ([#31838](https://github.com/frappe/erpnext/issues/31838)) ([a46dca5](a46dca57cb))
* permissions for Task Type ([#32016](https://github.com/frappe/erpnext/issues/32016)) ([1157bf8](1157bf887f))
* **pos:** edge case while closing pos (backport [#31748](https://github.com/frappe/erpnext/issues/31748)) ([#31893](https://github.com/frappe/erpnext/issues/31893)) ([261405c](261405cec1))
* Purposes not set ([edfaf99](edfaf99388))
* Route condition set for stock ledger (backport [#31935](https://github.com/frappe/erpnext/issues/31935)) ([#31946](https://github.com/frappe/erpnext/issues/31946)) ([34537c9](34537c9dc2))
* Set the condition to create a purchase receipt ([b4c992d](b4c992dd4d))
* Test cases ([7c85b48](7c85b487cd))

### Features

* In BOM,  Operation time can be fix (backport [#27063](https://github.com/frappe/erpnext/issues/27063)) ([#31923](https://github.com/frappe/erpnext/issues/31923)) ([c2b8d1b](c2b8d1bd9a))
2022-08-30 08:05:05 +00:00
Deepesh Garg
4c1156a816 Merge pull request #32023 from frappe/version-13-hotfix
chore: weekly version 13 release
2022-08-30 13:32:35 +05:30
Deepesh Garg
570729b73e Merge pull request #32024 from frappe/mergify/bp/version-13-hotfix/pr-31838
fix(minor): don't print tax rate if its '0' (backport #31838)
2022-08-30 13:32:16 +05:30
ruthra kumar
a46dca57cb fix(minor): don't print tax rate if its '0' (#31838)
(cherry picked from commit 3b4c0a3fc0)
2022-08-30 07:34:26 +00:00
Deepesh Garg
821c1cddfc Merge pull request #32011 from deepeshgarg007/loan_write_off_salary_slip
fix: Loan Write-off for term loans
2022-08-30 11:36:09 +05:30
Deepesh Garg
8217c6dd9f chore: Linting issues and test case fixes 2022-08-30 10:24:31 +05:30
Deepesh Garg
fc030a7de9 Merge pull request #32018 from frappe/mergify/bp/version-13-hotfix/pr-32016
fix: permissions for Task Type (backport #32016)
2022-08-30 08:38:25 +05:30
Raffael Meyer
1157bf887f fix: permissions for Task Type (#32016)
(cherry picked from commit 73f4d5931d)
2022-08-29 16:27:24 +00:00
Deepesh Garg
e64e812679 fix: Loan Write-off for term loans 2022-08-29 18:33:40 +05:30
Deepesh Garg
6025df97ef Merge pull request #31931 from frappe/mergify/bp/version-13-hotfix/pr-31910
fix: Cash and non trade discount calculation (backport #31910)
2022-08-29 15:06:00 +05:30
Deepesh Garg
4793adfefd chore: rounded total for cash and non trade discounts 2022-08-29 14:02:18 +05:30
Rucha Mahabal
7686c9e450 fix: filter leave types and render leave application dashboard w/o from date (#32001) 2022-08-29 12:26:05 +05:30
Rucha Mahabal
074d484d3c fix: do not clear promotion/transfer details if doc is amended (#32000) 2022-08-29 12:10:15 +05:30
Deepesh Garg
332e86af7e Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31910 2022-08-28 17:32:41 +05:30
Deepesh Garg
8eded437d2 Merge pull request #31971 from frappe/mergify/bp/version-13-hotfix/pr-31955
chore: update french translation (backport #31955)
2022-08-28 11:32:34 +05:30
Deepesh Garg
bef7f6114d Merge pull request #31989 from frappe/mergify/bp/version-13-hotfix/pr-31988
chore: remove precision on discount_percentage of Sales Invoice Item (backport #31988)
2022-08-28 11:32:14 +05:30
Deepesh Garg
4095a3dae2 chore: Resolve conflicts 2022-08-26 18:10:09 +05:30
ruthra kumar
0b40117bfd chore: remove precision on discount_percentage of Sales Invoice Item
(cherry picked from commit c42fef541a)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice_item/sales_invoice_item.json
2022-08-26 10:34:31 +00:00
ruthra kumar
09de1cba92 Merge pull request #31972 from frappe/mergify/bp/version-13-hotfix/pr-31934
refactor: disable discount accounting on Buying module(PI) (backport #31934)
2022-08-25 17:14:44 +05:30
ruthra kumar
51a40ad2fc test: remove discount accounting tests
(cherry picked from commit 277ef04b60)
2022-08-25 16:05:01 +05:30
mergify[bot]
261405cec1 fix(pos): edge case while closing pos (backport #31748) (#31893) 2022-08-25 14:50:24 +05:30
ruthra kumar
1ac9d7f43e refactor: disable discount accounting on Buying module(PI)
(cherry picked from commit a956e20f29)
2022-08-25 14:44:54 +05:30
Florian HENRY
69b3145be4 chore: update fr translation
(cherry picked from commit 299da5d596)
2022-08-25 07:37:26 +00:00
Florian HENRY
5e1d367d7a chore: update fr translation
(cherry picked from commit 1f6f2747d4)
2022-08-25 07:37:25 +00:00
Florian HENRY
10f0baf6ad chore: update french translation
(cherry picked from commit 264f98af14)
2022-08-25 07:37:25 +00:00
Deepesh Garg
20694eb509 Merge pull request #31965 from frappe/mergify/bp/version-13-hotfix/pr-31909
fix: Add docstatus filter for voucher_no in Repost Item Valuation (backport #31909)
2022-08-25 11:25:14 +05:30
HENRY Florian
c2b8d1bd9a feat: In BOM, Operation time can be fix (backport #27063) (#31923)
* feat: In BOM Operation time can be fix (backport #27063)

* chore: only changes necessary for feature

* chore: add test

* chore: linter

* chore: linter

* chore: linter

* chore: fix date in json

* chore: fix test order

* chore: revert test from version-13 not develop

* chore: make test ok
2022-08-25 11:14:35 +05:30
rohitwaghchaure
49bf05c1c2 Merge pull request #31962 from frappe/mergify/bp/version-13-hotfix/pr-31951
fix: Purposes not set in Maintenance Visit (backport #31951)
2022-08-25 10:51:12 +05:30
Sagar Sharma
2cf2885470 fix: Add docstatus filter for voucher_no in Repost Item Valuation
(cherry picked from commit 520306dc87)
2022-08-25 05:20:46 +00:00
Rohit Waghchaure
edfaf99388 fix: Purposes not set
(cherry picked from commit f9a7b31b5b)
2022-08-25 05:19:36 +00:00
Deepesh Garg
3a7a53ab72 Merge pull request #31919 from SolufyPrivateLimited/Solufy-pur_inv_docstatus
fix: Set the condition to create a purchase receipt
2022-08-25 10:35:14 +05:30
mergify[bot]
34537c9dc2 fix: Route condition set for stock ledger (backport #31935) (#31946)
fix: Route condition set for stock ledger (#31935)

(cherry picked from commit 0e26df331c)

Co-authored-by: Solufyin <34390782+Solufyin@users.noreply.github.com>
2022-08-24 13:30:49 +05:30
Frappe PR Bot
f6248d0259 chore(release): Bumped to Version 13.36.5
## [13.36.5](https://github.com/frappe/erpnext/compare/v13.36.4...v13.36.5) (2022-08-23)

### Bug Fixes

* added employee name to call log ([476ded2](476ded2972))
* added field to show called group, user_id ([66578a5](66578a58cf))
* added tests ([aa8a063](aa8a063103))
* added type of call select field, additional status for agent rejecting call ([b65bce8](b65bce8f98))
* call status fix ([ffb1196](ffb1196516))
* call type doctype, fixes ([b94154f](b94154f00a))
* Handle exception where no employee is returned ([baab96d](baab96d02c))
* incorrect buying amount in Gross Profit rpt ([6405a93](6405a9378d))
* incorrect tax amt due to different exchange rate in PR and PI ([ba5ee1c](ba5ee1ca96))
* interview rescheduling not working ([a482840](a4828407d0))
* limit pos recent order page result ([9751f10](9751f1060e))
* linter, sider fixes ([b529627](b52962751c))
* **minor:** save the employee doc on promotion/transfer update ([36130c6](36130c6292))
* process loan interest accrual ([acbed43](acbed434c2))
* Replace walrus operator ([23a4412](23a441252b))
* sider fixes ([90ed14a](90ed14a055))
* TDS calculation for advance payment ([a452143](a452143782))
* term loan interest calculation ([8dea238](8dea238d12))
* Update received_by if "to" is changed ([9263d5f](9263d5ff4d))
* used get_employees_with_number, strip_number methods ([3f46b2a](3f46b2a0ce))
2022-08-23 13:37:34 +00:00
Deepesh Garg
4e6ef5d6fa Merge pull request #31939 from frappe/version-13-hotfix
chore: Weekly version 13 release
2022-08-23 19:05:53 +05:30
mergify[bot]
154adcbb58 chore: add Work Order test dependencies (backport #31936) (#31938)
chore: add Work Order test dependencies (#31936)

(cherry picked from commit fe73d55f70)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2022-08-23 16:10:27 +05:30
Deepesh Garg
6a9d13ff28 chore: Linting issues
(cherry picked from commit 1cb7ae16ab)
2022-08-23 04:50:19 +00:00
Deepesh Garg
7c85b487cd fix: Test cases
(cherry picked from commit ae3dce0cbd)
2022-08-23 04:50:18 +00:00
Deepesh Garg
20e9599fc1 fix: Cash and non trade discount calculation
(cherry picked from commit 3b15966cc9)
2022-08-23 04:50:17 +00:00
Solufyin
b4c992dd4d fix: Set the condition to create a purchase receipt 2022-08-22 12:00:21 +05:30
Suraj Shetty
d46ce05dcd Merge pull request #31903 from frappe/exotel_fixes_v13 2022-08-22 10:52:18 +05:30
Deepesh Garg
6bc6681f92 Merge pull request #31825 from frappe/mergify/bp/version-13-hotfix/pr-31817
fix: limit pos recent order page result (backport #31817)
2022-08-22 10:32:30 +05:30
Deepesh Garg
75d57c1f77 Merge pull request #31889 from frappe/mergify/bp/version-13-hotfix/pr-31871
fix: incorrect buying amount in Gross Profit rpt (backport #31871)
2022-08-22 10:29:47 +05:30
Deepesh Garg
fc7285cc85 Merge pull request #31826 from frappe/mergify/bp/version-13-hotfix/pr-31799
fix: process loan interest accrual (backport #31799)
2022-08-22 10:28:04 +05:30
Suraj Shetty
23a441252b fix: Replace walrus operator 2022-08-22 09:49:15 +05:30
Deepesh Garg
474f34c04c Merge pull request #31868 from frappe/mergify/bp/version-13-hotfix/pr-31856
fix: incorrect tax amt due to different exchange rate in PR and PI (backport #31856)
2022-08-22 09:09:53 +05:30
Deepesh Garg
6606028062 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31799 2022-08-22 09:00:14 +05:30
Deepesh Garg
f58427bffe Merge pull request #31894 from maharshivpatel/fix-tax-withholding-advance-vouchers
fix: TDS calculation for advance payment
2022-08-22 08:58:59 +05:30
Suraj Shetty
89f889068e style: Fix formatting 2022-08-20 14:19:15 +05:30
Suraj Shetty
9263d5ff4d fix: Update received_by if "to" is changed 2022-08-20 14:15:54 +05:30
Suraj Shetty
4df197a282 test: Do not overwrite frappe.form_dict to retain proxy reference
Set frappe.local.form_dict instead
2022-08-20 14:14:16 +05:30
Suraj Shetty
b495969eb8 test: Clean up form_dict
To avoid failures like
https://github.com/frappe/erpnext/runs/5887687369?check_suite_focus=true#step:12:783
2022-08-20 14:14:10 +05:30
Suraj Shetty
5f4760985c test: Fix used frappe._dict to avoid AttributeError down the line
ref: https://github.com/frappe/erpnext/runs/5816574721?check_suite_focus=true#step:12:880
2022-08-20 14:14:03 +05:30
Suraj Shetty
4a61840e39 test: Use FrappeAPITestCase to track coverage 2022-08-20 14:13:56 +05:30
Suraj Shetty
ca48b9de54 test: Fix erroneous code 2022-08-20 14:13:50 +05:30
Suraj Shetty
baab96d02c fix: Handle exception where no employee is returned 2022-08-20 14:13:40 +05:30
Suraj Shetty
f5b967a947 chore: Remove unused code
- and simplify get_call_log
2022-08-20 14:13:24 +05:30
Suraj Shetty
06b1bcbf59 test: Refactor exotel test setup
- Remove unnecessary code
- Move test data to separate file
- Make proper test assertions
2022-08-20 14:12:17 +05:30
Subin Tom
aa8a063103 fix: added tests 2022-08-20 14:11:48 +05:30
Subin Tom
3f46b2a0ce fix: used get_employees_with_number, strip_number methods 2022-08-20 14:10:18 +05:30
Subin Tom
b52962751c fix: linter, sider fixes 2022-08-20 14:07:17 +05:30
Subin Tom
b94154f00a fix: call type doctype, fixes 2022-08-20 14:06:52 +05:30
Subin Tom
90ed14a055 fix: sider fixes 2022-08-20 14:05:49 +05:30
Subin Tom
b65bce8f98 fix: added type of call select field, additional status for agent rejecting call 2022-08-20 14:05:27 +05:30
Subin Tom
66578a58cf fix: added field to show called group, user_id 2022-08-20 14:04:01 +05:30
Subin Tom
476ded2972 fix: added employee name to call log 2022-08-20 14:03:40 +05:30
Subin Tom
ffb1196516 fix: call status fix 2022-08-20 14:03:14 +05:30
Maharshi Patel
a452143782 fix: TDS calculation for advance payment
"against_voucher": ["is", "not set"] was used in query due to which if TDS was added on "advance" payment vouchers and then reconciled against purchase invoice. it will not find those vouchers and consider this as first-time threshold due to which it will calculate Tax for all transactions.
2022-08-19 12:30:47 +05:30
ruthra kumar
6405a9378d fix: incorrect buying amount in Gross Profit rpt
(cherry picked from commit 967dd398e7)
2022-08-18 13:28:45 +00:00
Rucha Mahabal
2471ca58ee Merge pull request #31884 from ruchamahabal/fix-promotion 2022-08-18 12:29:31 +05:30
Rucha Mahabal
a4828407d0 fix: interview rescheduling not working 2022-08-18 12:02:32 +05:30
Frappe PR Bot
bafa3ce150 chore(release): Bumped to Version 13.36.4
## [13.36.4](https://github.com/frappe/erpnext/compare/v13.36.3...v13.36.4) (2022-08-18)

### Bug Fixes

* check item_code in all rows of po_items (backport [#31741](https://github.com/frappe/erpnext/issues/31741)) ([#31843](https://github.com/frappe/erpnext/issues/31843)) ([ba8dc89](ba8dc8925f))
* conflicts ([41b8563](41b8563b7a))
* contact search in request for quotation (backport [#31828](https://github.com/frappe/erpnext/issues/31828)) ([#31841](https://github.com/frappe/erpnext/issues/31841)) ([2a615af](2a615af00a))
* incorrect produced-qty in production-plan-item (backport [#31706](https://github.com/frappe/erpnext/issues/31706)) ([#31862](https://github.com/frappe/erpnext/issues/31862)) ([7ddb332](7ddb332f47))
* incorrect rate in BOM exploded items (backport [#31513](https://github.com/frappe/erpnext/issues/31513)) ([#31865](https://github.com/frappe/erpnext/issues/31865)) ([3274e76](3274e7681d))
* Make expense account editable in Purchase Receipt Item (backport [#31730](https://github.com/frappe/erpnext/issues/31730)) ([#31879](https://github.com/frappe/erpnext/issues/31879)) ([4775c42](4775c42593))
* not able to issue expired batches ([7ee75ff](7ee75ff762))
* set `billing_address` for purchases in `get_party_details` ([a7d66fa](a7d66fa352))
* set `company_address` for purchases in `party.js` ([d1de4b0](d1de4b027c))
* Transit filter for Default Target Warehouse in SE (backport [#31839](https://github.com/frappe/erpnext/issues/31839)) ([#31874](https://github.com/frappe/erpnext/issues/31874)) ([b0917aa](b0917aaf8a))
* use old style for `_dict.update` ([15654aa](15654aae8b))
2022-08-18 06:15:23 +00:00
Deepesh Garg
cff140db3d Merge pull request #31880 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-08-18 11:43:42 +05:30
Rucha Mahabal
36130c6292 fix(minor): save the employee doc on promotion/transfer update 2022-08-18 11:42:29 +05:30
mergify[bot]
4775c42593 fix: Make expense account editable in Purchase Receipt Item (backport #31730) (#31879)
* fix: Make expense account editable in Purchase Receipt Item (#31730)

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
(cherry picked from commit 1a6508972e)

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

* chore: conflicts

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-18 11:15:26 +05:30
mergify[bot]
b0917aaf8a fix: Transit filter for Default Target Warehouse in SE (backport #31839) (#31874)
fix: Transit filter for Default Target Warehouse in SE (#31839)

(cherry picked from commit f1a612245c)

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-17 17:25:31 +05:30
rohitwaghchaure
d349a337e1 Merge pull request #31866 from frappe/mergify/bp/version-13-hotfix/pr-31863
fix: not able to issue expired batches (backport #31863)
2022-08-17 15:43:22 +05:30
ruthra kumar
ba5ee1ca96 fix: incorrect tax amt due to different exchange rate in PR and PI
(cherry picked from commit 5fd0770372)
2022-08-17 09:40:36 +00:00
rohitwaghchaure
41b8563b7a fix: conflicts 2022-08-17 14:47:47 +05:30
Rohit Waghchaure
7ee75ff762 fix: not able to issue expired batches
(cherry picked from commit 795c94384a)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/test_stock_entry.py
2022-08-17 09:16:37 +00:00
mergify[bot]
3274e7681d fix: incorrect rate in BOM exploded items (backport #31513) (#31865)
* fix: incorrect rate in BOM exploded items (#31513)

(cherry picked from commit 313625c349)

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

* chore: conflicts

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-17 14:39:15 +05:30
mergify[bot]
7ddb332f47 fix: incorrect produced-qty in production-plan-item (backport #31706) (#31862)
fix: incorrect produced-qty in production-plan-item (#31706)

(cherry picked from commit 538cd6fdcf)

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-17 13:49:51 +05:30
mergify[bot]
2a615af00a fix: contact search in request for quotation (backport #31828) (#31841)
* fix: contact search in request for quotation (#31828)

(cherry picked from commit e5e88bb9f1)

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

* chore: conflicts

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-17 11:23:24 +05:30
mergify[bot]
ba8dc8925f fix: check item_code in all rows of po_items (backport #31741) (#31843)
fix: check item_code in all rows of po_items (#31741)

fix: check item-code in each row of po-items
(cherry picked from commit 0047e18a9b)

Co-authored-by: Sagar Sharma <sagarsharma.s312@gmail.com>
2022-08-17 11:21:47 +05:30
Sagar Vora
14891ccf18 Merge pull request #31792 from frappe/mergify/bp/version-13-hotfix/pr-31733
fix: set `billing_address` for purchases in `get_party_details` (backport #31733)
2022-08-16 05:48:48 +00:00
Sagar Vora
15654aae8b fix: use old style for _dict.update 2022-08-13 08:00:27 +00:00
Sagar Vora
d1de4b027c fix: set company_address for purchases in party.js
(cherry picked from commit d05082987f)
2022-08-13 08:00:27 +00:00
Sagar Vora
a7d66fa352 fix: set billing_address for purchases in get_party_details
(cherry picked from commit a3625b3817)
2022-08-13 08:00:27 +00:00
Abhinav Raut
8dea238d12 fix: term loan interest calculation
(cherry picked from commit 534d7ce64b)
2022-08-11 10:18:04 +00:00
Abhinav Raut
acbed434c2 fix: process loan interest accrual
(cherry picked from commit 9ef8d5c5c3)
2022-08-11 10:18:04 +00:00
ruthra kumar
9751f1060e fix: limit pos recent order page result
(cherry picked from commit bb40e38451)
2022-08-11 08:40:05 +00:00
Frappe PR Bot
c15cff05b0 chore(release): Bumped to Version 13.36.3
## [13.36.3](https://github.com/frappe/erpnext/compare/v13.36.2...v13.36.3) (2022-08-09)

### Bug Fixes

* (india) HSN wise report ([08c69c7](08c69c7a76))
* add asset repair to accounting dimension list ([809d5ca](809d5caf80))
* consider precision while validating advance amount against sanctioned amount ([63cd434](63cd4349a6))
* **ecommerce:** remove query to non-existing field (backport [#31771](https://github.com/frappe/erpnext/issues/31771)) ([#31774](https://github.com/frappe/erpnext/issues/31774)) ([0e46b33](0e46b33ee3))
* f-string and where clause ([42b3959](42b395916d))
* getting error to show sales invoice group or print rep… (backport [#31756](https://github.com/frappe/erpnext/issues/31756)) ([#31768](https://github.com/frappe/erpnext/issues/31768)) ([473a43b](473a43b6b1))
* incorrect incoming rate set for inter transfer purchase receipt ([4e8b39a](4e8b39ab3f))
* incorrect tax calculation in case of reduced payment days ([80981d0](80981d025f))
* intercompany SO throws exception ([a17acfd](a17acfdaa2))
* minor changed link ([e9e53a7](e9e53a74c9))
* Payment Entry button is visible even when claim is fully paid ([d820757](d820757359))
* pending principal- amount ([16c94d2](16c94d292c))
* **pos:** validate product bundles while submitting pos invoice (backport [#31615](https://github.com/frappe/erpnext/issues/31615)) ([#31657](https://github.com/frappe/erpnext/issues/31657)) ([b145fe3](b145fe3b3e))
* specify allowed doctype in queries ([#31765](https://github.com/frappe/erpnext/issues/31765)) ([0dbfb15](0dbfb1589e))
* statistical component showing up in salary slip ([#31746](https://github.com/frappe/erpnext/issues/31746)) ([26aef4f](26aef4fb1c))
* sum stock_value and group by warehouse ([18d93f8](18d93f8398))
* taxable_value and gst_account_heads ([6c574fb](6c574fbf33))
* update To Date in Employee Work History ([#31811](https://github.com/frappe/erpnext/issues/31811)) ([0057c10](0057c10a7d))
2022-08-09 14:09:11 +00:00
Deepesh Garg
b80526f226 Merge pull request #31812 from frappe/version-13-hotfix
chore: weekly version 13 release
2022-08-09 19:37:13 +05:30
Deepesh Garg
0569f8a857 Merge pull request #31736 from maharshivpatel/fix-india-hsn-report
fix: (india) HSN wise report
2022-08-09 18:58:25 +05:30
Rucha Mahabal
63715bf229 Merge pull request #31813 from ruchamahabal/fix-claim 2022-08-09 18:52:22 +05:30
Rucha Mahabal
63cd4349a6 fix: consider precision while validating advance amount against sanctioned amount 2022-08-09 18:28:19 +05:30
Maharshi Patel
42b395916d fix: f-string and where clause
Used f-string formatting and added conditions to WHERE clause
2022-08-09 18:22:05 +05:30
Rucha Mahabal
0057c10a7d fix: update To Date in Employee Work History (#31811) 2022-08-09 18:19:09 +05:30
Deepesh Garg
3c8c5d01fb Merge pull request #31797 from frappe/mergify/bp/version-13-hotfix/pr-31779
Bug add accouting dimension in asset repair (backport #31779)
2022-08-09 18:18:42 +05:30
Rucha Mahabal
d820757359 fix: Payment Entry button is visible even when claim is fully paid 2022-08-09 18:15:41 +05:30
mergify[bot]
14e59c86aa Tds report (backport #31801) (#31808)
* fix: TDS Computation Summary Report not loading, too many values to unpack
2022-08-09 18:11:13 +05:30
Deepesh Garg
9e16f4e412 chore: resolve conflicts 2022-08-09 17:55:02 +05:30
rohitwaghchaure
6d269a4d89 Merge pull request #31805 from frappe/mergify/bp/version-13-hotfix/pr-31804
fix: incorrect incoming rate set for inter transfer purchase receipt (backport #31804)
2022-08-09 16:26:34 +05:30
Rohit Waghchaure
4e8b39ab3f fix: incorrect incoming rate set for inter transfer purchase receipt
(cherry picked from commit ddd24ea8c8)
2022-08-09 10:31:14 +00:00
Rucha Mahabal
9925eb9982 Merge pull request #31802 from ruchamahabal/fix-salary-slip-tds-v13 2022-08-09 15:33:54 +05:30
Rucha Mahabal
301d199ece test: default amount in slip 2022-08-09 14:57:10 +05:30
Maharshi Patel
6c574fbf33 fix: taxable_value and gst_account_heads
used taxable_value instead of base_net_amount and only appended required GST accounts
2022-08-09 14:39:13 +05:30
Rucha Mahabal
80981d025f fix: incorrect tax calculation in case of reduced payment days 2022-08-09 12:40:06 +05:30
ruthra kumar
a420d0242c chore: patch for creating existing dimensions in asset repair
(cherry picked from commit 80f508c4b1)

# Conflicts:
#	erpnext/patches.txt
2022-08-08 11:09:55 +00:00
ruthra kumar
809d5caf80 fix: add asset repair to accounting dimension list
(cherry picked from commit 452584c4bd)
2022-08-08 11:09:53 +00:00
Deepesh Garg
6f442d14cf Merge pull request #31795 from frappe/mergify/bp/version-13-hotfix/pr-31777
fix: intercompany SO created from Purchase Order throws exception (backport #31777)
2022-08-08 16:37:39 +05:30
ruthra kumar
a17acfdaa2 fix: intercompany SO throws exception
(cherry picked from commit af0a353b79)
2022-08-08 10:37:25 +00:00
Deepesh Garg
3673dea03b Merge pull request #31783 from frappe/mergify/bp/version-13-hotfix/pr-31780
Fix: Loan pending principal amount  (backport #31780)
2022-08-08 14:48:06 +05:30
Deepesh Garg
fb3725752f chore: resolve conflicts 2022-08-08 11:53:49 +05:30
Abhinav Raut
16c94d292c fix: pending principal- amount
(cherry picked from commit a272d73dd9)

# Conflicts:
#	erpnext/loan_management/doctype/loan_repayment/loan_repayment.json
2022-08-05 10:35:05 +00:00
mergify[bot]
0e46b33ee3 fix(ecommerce): remove query to non-existing field (backport #31771) (#31774)
fix(ecommerce): remove query to non-existing field (#31771)

(cherry picked from commit 17b9bfd249)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-08-03 17:08:46 +05:30
mergify[bot]
df716fbd0c ci: fix automated release regex (backport #31770) (#31772)
ci: fix automated release regex (#31770)

[skip ci]

(cherry picked from commit 2defb89962)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-08-03 16:37:39 +05:30
mergify[bot]
0dbfb1589e fix: specify allowed doctype in queries (#31765)
Co-authored-by: Sagar Vora <sagar@resilient.tech>
2022-08-03 12:03:53 +05:30
mergify[bot]
473a43b6b1 fix: getting error to show sales invoice group or print rep… (backport #31756) (#31768)
fix: getting error to show sales invoice group or print rep… (#31756)

fix: formatter getting error to show sales invoice group or print report.

1 - When I view the Gross Profit report in Sales Invoice mode, the table is all broken.
Error on browser console:
TypeError: Cannot read properties of undefined (reading 'indent')

2 - When I try to print, no matter the Group (Sales Invoice, Item Code, Item Group...) nothing happens. in browser log console I have the following error:
TypeError: Cannot read properties of undefined (reading 'content')

i fixed both errors and all working perfectly.

(cherry picked from commit ea88451875)

Co-authored-by: HarryPaulo <paulo_fabris@hotmail.com>
2022-08-03 11:23:10 +05:30
rohitwaghchaure
1a3b3b96c2 Merge pull request #31751 from frappe/mergify/bp/version-13-hotfix/pr-31750
fix: minor URL link (backport #31750)
2022-08-01 14:34:12 +05:30
Rohit Waghchaure
e9e53a74c9 fix: minor changed link
(cherry picked from commit 0e7c4314b4)
2022-08-01 09:02:07 +00:00
Rucha Mahabal
26aef4fb1c fix: statistical component showing up in salary slip (#31746)
* fix: statistical component showing up in salary slip

* fix(test): payment days effect on timesheet salary slio
2022-08-01 12:54:25 +05:30
mergify[bot]
b145fe3b3e fix(pos): validate product bundles while submitting pos invoice (backport #31615) (#31657) 2022-07-31 19:12:14 +05:30
Marica
d83c869d73 Merge pull request #31717 from frappe/mergify/bp/version-13-hotfix/pr-31601
perf: reduce db calls for warehouse wise stock value chart (backport #31601)
2022-07-31 18:26:27 +05:30
Maharshi Patel
08c69c7a76 fix: (india) HSN wise report
Problem:
The previous approach for calculating tax_rate was incorrect.
```
['tax_rate'] * ['number of unique rows']
```
Joining `tabSales Taxes and Charges` was adding unnecessary rows & complexity.

Solution:
Instead of trying to get tax_rate from the main query itself, I used the get_tax_accounts's data to calculate the correct tax_rate.

Todo:
Union Territory
2022-07-29 14:22:31 +05:30
Frappe PR Bot
84e6cead56 chore(release): Bumped to Version 13.36.2
## [13.36.2](https://github.com/frappe/erpnext/compare/v13.36.1...v13.36.2) (2022-07-28)

### Bug Fixes

* (india) (e-invoice) margin & internal company transfer ([b97d30a](b97d30aad0))
* (india) add overseas in HSN wise report ([1d69ce1](1d69ce1932))
* Allow allocating advance amount against Expense Claim taxes ([42f3592](42f3592e95))
* assign duplicate_items_msg outside conditional ([#31639](https://github.com/frappe/erpnext/issues/31639)) ([8e23c6a](8e23c6ad69))
* correct Brazilian portuguese translations (backport [#31498](https://github.com/frappe/erpnext/issues/31498)) ([#31660](https://github.com/frappe/erpnext/issues/31660)) ([794fd08](794fd0819f))
* discount and test added ([a843e78](a843e784e6))
* display customer name on picking list ([dbf245c](dbf245c687))
* do not update component amount for timesheet components ([#31696](https://github.com/frappe/erpnext/issues/31696)) ([bc7cfe6](bc7cfe6919))
* enable tax withholding checkbox in PI with supplier_tds ([bc74942](bc7494278d))
* ensure defaults removed in bad frappe patch get set again (backport [#31659](https://github.com/frappe/erpnext/issues/31659)) ([#31661](https://github.com/frappe/erpnext/issues/31661)) ([763787b](763787b0a5))
* hero image not loading in portal homepage ([#31699](https://github.com/frappe/erpnext/issues/31699)) ([8a6432e](8a6432ec3f))
* **india:** e-way bill json for unregistered gst category ([01d6df4](01d6df45d0))
* make customer_name field read only. ([2381b81](2381b81aac))
* manually generated salary slips overwritten by structure amount ([#31711](https://github.com/frappe/erpnext/issues/31711)) ([32c1bb6](32c1bb61de))
* Map `Item` image to `Website Item` website_image only if published via UI (v13) ([9b1544a](9b1544aa14))
* payment entry to student ([#31708](https://github.com/frappe/erpnext/issues/31708)) ([4f02375](4f023757de))
* Reload loan Table in Salary Slip when change Employee ([#31525](https://github.com/frappe/erpnext/issues/31525)) ([a95c011](a95c011a93))
* rounding errors while closing pos (backport [#31654](https://github.com/frappe/erpnext/issues/31654)) ([#31658](https://github.com/frappe/erpnext/issues/31658)) ([529a47b](529a47bc88))
* Route condition set with proper filter ([#31556](https://github.com/frappe/erpnext/issues/31556)) ([5cdc267](5cdc267aee))
* The Fee details are not fetched in Program Enrollment ([#31153](https://github.com/frappe/erpnext/issues/31153)) ([0602848](0602848caa))
* update fr translations ([#31687](https://github.com/frappe/erpnext/issues/31687)) ([89348c1](89348c1bb4))
* update fr translations (backport [#31526](https://github.com/frappe/erpnext/issues/31526)) ([#31666](https://github.com/frappe/erpnext/issues/31666)) ([95e1021](95e1021caf))
* update SO's percentage billed on credit note ([2f2d3de](2f2d3de306))
* use current pos profile on sales return ([c442b4a](c442b4aef1))
2022-07-28 12:13:57 +00:00
Deepesh Garg
590e48fa1d Merge pull request #31725 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-07-28 17:42:15 +05:30
Deepesh Garg
25da4d28ff Merge pull request #31727 from frappe/mergify/bp/version-13-hotfix/pr-31656
fix: use current pos profile on sales return (backport #31656)
2022-07-28 16:32:36 +05:30
Deepesh Garg
f57d2fadbc Merge pull request #31728 from frappe/mergify/bp/version-13-hotfix/pr-31676
fix: enable tax withholding checkbox in PI with supplier_tds (backport #31676)
2022-07-28 16:32:17 +05:30
Deepesh Garg
9e7edd677a Merge pull request #31726 from frappe/mergify/bp/version-13-hotfix/pr-31576
fix: credite note for returned delivery note updates SO's billed percentage (backport #31576)
2022-07-28 16:32:05 +05:30
ruthra kumar
bc7494278d fix: enable tax withholding checkbox in PI with supplier_tds
(cherry picked from commit b461724416)
2022-07-28 10:42:58 +00:00
ruthra kumar
c442b4aef1 fix: use current pos profile on sales return
(cherry picked from commit 5b85af5f1a)
2022-07-28 10:36:23 +00:00
ruthra kumar
ef9b25cf08 test: SO percentage billed when cr_note made against delivery return
(cherry picked from commit 243f66fcd3)
2022-07-28 10:21:19 +00:00
ruthra kumar
2f2d3de306 fix: update SO's percentage billed on credit note
Credit Note created from Sales Return will update precentage billed in
Sales Order accordingly

(cherry picked from commit 04c1019242)
2022-07-28 10:21:18 +00:00
Rucha Mahabal
13639682ce Merge pull request #31724 from ruchamahabal/expense-claim-adv 2022-07-28 14:51:15 +05:30
Rucha Mahabal
c01adae8a5 test: advance amount allocation against expense claim with taxes 2022-07-28 14:27:09 +05:30
Deepesh Garg
8ae691d9dc Merge branch 'version-13' into version-13-hotfix 2022-07-28 13:59:25 +05:30
Alaa Alsalehi
a95c011a93 fix: Reload loan Table in Salary Slip when change Employee (#31525)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
Co-authored-by: bahaaabed <bahaa.9999.sh@gmail.com>
Co-authored-by: newhr1 <104132586+newhr1@users.noreply.github.com>
2022-07-28 13:22:07 +05:30
Rucha Mahabal
42f3592e95 fix: Allow allocating advance amount against Expense Claim taxes 2022-07-28 13:21:29 +05:30
Syed Mujeer Hashmi
0602848caa fix: The Fee details are not fetched in Program Enrollment (#31153) 2022-07-28 12:30:39 +05:30
Rucha Mahabal
9985d28571 chore: Add HR & Payroll deprecation warning (#31720) 2022-07-28 11:43:49 +05:30
Marica
31824c2280 Merge pull request #31716 from frappe/mergify/bp/version-13-hotfix/pr-31687
fix: update fr translations (backport #31687)
2022-07-27 18:01:30 +05:30
Devin Slauenwhite
18d93f8398 fix: sum stock_value and group by warehouse
(cherry picked from commit 1e20358c28)
2022-07-27 12:18:39 +00:00
Devin Slauenwhite
c9443123f9 chore: remove unused import
(cherry picked from commit bc3023318e)
2022-07-27 12:18:38 +00:00
Devin Slauenwhite
0fdec8fac8 pref: reduce count of db calls from n to 2
(cherry picked from commit 73ade04dcf)
2022-07-27 12:18:38 +00:00
marination
6fbb06a878 chore: Merge Conflict 2022-07-27 17:30:46 +05:30
HENRY Florian
89348c1bb4 fix: update fr translations (#31687)
* fix: update fr translations

* fix: update fr translation

* fix: update fr translation

* chore: Replace apostrophe encoding by symbol

Co-authored-by: marination <maricadsouza221197@gmail.com>
(cherry picked from commit cc1f837685)

# Conflicts:
#	erpnext/translations/fr.csv
2022-07-27 11:52:03 +00:00
Marica
598dbc93ac Merge pull request #31669 from frappe/mergify/bp/version-13-hotfix/pr-31579
fix: display customer name on picking list (backport #31579)
2022-07-27 16:45:07 +05:30
Marica
51a4ef3069 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31579 2022-07-27 16:23:22 +05:30
Marica
49fb177f86 chore: Merge Conflicts 2022-07-27 16:22:17 +05:30
Marica
b0aae8a297 Merge pull request #31713 from frappe/mergify/bp/version-13-hotfix/pr-31469
chore: Make `image` field obsolete in Website Item (redundant) (backport #31469)
2022-07-27 16:12:32 +05:30
Marica
e310347ca4 chore: Merge Conflicts 2022-07-27 15:51:01 +05:30
marination
9b1544aa14 fix: Map Item image to Website Item website_image only if published via UI (v13)
- For v12 Items, `website_image` should be mapped from `Item` to `Website Item`

(cherry picked from commit af38baeb3b)

# Conflicts:
#	erpnext/e_commerce/doctype/website_item/website_item.py
2022-07-27 10:14:20 +00:00
marination
a8da5f4566 chore: Remove image use in website item list
(cherry picked from commit 7a6ee8cf2d)
2022-07-27 10:14:18 +00:00
marination
0e469f6d95 chore: Remove image from ProductQuery fields
(cherry picked from commit eec07833f4)
2022-07-27 10:14:18 +00:00
marination
b393c230bd chore: Make image field obsolete in Website Item (redundant)
- Delete Image field and set `website_image` as form's image field for uploads
- Remove instances of `image` field access via Website Item
- Item -> Web Item via Desk: Map Item's `image` to Web Item's `website_image`
- Item -> Web Item via patch: `website_image` will be mapped with thumbnail
- Remove magic that auto-sets `website_image` from `image` in Website Item

(cherry picked from commit 9541354ec7)

# Conflicts:
#	erpnext/e_commerce/doctype/website_item/website_item.py
2022-07-27 10:14:16 +00:00
Rucha Mahabal
32c1bb61de fix: manually generated salary slips overwritten by structure amount (#31711) 2022-07-27 12:44:26 +05:30
MohsinAli
4f023757de fix: payment entry to student (#31708)
Payment entry to student via Payment References(From Journal Entry)
2022-07-27 11:50:15 +05:30
Deepesh Garg
d2d25e17bb Merge pull request #31698 from maharshivpatel/fix-einvoice-margin-internal-transfer
fix: (india) (e-invoice) margin & internal company transfer
2022-07-26 21:59:44 +05:30
Maharshi Patel
a843e784e6 fix: discount and test added
only report net rate if discount is less than 0 and added test.
2022-07-26 17:40:59 +05:30
Rucha Mahabal
8a6432ec3f fix: hero image not loading in portal homepage (#31699) 2022-07-26 13:43:36 +05:30
Maharshi Patel
b97d30aad0 fix: (india) (e-invoice) margin & internal company transfer
When the item price is more than the price list rate ( margin added ) discount value becomes negative. The previous attempt to solve this was to convert discount to absolute value. However, that gives incorrect unit price and discount value. To solve this, I have made changes to report net rates in cases where the margin is added or is an internal company transfer.
2022-07-26 12:57:47 +05:30
Rucha Mahabal
bc7cfe6919 fix: do not update component amount for timesheet components (#31696)
* fix: do not update component amount for timesheet components

* fix: warn the user about overwriting timesheet component amount
2022-07-26 12:35:50 +05:30
Deepesh Garg
85802b0f97 Merge pull request #31602 from rtdany10/patch-19
fix(india): e-way bill json for unregistered gst category
2022-07-22 13:11:19 +05:30
Deepesh Garg
dc67d39ce6 Merge pull request #31665 from maharshivpatel/fix-add-overseas-hsn-report
fix: (india) add entries from overseas invoices in HSN wise report
2022-07-22 13:06:30 +05:30
mergify[bot]
529a47bc88 fix: rounding errors while closing pos (backport #31654) (#31658) 2022-07-22 11:17:59 +05:30
Devin Slauenwhite
2381b81aac fix: make customer_name field read only.
(cherry picked from commit 7083b3148b)

# Conflicts:
#	erpnext/stock/doctype/pick_list/pick_list.json
2022-07-21 13:08:41 +00:00
Devin Slauenwhite
dbf245c687 fix: display customer name on picking list
(cherry picked from commit 0a633a212d)

# Conflicts:
#	erpnext/stock/doctype/pick_list/pick_list.json
2022-07-21 13:08:40 +00:00
Nihantra C. Patel
5cdc267aee fix: Route condition set with proper filter (#31556)
* fix: Redirect to report with proper filter

* Update member.js

* fix: Route condition set with proper filter

* fix: Route condition set with proper filter

* fix: Route condition set with proper filter

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-07-21 18:29:06 +05:30
mergify[bot]
95e1021caf fix: update fr translations (backport #31526) (#31666)
fix: update fr translations (#31526)

* fix: update fr translations

* fix: update fr translations

* fix: update fr translations

* fix: update fr translations

* chore: Update french translation

Co-authored-by: Marica <maricadsouza221197@gmail.com>
(cherry picked from commit 3ba0d6cc5c)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2022-07-21 18:11:32 +05:30
mergify[bot]
7d50f8798a Update de.csv (backport #31596) (#31667)
Update de.csv (#31596)

IN,IM to IN,EIN

Co-authored-by: Marica <maricadsouza221197@gmail.com>
(cherry picked from commit 8629d01dd5)

Co-authored-by: billy995 <48571007+billy995@users.noreply.github.com>
2022-07-21 18:10:46 +05:30
Marica
dd751c6e92 Merge pull request #31664 from frappe/mergify/bp/version-13-hotfix/pr-31544
FIX: quality inspection quick creation from purchase receipt: pre-fill sample size if available (backport #31544)
2022-07-21 14:13:48 +05:30
Frappe PR Bot
69087b8790 chore(release): Bumped to Version 13.36.1
## [13.36.1](https://github.com/frappe/erpnext/compare/v13.36.0...v13.36.1) (2022-07-21)

### Bug Fixes

* ensure defaults removed in bad frappe patch get set again (backport [#31659](https://github.com/frappe/erpnext/issues/31659)) ([2ae3bd9](2ae3bd9fed))
2022-07-21 08:26:20 +00:00
mergify[bot]
763787b0a5 fix: ensure defaults removed in bad frappe patch get set again (backport #31659) (#31661)
fix: ensure defaults removed in bad frappe patch get set again (#31659)

(cherry picked from commit bf2833b8ee)

Co-authored-by: Sagar Vora <sagar@resilient.tech>
2022-07-21 13:54:55 +05:30
mergify[bot]
2ae3bd9fed fix: ensure defaults removed in bad frappe patch get set again (backport #31659)
fix: ensure defaults removed in bad frappe patch get set again (#31659)

(cherry picked from commit bf2833b8ee)
(cherry picked from commit 9071018e4e)

Co-authored-by: Sagar Vora <sagar@resilient.tech>
2022-07-21 13:54:40 +05:30
Marc de Lima Lucio
1998223ee3 FIX: quality inspection quick creation from purchase receipt: pre-fill sample size if available (#31544)
FIX: quality inspection quick creation from transaction documents: pre-fill sample size if available

Co-authored-by: Marica <maricadsouza221197@gmail.com>
(cherry picked from commit 048c037842)
2022-07-21 08:17:48 +00:00
mergify[bot]
794fd0819f fix: correct Brazilian portuguese translations (backport #31498) (#31660)
fix: correct Brazilian portuguese translations (#31498)

* fix brazilian portuguese translations

* minor adjustments

* fix minor adjustments

* fix: remove legacy pt_br.csv

* chore: Fix translation quotation marks

Co-authored-by: Marica <maricadsouza221197@gmail.com>
(cherry picked from commit d30f8387d9)

Co-authored-by: Marco Fonseca <62901164+treasuryesc@users.noreply.github.com>
2022-07-21 13:47:18 +05:30
Maharshi Patel
1d69ce1932 fix: (india) add overseas in HSN wise report
SQL query had WHERE `tabSales Taxes and Charges`.parent = `tabSales Invoice`.name. However, In overseas, there is no `tabSales Taxes and Charges` so I changed the query to use a combination of INNER JOIN and LEFT JOIN to fetch all entries.
2022-07-21 13:27:30 +05:30
Maharshi Patel
8e23c6ad69 fix: assign duplicate_items_msg outside conditional (#31639)
duplicate_items_msg was defined inside if the statement  of stock_item so when duplicate was found in non_stock_item it raised referenced before assignment
2022-07-20 21:25:36 +05:30
Frappe PR Bot
32ba8c7d6d chore(release): Bumped to Version 13.36.0
# [13.36.0](https://github.com/frappe/erpnext/compare/v13.35.3...v13.36.0) (2022-07-20)

### Bug Fixes

* (india) (e-invoice) allow generation for UIN Holders ([82539fc](82539fc18a))
* (india) (e-invoice) CN / DN with 0 qty ([84f260e](84f260e1d8))
* (india) (e-invoice) discount calculation ([1f4d434](1f4d434675))
* (india) (e-invoice) discount in CN/DN ([6e6b55e](6e6b55ece0))
* (india) (e-invoice) qty should not be changed to 1 ([b0efb98](b0efb98237))
* (india)(einvoice) discount for CN DN ([844758a](844758a27c))
* added Section translation in German for Salary Slip (backport [#31608](https://github.com/frappe/erpnext/issues/31608)) ([#31616](https://github.com/frappe/erpnext/issues/31616)) ([12d3d6a](12d3d6ab49))
* Allow multi currency invoice against single party account ([9ac9c46](9ac9c46dab))
* **India:** Inward supplies from Composition Supplier in 3B report ([b147ce4](b147ce4206))
* LCV updates wrong future qty/Bin qty ([f0ecdbe](f0ecdbef5a))
* linter ([9a3c846](9a3c84663f))
* move auto attendance job to long queue ([8eb9aaa](8eb9aaafe9))
* on cancel for loan refund ([8237d94](8237d94b11))
* Opening Invoice Creation Tool msgprint ([cb80bcd](cb80bcd0ee))
* Patch to make accounting dimension in orders ([55399f2](55399f2e58))
* Remove unnecessary list comprehensions ([711501b](711501be5e))
* Removed 'Allow Monthly Depreciation' checkbox and fixed wdv depreciation rate ([616e3c6](616e3c66b9))
* Renamed status field to gle_processing_status ([1180135](1180135067))
* Set Amount in Supplied Item table ([72e8c02](72e8c02ae0))
* set default_bom for item ([def622c](def622c13e))
* set status on submit/cancel ([04b077a](04b077a89f))
* slow stock reposting ([a5dae92](a5dae9264d))
* Supplier details in TDS monthly report ([#31599](https://github.com/frappe/erpnext/issues/31599)) ([431d79f](431d79f516))
* Tax amount not considered in Expense Claim Journal Entry ([90c751f](90c751f648))
* test ([9631ffd](9631ffd215))

### Features

* add adjustment amount to loan ([d5ce780](d5ce780e87))

### Performance Improvements

* index shift type and employee in checkins and assignment to avoid full table scans ([6938025](6938025952))
* Optimization of gl entry processing logic in period closing voucher ([903e42f](903e42fbdd))
* Replace `db.get_all` with `db.exists` in `is_holiday` ([85c554e](85c554eab5))
* Replace `get_doc` with `db.get_value` in `get_shift_details` ([abb7ac5](abb7ac5a0b))
* Use `get_cached_value` and `get_cached_doc` ([8c9035d](8c9035d914))
2022-07-20 15:21:11 +00:00
Deepesh Garg
4d67695294 Merge pull request #31647 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-07-20 20:49:09 +05:30
Deepesh Garg
50fbfd9839 Merge pull request #31649 from frappe/mergify/bp/version-13-hotfix/pr-31648
fix: Patch to make accounting dimension in orders (backport #31648)
2022-07-20 20:01:27 +05:30
Deepesh Garg
e36c74ac44 chore: resolve conflicts 2022-07-20 19:39:18 +05:30
Deepesh Garg
45e25b2d56 chore: do not re run patch
(cherry picked from commit cad2035e07)

# Conflicts:
#	erpnext/patches.txt
2022-07-20 13:32:41 +00:00
Deepesh Garg
55399f2e58 fix: Patch to make accounting dimension in orders
(cherry picked from commit d46e406db7)

# Conflicts:
#	erpnext/patches.txt
2022-07-20 13:32:41 +00:00
Deepesh Garg
a5cd81c73c Merge branch 'version-13' into version-13-hotfix 2022-07-20 17:52:28 +05:30
Nabin Hait
52c8e0a6ea Merge pull request #31644 from nabinhait/asset-monthly-depreciation-v13-hotfix
fix: Removed 'Allow Monthly Depreciation' checkbox
2022-07-20 17:33:15 +05:30
Nabin Hait
616e3c66b9 fix: Removed 'Allow Monthly Depreciation' checkbox and fixed wdv depreciation rate 2022-07-20 17:32:28 +05:30
Nabin Hait
a6e97ea9ab Merge pull request #31626 from nabinhait/pcv-perf-enhancements
perf: Optimization of gl entry processing logic in period closing voucher
2022-07-20 15:39:39 +05:30
Deepesh Garg
2c5e117f01 Merge pull request #31629 from maharshivpatel/fix-einvoice-discounts
fix: (india) (e-invoice) convert discount to absolute value
2022-07-20 13:18:14 +05:30
Marica
a65dd58444 Merge pull request #31416 from frappe/mergify/bp/version-13-hotfix/pr-31412
fix: set default_bom for item (backport #31412)
2022-07-20 11:31:55 +05:30
Nabin Hait
04b077a89f fix: set status on submit/cancel 2022-07-20 11:10:36 +05:30
Nabin Hait
1180135067 fix: Renamed status field to gle_processing_status 2022-07-20 10:50:44 +05:30
Rucha Mahabal
eae4b06a80 Merge pull request #31630 from ruchamahabal/auto-attendance-perf 2022-07-20 10:25:02 +05:30
Maharshi Patel
b0efb98237 fix: (india) (e-invoice) qty should not be changed to 1
Qty of 0 is allowed so can't change item.qty to 1  instead created item_qty and used it.
2022-07-19 22:29:38 +05:30
rohitwaghchaure
e7e1847ec9 Merge pull request #31634 from frappe/mergify/bp/version-13-hotfix/pr-31631
fix: slow stock reposting (backport #31631)
2022-07-19 19:26:35 +05:30
Rohit Waghchaure
a5dae9264d fix: slow stock reposting
(cherry picked from commit 1d80d37ccf)
2022-07-19 13:18:13 +00:00
Marica
284095106c Merge pull request #31588 from SolufyPrivateLimited/Solufyin-oict
fix: Opening Invoice Creation Tool msgprint
2022-07-19 17:47:44 +05:30
Rucha Mahabal
8eb9aaafe9 fix: move auto attendance job to long queue 2022-07-19 16:07:18 +05:30
Rucha Mahabal
6938025952 perf: index shift type and employee in checkins and assignment to avoid full table scans 2022-07-19 16:02:31 +05:30
Maharshi Patel
6e6b55ece0 fix: (india) (e-invoice) discount in CN/DN
discount fixes
2022-07-19 15:31:34 +05:30
Rucha Mahabal
8c9035d914 perf: Use get_cached_value and get_cached_doc 2022-07-19 14:47:14 +05:30
Nabin Hait
cfb11f4b84 test: Added test for PCV cancellation 2022-07-19 14:31:02 +05:30
Marica
feffc3af27 Merge pull request #31627 from frappe/mergify/bp/version-13-hotfix/pr-31515
fix: LCV updates wrong future qty/Bin qty (backport #31515)
2022-07-19 14:21:33 +05:30
marination
ca9c6e1651 test: LCV impact on future stock balancees
(cherry picked from commit de9ea70ce3)
2022-07-19 08:10:22 +00:00
marination
f0ecdbef5a fix: LCV updates wrong future qty/Bin qty
- As -ve LCV SLE case is returned from `repost_current_voucher`, future qty is not updated
- This just doubly shifts all future qty which is then fixed by a repost
- Until the repost balance values are wrong
- Bin continues to show wrong projected qty even after repost, this is fixed by next SLE that recalculates Bin

(cherry picked from commit 7a5fd71a6c)
2022-07-19 08:10:21 +00:00
Marica
31930a16fa Merge pull request #31624 from marination/sub-contract-amount
fix: Set `amount` in Raw Supplied Items table
2022-07-19 12:55:20 +05:30
Deepesh Garg
4f55fef782 Merge pull request #31623 from frappe/mergify/bp/version-13-hotfix/pr-31599
fix: Supplier details in TDS monthly report (backport #31599)
2022-07-19 12:20:29 +05:30
marination
72e8c02ae0 fix: Set Amount in Supplied Item table 2022-07-19 11:47:25 +05:30
Deepesh Garg
f02596242c Merge pull request #31609 from deepeshgarg007/gstr_3b_gst_category
fix(India): Inward supplies from Composition Supplier in GST 3B report
2022-07-19 10:23:44 +05:30
Deepesh Garg
431d79f516 fix: Supplier details in TDS monthly report (#31599)
(cherry picked from commit a6ff4db2ec)
2022-07-19 04:45:28 +00:00
Rucha Mahabal
711501be5e fix: Remove unnecessary list comprehensions 2022-07-18 21:32:04 +05:30
Rucha Mahabal
abb7ac5a0b perf: Replace get_doc with db.get_value in get_shift_details 2022-07-18 21:13:02 +05:30
Rucha Mahabal
85c554eab5 perf: Replace db.get_all with db.exists in is_holiday
- widely used function call, fetching all rows for holidays
2022-07-18 21:08:15 +05:30
Nabin Hait
903e42fbdd perf: Optimization of gl entry processing logic in period closing voucher 2022-07-18 17:59:42 +05:30
mergify[bot]
12d3d6ab49 fix: added Section translation in German for Salary Slip (backport #31608) (#31616)
Co-authored-by: Wolfram Schmidt <wolfram.schmidt@phamos.eu>
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-07-18 13:41:42 +05:30
Rucha Mahabal
26497f9c0e Merge pull request #31614 from ruchamahabal/fix-claim-payment
fix: Tax amount not considered in Expense Claim Journal Entry
2022-07-18 13:24:12 +05:30
Rucha Mahabal
6a7549d4b2 test: Journal Entry against Expense Claim 2022-07-18 12:57:50 +05:30
Rucha Mahabal
90c751f648 fix: Tax amount not considered in Expense Claim Journal Entry
- add a helper function `get_outstanding_amount_for_claim` for uniformity in usages
2022-07-18 12:39:09 +05:30
Frappe PR Bot
1090862296 chore(release): Bumped to Version 13.35.3
## [13.35.3](https://github.com/frappe/erpnext/compare/v13.35.2...v13.35.3) (2022-07-18)

### Bug Fixes

* (india) (e-invoice) CN / DN with 0 qty and discount issues ([425abcd](425abcdea7))
2022-07-18 05:21:17 +00:00
mergify[bot]
425abcdea7 fix: (india) (e-invoice) CN / DN with 0 qty and discount issues
* fix: (india) (e-invoice) CN / DN with 0 qty
2022-07-18 10:49:41 +05:30
Deepesh Garg
144057f7e3 Merge pull request #31583 from maharshivpatel/fix-e_invoice-cn-dn-qty-0-error
fix: (india) (e-invoice) CN / DN with 0 qty and discount issues
2022-07-18 09:09:19 +05:30
Maharshi Patel
9631ffd215 fix: test
change setting to run test with correct use case.
2022-07-17 15:40:55 +05:30
Maharshi Patel
9a3c84663f fix: linter 2022-07-17 15:22:37 +05:30
Maharshi Patel
2066e5a53a discount settings for e-invoice added and test cases 2022-07-17 15:08:40 +05:30
Deepesh Garg
b147ce4206 fix(India): Inward supplies from Composition Supplier in 3B report 2022-07-17 00:43:25 +05:30
Deepesh Garg
0d6beed546 test: Update test case 2022-07-16 14:06:01 +05:30
Maharshi Patel
844758a27c fix: (india)(einvoice) discount for CN DN 2022-07-15 16:54:10 +05:30
Maharshi Patel
1f4d434675 fix: (india) (e-invoice) discount calculation
I have added fixes for discount in e-inovice.
2022-07-15 16:03:42 +05:30
Dany Robert
01d6df45d0 fix(india): e-way bill json for unregistered gst category 2022-07-15 11:17:41 +05:30
Deepesh Garg
8c7b836de8 Merge pull request #31595 from maharshivpatel/fix-uin-e_invoice
fix: (india) (e-invoice) allow generation for UIN Holders
2022-07-14 21:25:45 +05:30
Deepesh Garg
9fd1fad259 Merge pull request #31572 from frappe/mergify/bp/version-13-hotfix/pr-31566
fix: Allow multi currency invoice against single party account (backport #31566)
2022-07-14 21:25:17 +05:30
Deepesh Garg
dfa0638baf Merge pull request #31577 from frappe/mergify/bp/version-13-hotfix/pr-31543
feat: Loan balance adjustment doctypes (backport #31543)
2022-07-14 21:24:49 +05:30
Deepesh Garg
0a5bc86d1b chore: resolve conflicts 2022-07-14 17:20:32 +05:30
Deepesh Garg
bdd15895ff chore: resolve conflicts 2022-07-14 17:06:01 +05:30
Maharshi Patel
82539fc18a fix: (india) (e-invoice) allow generation for UIN Holders
e-invoice is required for UIN Holders and they should be treated as Registered Regular. there was incorrect if hasattr check that prevented UIN number validation.
2022-07-14 15:12:51 +05:30
Solufyin
cb80bcd0ee fix: Opening Invoice Creation Tool msgprint 2022-07-13 11:55:47 +05:30
Maharshi Patel
84f260e1d8 fix: (india) (e-invoice) CN / DN with 0 qty
Qty 0 is allowed when creating Credit or Debit Note this caused ZeroDivisionError during unit_rate calculation.
fixed the issue by adding required conditionals.
2022-07-13 01:39:36 +05:30
Sagar Sharma
023c5db3bc Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31412 2022-07-12 23:33:48 +05:30
Deepesh Garg
0b3958d692 chore: Linting Issues
(cherry picked from commit 0bac030ca7)
2022-07-12 12:56:46 +00:00
Deepesh Garg
c2a7dc7754 chore: Linting Issues
(cherry picked from commit d933ff5cf6)
2022-07-12 12:56:46 +00:00
Abhinav Raut
8237d94b11 fix: on cancel for loan refund
(cherry picked from commit 13b7ed1e2c)
2022-07-12 12:56:45 +00:00
Labeeb Mattra
0713a240a7 Consider refund_amount in pending principal amount
(cherry picked from commit 35f2717ad2)
2022-07-12 12:56:45 +00:00
Labeeb Mattra
61b2a1c3cb fix excess amount calculation in loan refund
(cherry picked from commit 9df1413adb)
2022-07-12 12:56:44 +00:00
Labeeb Mattra
94be7a95f7 Update adjustment_type field options
(cherry picked from commit 245b0c7818)
2022-07-12 12:56:44 +00:00
Labeeb Mattra
7ba0326bdd fix adjustment amount field name
(cherry picked from commit 6cc09ef3a2)
2022-07-12 12:56:43 +00:00
Labeeb Mattra
86af1ef6ed fix indent and imports
(cherry picked from commit 0ed6382ab6)
2022-07-12 12:56:43 +00:00
Labeeb Mattra
b995338d0c fix lint
(cherry picked from commit 8434ec09c3)
2022-07-12 12:56:43 +00:00
Labeeb Mattra
0856e14c13 Use adjustment amounts in pending principal amnt
(cherry picked from commit 1b5b2138ee)
2022-07-12 12:56:42 +00:00
Labeeb Mattra
ff5ee2bbac Add ref no to balance adjustment remarks
(cherry picked from commit a1a51ce1a6)
2022-07-12 12:56:42 +00:00
Labeeb Mattra
a36e8a83d8 Add reference number to repayment remarks
(cherry picked from commit 74dbf8c5d9)

# Conflicts:
#	erpnext/loan_management/doctype/loan_repayment/loan_repayment.py
2022-07-12 12:56:41 +00:00
Labeeb Mattra
d81e7e2421 Add NPA checkbox in Loan
(cherry picked from commit 27a8e16b28)
2022-07-12 12:56:41 +00:00
Labeeb Mattra
8181d61293 Update list view for Accrual and Shortfall
(cherry picked from commit 7d6e4898c4)
2022-07-12 12:56:40 +00:00
Labeeb Mattra
548aac5b11 Remove loan account field from doctype
(cherry picked from commit 6febcd529b)
2022-07-12 12:56:40 +00:00
Labeeb Mattra
de69fee6aa Use new adjustment amount fields
(cherry picked from commit 7d468a8778)
2022-07-12 12:56:39 +00:00
Labeeb Mattra
c3e6d7ba29 Seperate credit and debit adjust amount fields in Loan
(cherry picked from commit d6f632a770)
2022-07-12 12:56:38 +00:00
Abhinav Raut
d5ce780e87 feat: add adjustment amount to loan
- fix: bugs in loan balance adjustment

(cherry picked from commit 5c0a25012c)
2022-07-12 12:56:38 +00:00
Labeeb Mattra
a2125e694d Add Loan Balance Adjustment doctype
(cherry picked from commit 2e8f056514)
2022-07-12 12:56:37 +00:00
Labeeb Mattra
0d94653c5b Add Loan Refund doctype
(cherry picked from commit e1682965c5)
2022-07-12 12:56:36 +00:00
Labeeb Mattra
d9723a12c4 Add refund amount to loan
(cherry picked from commit 88cd780ca1)
2022-07-12 12:56:36 +00:00
Labeeb Mattra
d24cb01a9d Add more loan interest accrual types
(cherry picked from commit a81da2ea85)
2022-07-12 12:56:35 +00:00
Labeeb Mattra
ab214bcdfc update loan interest accrual types
(cherry picked from commit 900c878e03)
2022-07-12 12:56:35 +00:00
Frappe PR Bot
751fbd6794 chore(release): Bumped to Version 13.35.2
## [13.35.2](https://github.com/frappe/erpnext/compare/v13.35.1...v13.35.2) (2022-07-12)

### Bug Fixes

* components in the same table don't get updated value of prev payment-days based component ([01beb6f](01beb6f391))
* conflicts ([2045df1](2045df19f9))
* Incorrect provisional expense booking while reposting ([d182137](d182137ed1))
* timeout error while reposting ([07b80c2](07b80c295d))
* Use Contact Name instead of Supplier in RFQ Email ([b0e17de](b0e17dea2a))
* Use fallback conversion factor while setting incoming rate for petty purchase ([2a432c2](2a432c22d4))
* Validate payment-days-based dependent component ([a28c7cf](a28c7cf094))
2022-07-12 09:29:26 +00:00
Deepesh Garg
36566c1d14 Merge pull request #31574 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-07-12 14:57:39 +05:30
Rucha Mahabal
28e4e4320e Merge pull request #31521 from ruchamahabal/fix-salary-calc-pd
fix: components in the same table don't get updated value of prev payment-days based component
2022-07-12 12:06:21 +05:30
Rucha Mahabal
1133062bfc Merge branch 'version-13-hotfix' into fix-salary-calc-pd 2022-07-12 11:42:07 +05:30
Rucha Mahabal
a28c7cf094 fix: Validate payment-days-based dependent component 2022-07-12 11:39:00 +05:30
Deepesh Garg
1c686c732e chore: fix query
(cherry picked from commit e04e67c6bf)
2022-07-11 15:44:49 +00:00
Deepesh Garg
66c5290dee chore: Ignore validation
(cherry picked from commit 3cf609fab1)
2022-07-11 15:44:49 +00:00
Deepesh Garg
9ac9c46dab fix: Allow multi currency invoice against single party account
(cherry picked from commit c83fbd5c50)

# Conflicts:
#	erpnext/accounts/doctype/accounts_settings/accounts_settings.json
2022-07-11 15:44:48 +00:00
Sagar Sharma
faa489bc73 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31412 2022-07-11 17:11:21 +05:30
Sagar Sharma
b17850ac3e chore: conflicts 2022-07-11 17:09:30 +05:30
Marica
7d36bdf292 Merge pull request #31565 from frappe/mergify/bp/version-13-hotfix/pr-31550
fix: Use Contact Name instead of Supplier in RFQ Email (backport #31550)
2022-07-11 12:35:18 +05:30
marination
b331c462ef chore: Instantiate variable unconditionally
(cherry picked from commit 300e812a1f)
2022-07-11 05:52:08 +00:00
marination
b0e17dea2a fix: Use Contact Name instead of Supplier in RFQ Email
(cherry picked from commit 88ac519b24)
2022-07-11 05:52:07 +00:00
Frappe PR Bot
be3b010b44 chore(release): Bumped to Version 13.35.1
## [13.35.1](https://github.com/frappe/erpnext/compare/v13.35.0...v13.35.1) (2022-07-08)

### Bug Fixes

* Use fallback conversion factor while setting incoming rate for petty purchase ([bac8546](bac854628f))
2022-07-08 10:20:30 +00:00
Deepesh Garg
45799f51b3 Merge pull request #31558 from frappe/mergify/bp/version-13/pr-31529
fix: Use fallback conversion factor while setting incoming rate for petty purchase (backport #31529)
2022-07-08 15:48:47 +05:30
marination
bac854628f fix: Use fallback conversion factor while setting incoming rate for petty purchase
- PIs for petty items (that do not need an Item record) are allowed using Item Name field
- If a different UOM is used in this case, conversion factor stays 0 and causes an error
- Fallback to 1 in `set_incoming_rate` for buying
- Selling will need a proper item, so this change is not needed there

(cherry picked from commit aa043fe961)
2022-07-08 09:47:05 +00:00
Deepesh Garg
6d04bafb04 Merge pull request #31518 from frappe/mergify/bp/version-13-hotfix/pr-31516
fix: Incorrect provisional expense booking while reposting (backport #31516)
2022-07-07 11:53:58 +05:30
rohitwaghchaure
c4f39c7b8b Merge pull request #31538 from frappe/mergify/bp/version-13-hotfix/pr-31519
fix: timeout error while reposting (backport #31519)
2022-07-06 14:33:26 +05:30
rohitwaghchaure
2045df19f9 fix: conflicts 2022-07-06 12:34:10 +05:30
Rohit Waghchaure
07b80c295d fix: timeout error while reposting
(cherry picked from commit 78c8bb251e)

# Conflicts:
#	erpnext/stock/doctype/stock_entry/test_stock_entry.py
2022-07-06 07:02:31 +00:00
Marica
a8c3882400 Merge pull request #31534 from frappe/mergify/bp/version-13-hotfix/pr-31529
fix: Use fallback conversion factor while setting incoming rate for petty purchase (backport #31529)
2022-07-06 01:20:51 +05:30
marination
2a432c22d4 fix: Use fallback conversion factor while setting incoming rate for petty purchase
- PIs for petty items (that do not need an Item record) are allowed using Item Name field
- If a different UOM is used in this case, conversion factor stays 0 and causes an error
- Fallback to 1 in `set_incoming_rate` for buying
- Selling will need a proper item, so this change is not needed there

(cherry picked from commit aa043fe961)
2022-07-05 19:09:36 +00:00
Deepesh Garg
776e807ade Merge pull request #31530 from vorasmit/warn-remove-india
chore: deprecation warning for remove-india
2022-07-05 22:46:33 +05:30
Smit Vora
6bda2a0865 chore: deprecation warning for remove-india 2022-07-05 21:20:51 +05:30
Frappe PR Bot
5072e6b1dc chore(release): Bumped to Version 13.35.0
# [13.35.0](https://github.com/frappe/erpnext/compare/v13.34.2...v13.35.0) (2022-07-05)

### Bug Fixes

* **India:** Discounts in E-Invoicing ([9ba7290](9ba7290dc9))
* Internal PI link in Sales Invoice ([8727a6c](8727a6c5da))
* Modify opts parameter misspell (backport [#31476](https://github.com/frappe/erpnext/issues/31476)) ([#31477](https://github.com/frappe/erpnext/issues/31477)) ([4d987a9](4d987a9510)), closes [#31474](https://github.com/frappe/erpnext/issues/31474)
* offset some scheduled jobs to avoid locks (backport [#31466](https://github.com/frappe/erpnext/issues/31466)) ([#31489](https://github.com/frappe/erpnext/issues/31489)) ([b1c6d78](b1c6d789a9))
* **UX:** dont apply price list  when changing batch on mapped docs (backport [#31503](https://github.com/frappe/erpnext/issues/31503)) ([#31504](https://github.com/frappe/erpnext/issues/31504)) ([31fd263](31fd263825))

### Features

* Cash and Non trade discounts in Sales Invoice ([fd2ec25](fd2ec25588))
2022-07-05 08:55:20 +00:00
Deepesh Garg
a8180796db Merge pull request #31524 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-07-05 14:22:20 +05:30
Rucha Mahabal
01beb6f391 fix: components in the same table don't get updated value of prev payment-days based component 2022-07-04 23:14:26 +05:30
Deepesh Garg
d182137ed1 fix: Incorrect provisional expense booking while reposting
(cherry picked from commit 60aad31162)
2022-07-04 14:58:41 +00:00
mergify[bot]
31fd263825 fix(UX): dont apply price list when changing batch on mapped docs (backport #31503) (#31504)
fix(UX): dont apply price list  when changing batch on mapped docs (#31503)

fix(UX): dont apply price list batch change on mapped docs

(cherry picked from commit 7e40c86c56)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-07-04 17:02:11 +05:30
Ankush Menat
5fc93076f4 chore: ignore late binding warnings
Most are false positives

[skip ci]
2022-07-04 13:22:01 +05:30
Deepesh Garg
827794b676 Merge pull request #31510 from frappe/mergify/bp/version-13-hotfix/pr-31405
feat: Cash and Non trade discounts in Sales Invoice (backport #31405)
2022-07-04 11:58:45 +05:30
Deepesh Garg
c72ae178fa chore: resolve conflicts 2022-07-03 14:05:34 +05:30
Deepesh Garg
4a5d681c77 chore: use get instead of . operator
(cherry picked from commit e54ec4b9b6)
2022-07-03 08:05:23 +00:00
Deepesh Garg
57dc1026c8 test: Add test for einvoice discounts
(cherry picked from commit 38352b3e46)
2022-07-03 08:05:22 +00:00
Deepesh Garg
9ba7290dc9 fix(India): Discounts in E-Invoicing
(cherry picked from commit f337213f33)
2022-07-03 08:05:21 +00:00
Deepesh Garg
fd2ec25588 feat: Cash and Non trade discounts in Sales Invoice
(cherry picked from commit 169ff5a0dd)

# Conflicts:
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2022-07-03 08:05:19 +00:00
Deepesh Garg
eb85ef974a Merge pull request #31508 from frappe/mergify/bp/version-13-hotfix/pr-31493
fix: Internal PI link in Sales Invoice (backport #31493)
2022-07-03 10:09:51 +05:30
Deepesh Garg
8727a6c5da fix: Internal PI link in Sales Invoice
(cherry picked from commit 536e768ba9)
2022-07-02 17:17:50 +00:00
Ankush Menat
1b9a4483d4 chore(meta): update CODEOWNERS 2022-07-01 15:44:18 +05:30
Deepesh Garg
fecf567e92 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31412 2022-06-30 16:46:59 +05:30
Ankush Menat
2e130c335a ci: reduce container count on v13 2022-06-30 11:38:12 +05:30
mergify[bot]
b1c6d789a9 fix: offset some scheduled jobs to avoid locks (backport #31466) (#31489)
fix: offset some scheduled jobs to avoid locks (#31466)

If your site has multiple background workers then there's possibility
that two jobs will execute in parallal, this creates problem when both
are on operating on same data.

This PR adds a separate section for hourly and daily jobs which have
frequency offset from default frequency to avoid such conflicts.

(cherry picked from commit 5d73697c64)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-30 11:35:01 +05:30
mergify[bot]
4d987a9510 fix: Modify opts parameter misspell (backport #31476) (#31477)
fix: Modify opts parameter misspell (#31476)

Modify opts parameter misspell

closes #31474

(cherry picked from commit 2a619fd789)

Co-authored-by: gn306029 <gn306029@users.noreply.github.com>
2022-06-29 14:58:03 +05:30
Sagar Sharma
96bd493a6f Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31412 2022-06-24 13:17:43 +05:30
s-aga-r
def622c13e fix: set default_bom for item
(cherry picked from commit dc2830da4d)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/test_bom.py
2022-06-21 11:13:31 +00:00
281 changed files with 17786 additions and 10514 deletions

View File

@@ -66,6 +66,7 @@ ignore =
F841,
E713,
E712,
B023
max-line-length = 200

View File

@@ -25,7 +25,7 @@ jobs:
fail-fast: false
matrix:
container: [1, 2, 3]
container: [1, 2]
name: Python Unit Tests
@@ -93,7 +93,7 @@ jobs:
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
- name: Run Tests
run: cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --use-orchestrator
run: 'cd ~/frappe-bench/ && bench --site test_site run-parallel-tests --app erpnext --total-builds 2 --build-number ${{ matrix.container }}'
env:
TYPE: server
CI_BUILD_ID: ${{ github.run_id }}

View File

@@ -1,117 +0,0 @@
name: UI
on:
pull_request:
paths-ignore:
- '**.md'
workflow_dispatch:
concurrency:
group: ui-v13-${{ github.event.number }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-18.04
timeout-minutes: 60
strategy:
fail-fast: false
name: UI Tests (Cypress)
services:
mysql:
image: mariadb:10.3
env:
MYSQL_ALLOW_EMPTY_PASSWORD: YES
ports:
- 3306:3306
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
steps:
- name: Clone
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.7
- uses: actions/setup-node@v2
with:
node-version: 14
check-latest: true
- name: Add to Hosts
run: |
echo "127.0.0.1 test_site" | sudo tee -a /etc/hosts
- name: Cache pip
uses: actions/cache@v2
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
${{ runner.os }}-
- name: Cache node modules
uses: actions/cache@v2
env:
cache-name: cache-node-modules
with:
path: ~/.npm
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-${{ env.cache-name }}-
${{ runner.os }}-build-
${{ runner.os }}-
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v2
id: yarn-cache
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Cache cypress binary
uses: actions/cache@v2
with:
path: ~/.cache
key: ${{ runner.os }}-cypress-
restore-keys: |
${{ runner.os }}-cypress-
${{ runner.os }}-
- name: Install
run: bash ${GITHUB_WORKSPACE}/.github/helper/install.sh
env:
DB: mariadb
TYPE: ui
- name: Site Setup
run: cd ~/frappe-bench/ && bench --site test_site execute erpnext.setup.utils.before_tests
- name: cypress pre-requisites
run: cd ~/frappe-bench/apps/frappe && yarn add cypress-file-upload@^5 @testing-library/cypress@^8 --no-lockfile
- name: Build Assets
run: cd ~/frappe-bench/ && bench build
env:
CI: Yes
- name: UI Tests
run: cd ~/frappe-bench/ && bench --site test_site run-ui-tests erpnext --headless
env:
CYPRESS_RECORD_KEY: 60a8e3bf-08f5-45b1-9269-2b207d7d30cd
- name: Show bench console if tests failed
if: ${{ failure() }}
run: cat ~/frappe-bench/bench_run_logs.txt

View File

@@ -10,7 +10,7 @@
"@semantic-release/release-notes-generator",
[
"@semantic-release/exec", {
"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
"prepareCmd": 'sed -ir -E "s/\"[0-9]+\.[0-9]+\.[0-9]+\"/\"${nextRelease.version}\"/" erpnext/__init__.py'
}
],
[

View File

@@ -3,33 +3,31 @@
# These owners will be the default owners for everything in
# the repo. Unless a later match takes precedence,
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007
erpnext/assets/ @nextchamp-saqib @deepeshgarg007
erpnext/accounts/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/assets/ @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/erpnext_integrations/ @nextchamp-saqib
erpnext/loan_management/ @nextchamp-saqib @deepeshgarg007
erpnext/regional @nextchamp-saqib @deepeshgarg007
erpnext/selling @nextchamp-saqib @deepeshgarg007
erpnext/regional @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/selling @nextchamp-saqib @deepeshgarg007 @ruthra-kumar
erpnext/support/ @nextchamp-saqib @deepeshgarg007
pos* @nextchamp-saqib
erpnext/buying/ @marination @rohitwaghchaure @ankush
erpnext/e_commerce/ @marination
erpnext/maintenance/ @marination @rohitwaghchaure
erpnext/manufacturing/ @marination @rohitwaghchaure @ankush
erpnext/portal/ @marination
erpnext/quality_management/ @marination @rohitwaghchaure
erpnext/shopping_cart/ @marination
erpnext/stock/ @marination @rohitwaghchaure @ankush
erpnext/buying/ @rohitwaghchaure @s-aga-r
erpnext/maintenance/ @rohitwaghchaure @s-aga-r
erpnext/manufacturing/ @rohitwaghchaure @s-aga-r
erpnext/quality_management/ @rohitwaghchaure @s-aga-r
erpnext/stock/ @rohitwaghchaure @s-aga-r
erpnext/crm/ @ruchamahabal @pateljannat
erpnext/education/ @ruchamahabal @pateljannat
erpnext/healthcare/ @ruchamahabal @pateljannat @chillaranand
erpnext/hr/ @ruchamahabal @pateljannat
erpnext/healthcare/ @chillaranand
erpnext/hr/ @ruchamahabal
erpnext/non_profit/ @ruchamahabal
erpnext/payroll @ruchamahabal @pateljannat
erpnext/projects/ @ruchamahabal @pateljannat
erpnext/payroll @ruchamahabal
erpnext/projects/ @ruchamahabal
erpnext/controllers @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure @marination
erpnext/patches/ @deepeshgarg007 @nextchamp-saqib @rohitwaghchaure
erpnext/public/ @nextchamp-saqib @marination
.github/ @surajshetty3416 @ankush
requirements.txt @gavindsouza
.github/ @ankush
requirements.txt @gavindsouza @ankush

View File

@@ -65,6 +65,8 @@ GNU/General Public License (see [license.txt](license.txt))
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
By contributing to ERPNext, you agree that your contributions will be licensed under its GNU General Public License (v3).
---
## Contributing

View File

@@ -4,7 +4,7 @@ import frappe
from erpnext.hooks import regional_overrides
__version__ = "13.34.2"
__version__ = "13.40.2"
def get_default_company(user=None):

View File

@@ -19,6 +19,7 @@
"book_asset_depreciation_entry_automatically",
"unlink_advance_payment_on_cancelation_of_order",
"enable_common_party_accounting",
"allow_multi_currency_invoices_against_single_party_account",
"post_change_gl_entries",
"enable_discount_accounting",
"tax_settings_section",
@@ -276,14 +277,21 @@
"fieldname": "enable_common_party_accounting",
"fieldtype": "Check",
"label": "Enable Common Party Accounting"
}
},
{
"default": "0",
"description": "Enabling this will allow creation of multi-currency invoices against single party account in company currency",
"fieldname": "allow_multi_currency_invoices_against_single_party_account",
"fieldtype": "Check",
"label": "Allow multi-currency invoices against single party account"
}
],
"icon": "icon-cog",
"idx": 1,
"index_web_pages_for_search": 1,
"issingle": 1,
"links": [],
"modified": "2021-10-11 17:42:36.427699",
"modified": "2022-07-11 13:37:50.605141",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounts Settings",

View File

@@ -43,7 +43,7 @@ class GLEntry(Document):
self.validate_and_set_fiscal_year()
self.pl_must_have_cost_center()
if not self.flags.from_repost:
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
self.check_mandatory()
self.validate_cost_center()
self.check_pl_account()
@@ -52,7 +52,7 @@ class GLEntry(Document):
def on_update(self):
adv_adj = self.flags.adv_adj
if not self.flags.from_repost:
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
self.validate_account_details(adv_adj)
self.validate_dimensions_for_pl_and_bs()
self.validate_allowed_dimensions()
@@ -358,7 +358,7 @@ def update_outstanding_amt(
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
# Didn't use db_set for optimisation purpose
# Didn't use db_set for optimization purpose
ref_doc.outstanding_amount = bal
frappe.db.set_value(against_voucher_type, against_voucher, "outstanding_amount", bal)

View File

@@ -173,8 +173,8 @@ frappe.ui.form.on("Journal Entry", {
var update_jv_details = function(doc, r) {
$.each(r, function(i, d) {
var row = frappe.model.add_child(doc, "Journal Entry Account", "accounts");
row.account = d.account;
row.balance = d.balance;
frappe.model.set_value(row.doctype, row.name, "account", d.account)
frappe.model.set_value(row.doctype, row.name, "balance", d.balance)
});
refresh_field("accounts");
}

View File

@@ -25,7 +25,10 @@ from erpnext.accounts.utils import (
get_stock_and_account_balance,
)
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.hr.doctype.expense_claim.expense_claim import (
get_outstanding_amount_for_claim,
update_reimbursed_amount,
)
class StockAccountInvalidTransaction(frappe.ValidationError):
@@ -191,7 +194,9 @@ class JournalEntry(AccountsController):
}
)
tax_withholding_details = get_party_tax_withholding_details(inv, self.tax_withholding_category)
tax_withholding_details, advance_taxes, voucher_wise_amount = get_party_tax_withholding_details(
inv, self.tax_withholding_category
)
if not tax_withholding_details:
return
@@ -935,15 +940,12 @@ class JournalEntry(AccountsController):
def validate_expense_claim(self):
for d in self.accounts:
if d.reference_type == "Expense Claim":
sanctioned_amount, reimbursed_amount = frappe.db.get_value(
"Expense Claim", d.reference_name, ("total_sanctioned_amount", "total_amount_reimbursed")
)
pending_amount = flt(sanctioned_amount) - flt(reimbursed_amount)
if d.debit > pending_amount:
outstanding_amt = get_outstanding_amount_for_claim(d.reference_name)
if d.debit > outstanding_amt:
frappe.throw(
_(
"Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}"
).format(d.idx, d.reference_name, pending_amount)
"Row No {0}: Amount cannot be greater than the Outstanding Amount against Expense Claim {1}. Outstanding Amount is {2}"
).format(d.idx, d.reference_name, outstanding_amt)
)
def validate_credit_debit_note(self):

View File

@@ -2,7 +2,7 @@
// For license information, please see license.txt
frappe.ui.form.on("Journal Entry Template", {
setup: function(frm) {
refresh: function(frm) {
frappe.model.set_default_values(frm.doc);
frm.set_query("account" ,"accounts", function(){

View File

@@ -49,7 +49,15 @@ frappe.ui.form.on('Opening Invoice Creation Tool', {
doc: frm.doc,
btn: $(btn_primary),
method: "make_invoices",
freeze_message: __("Creating {0} Invoice", [frm.doc.invoice_type])
freeze: 1,
freeze_message: __("Creating {0} Invoice", [frm.doc.invoice_type]),
callback: function(r) {
if (r.message.length == 1) {
frappe.msgprint(__("{0} Invoice created successfully.", [frm.doc.invoice_type]));
} else if (r.message.length < 50) {
frappe.msgprint(__("{0} Invoices created successfully.", [frm.doc.invoice_type]));
}
}
});
});

View File

@@ -1111,7 +1111,7 @@ frappe.ui.form.on('Payment Entry', {
$.each(tax_fields, function(i, fieldname) { tax[fieldname] = 0.0; });
frm.doc.paid_amount_after_tax = frm.doc.paid_amount;
frm.doc.paid_amount_after_tax = frm.doc.base_paid_amount;
});
},
@@ -1202,7 +1202,7 @@ frappe.ui.form.on('Payment Entry', {
}
cumulated_tax_fraction += tax.tax_fraction_for_current_item;
frm.doc.paid_amount_after_tax = flt(frm.doc.paid_amount/(1+cumulated_tax_fraction))
frm.doc.paid_amount_after_tax = flt(frm.doc.base_paid_amount/(1+cumulated_tax_fraction))
});
},
@@ -1234,6 +1234,7 @@ frappe.ui.form.on('Payment Entry', {
frm.doc.total_taxes_and_charges = 0.0;
frm.doc.base_total_taxes_and_charges = 0.0;
let company_currency = frappe.get_doc(":Company", frm.doc.company).default_currency;
let actual_tax_dict = {};
// maintain actual tax rate based on idx
@@ -1254,8 +1255,8 @@ frappe.ui.form.on('Payment Entry', {
}
}
tax.tax_amount = current_tax_amount;
tax.base_tax_amount = tax.tax_amount * frm.doc.source_exchange_rate;
// tax accounts are only in company currency
tax.base_tax_amount = current_tax_amount;
current_tax_amount *= (tax.add_deduct_tax == "Deduct") ? -1.0 : 1.0;
if(i==0) {
@@ -1264,9 +1265,29 @@ frappe.ui.form.on('Payment Entry', {
tax.total = flt(frm.doc["taxes"][i-1].total + current_tax_amount, precision("total", tax));
}
tax.base_total = tax.total * frm.doc.source_exchange_rate;
frm.doc.total_taxes_and_charges += current_tax_amount;
frm.doc.base_total_taxes_and_charges += current_tax_amount * frm.doc.source_exchange_rate;
// tac accounts are only in company currency
tax.base_total = tax.total
// calculate total taxes and base total taxes
if(frm.doc.payment_type == "Pay") {
// tax accounts only have company currency
if(tax.currency != frm.doc.paid_to_account_currency) {
//total_taxes_and_charges has the target currency. so using target conversion rate
frm.doc.total_taxes_and_charges += flt(current_tax_amount / frm.doc.target_exchange_rate);
} else {
frm.doc.total_taxes_and_charges += current_tax_amount;
}
} else if(frm.doc.payment_type == "Receive") {
if(tax.currency != frm.doc.paid_from_account_currency) {
//total_taxes_and_charges has the target currency. so using source conversion rate
frm.doc.total_taxes_and_charges += flt(current_tax_amount / frm.doc.source_exchange_rate);
} else {
frm.doc.total_taxes_and_charges += current_tax_amount;
}
}
frm.doc.base_total_taxes_and_charges += tax.base_tax_amount;
frm.refresh_field('taxes');
frm.refresh_field('total_taxes_and_charges');

View File

@@ -30,7 +30,10 @@ from erpnext.controllers.accounts_controller import (
get_supplier_block_status,
validate_taxes_and_charges,
)
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.hr.doctype.expense_claim.expense_claim import (
get_outstanding_amount_for_claim,
update_reimbursed_amount,
)
from erpnext.setup.utils import get_exchange_rate
@@ -302,7 +305,7 @@ class PaymentEntry(AccountsController):
def validate_reference_documents(self):
if self.party_type == "Student":
valid_reference_doctypes = "Fees"
valid_reference_doctypes = ("Fees", "Journal Entry")
elif self.party_type == "Customer":
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry", "Dunning")
elif self.party_type == "Supplier":
@@ -941,6 +944,13 @@ class PaymentEntry(AccountsController):
)
if not d.included_in_paid_amount:
if get_account_currency(payment_account) != self.company_currency:
if self.payment_type == "Receive":
exchange_rate = self.target_exchange_rate
elif self.payment_type in ["Pay", "Internal Transfer"]:
exchange_rate = self.source_exchange_rate
base_tax_amount = flt((tax_amount / exchange_rate), self.precision("paid_amount"))
gl_entries.append(
self.get_gl_dict(
{
@@ -1056,7 +1066,7 @@ class PaymentEntry(AccountsController):
for fieldname in tax_fields:
tax.set(fieldname, 0.0)
self.paid_amount_after_tax = self.paid_amount
self.paid_amount_after_tax = self.base_paid_amount
def determine_exclusive_rate(self):
if not any((cint(tax.included_in_paid_amount) for tax in self.get("taxes"))):
@@ -1075,7 +1085,7 @@ class PaymentEntry(AccountsController):
cumulated_tax_fraction += tax.tax_fraction_for_current_item
self.paid_amount_after_tax = flt(self.paid_amount / (1 + cumulated_tax_fraction))
self.paid_amount_after_tax = flt(self.base_paid_amount / (1 + cumulated_tax_fraction))
def calculate_taxes(self):
self.total_taxes_and_charges = 0.0
@@ -1098,7 +1108,7 @@ class PaymentEntry(AccountsController):
current_tax_amount += actual_tax_dict[tax.idx]
tax.tax_amount = current_tax_amount
tax.base_tax_amount = tax.tax_amount * self.source_exchange_rate
tax.base_tax_amount = current_tax_amount
if tax.add_deduct_tax == "Deduct":
current_tax_amount *= -1.0
@@ -1112,14 +1122,20 @@ class PaymentEntry(AccountsController):
self.get("taxes")[i - 1].total + current_tax_amount, self.precision("total", tax)
)
tax.base_total = tax.total * self.source_exchange_rate
tax.base_total = tax.total
if self.payment_type == "Pay":
self.base_total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
self.total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
else:
self.base_total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
self.total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
if tax.currency != self.paid_to_account_currency:
self.total_taxes_and_charges += flt(current_tax_amount / self.target_exchange_rate)
else:
self.total_taxes_and_charges += current_tax_amount
elif self.payment_type == "Receive":
if tax.currency != self.paid_from_account_currency:
self.total_taxes_and_charges += flt(current_tax_amount / self.source_exchange_rate)
else:
self.total_taxes_and_charges += current_tax_amount
self.base_total_taxes_and_charges += tax.base_tax_amount
if self.get("taxes"):
self.paid_amount_after_tax = self.get("taxes")[-1].base_total
@@ -1649,12 +1665,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
outstanding_amount = ref_doc.get("outstanding_amount")
bill_no = ref_doc.get("bill_no")
elif reference_doctype == "Expense Claim":
outstanding_amount = (
flt(ref_doc.get("total_sanctioned_amount"))
+ flt(ref_doc.get("total_taxes_and_charges"))
- flt(ref_doc.get("total_amount_reimbursed"))
- flt(ref_doc.get("total_advance_amount"))
)
outstanding_amount = get_outstanding_amount_for_claim(ref_doc)
elif reference_doctype == "Employee Advance":
outstanding_amount = flt(ref_doc.advance_amount) - flt(ref_doc.paid_amount)
if party_account_currency != ref_doc.currency:

View File

@@ -4,6 +4,7 @@
import unittest
import frappe
from frappe import qb
from frappe.utils import flt, nowdate
from erpnext.accounts.doctype.payment_entry.payment_entry import (
@@ -743,6 +744,46 @@ class TestPaymentEntry(unittest.TestCase):
flt(payment_entry.total_taxes_and_charges, 2), flt(10 / payment_entry.target_exchange_rate, 2)
)
def test_gl_of_multi_currency_payment_with_taxes(self):
payment_entry = create_payment_entry(
party="_Test Supplier USD", paid_to="_Test Payable USD - _TC", save=True
)
payment_entry.append(
"taxes",
{
"account_head": "_Test Account Service Tax - _TC",
"charge_type": "Actual",
"tax_amount": 100,
"add_deduct_tax": "Add",
"description": "Test",
},
)
payment_entry.target_exchange_rate = 80
payment_entry.received_amount = 12.5
payment_entry = payment_entry.submit()
gle = qb.DocType("GL Entry")
gl_entries = (
qb.from_(gle)
.select(
gle.account,
gle.debit,
gle.credit,
gle.debit_in_account_currency,
gle.credit_in_account_currency,
)
.orderby(gle.account)
.where(gle.voucher_no == payment_entry.name)
.run()
)
expected_gl_entries = (
("_Test Account Service Tax - _TC", 100.0, 0.0, 100.0, 0.0),
("_Test Bank - _TC", 0.0, 1100.0, 0.0, 1100.0),
("_Test Payable USD - _TC", 1000.0, 0.0, 12.5, 0),
)
self.assertEqual(gl_entries, expected_gl_entries)
def test_payment_entry_against_onhold_purchase_invoice(self):
pi = make_purchase_invoice()

View File

@@ -8,7 +8,11 @@ from frappe.model.document import Document
from frappe.utils import flt, getdate, nowdate, today
import erpnext
from erpnext.accounts.utils import get_outstanding_invoices, reconcile_against_document
from erpnext.accounts.utils import (
get_outstanding_invoices,
reconcile_against_document,
update_reference_in_payment_entry,
)
from erpnext.controllers.accounts_controller import get_advance_payment_entries
@@ -190,6 +194,23 @@ class PaymentReconciliation(Document):
inv.currency = entry.get("currency")
inv.outstanding_amount = flt(entry.get("outstanding_amount"))
def get_difference_amount(self, allocated_entry):
if allocated_entry.get("reference_type") != "Payment Entry":
return
dr_or_cr = (
"credit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "debit_in_account_currency"
)
row = self.get_payment_details(allocated_entry, dr_or_cr)
doc = frappe.get_doc(allocated_entry.reference_type, allocated_entry.reference_name)
update_reference_in_payment_entry(row, doc, do_not_save=True)
return doc.difference_amount
@frappe.whitelist()
def allocate_entries(self, args):
self.validate_entries()
@@ -205,12 +226,16 @@ class PaymentReconciliation(Document):
res = self.get_allocated_entry(pay, inv, pay["amount"])
inv["outstanding_amount"] = flt(inv.get("outstanding_amount")) - flt(pay.get("amount"))
pay["amount"] = 0
res.difference_amount = self.get_difference_amount(res)
if pay.get("amount") == 0:
entries.append(res)
break
elif inv.get("outstanding_amount") == 0:
entries.append(res)
continue
else:
break
@@ -332,7 +357,7 @@ class PaymentReconciliation(Document):
def get_conditions(self, get_invoices=False, get_payments=False, get_return_invoices=False):
condition = " and company = '{0}' ".format(self.company)
if self.get("cost_center") and (get_invoices or get_payments or get_return_invoices):
if self.get("cost_center"):
condition = " and cost_center = '{0}' ".format(self.cost_center)
if get_invoices:

View File

@@ -186,8 +186,10 @@
{
"fetch_from": "bank_account.bank",
"fieldname": "bank",
"fieldtype": "Read Only",
"label": "Bank"
"fieldtype": "Link",
"label": "Bank",
"options": "Bank",
"read_only": 1
},
{
"fetch_from": "bank_account.bank_account_no",
@@ -366,10 +368,11 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2020-09-18 12:24:14.178853",
"modified": "2022-09-30 16:19:43.680025",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Request",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
@@ -401,5 +404,6 @@
}
],
"sort_field": "modified",
"sort_order": "DESC"
"sort_order": "DESC",
"states": []
}

View File

@@ -39,6 +39,7 @@
{
"columns": 2,
"fetch_from": "payment_term.description",
"fetch_if_empty": 1,
"fieldname": "description",
"fieldtype": "Small Text",
"in_list_view": 1,
@@ -159,7 +160,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-04-28 05:41:35.084233",
"modified": "2022-09-16 13:57:06.382859",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Schedule",
@@ -168,5 +169,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -10,10 +10,11 @@
"fiscal_year",
"amended_from",
"company",
"cost_center_wise_pnl",
"column_break1",
"closing_account_head",
"remarks"
"remarks",
"gle_processing_status",
"error_message"
],
"fields": [
{
@@ -86,17 +87,26 @@
"reqd": 1
},
{
"default": "0",
"fieldname": "cost_center_wise_pnl",
"fieldtype": "Check",
"label": "Book Cost Center Wise Profit/Loss"
"depends_on": "eval:doc.docstatus!=0",
"fieldname": "gle_processing_status",
"fieldtype": "Select",
"label": "GL Entry Processing Status",
"options": "In Progress\nCompleted\nFailed",
"read_only": 1
},
{
"depends_on": "eval:doc.gle_processing_status=='Failed'",
"fieldname": "error_message",
"fieldtype": "Text",
"label": "Error Message",
"read_only": 1
}
],
"icon": "fa fa-file-text",
"idx": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-05-20 15:27:37.210458",
"modified": "2022-07-20 14:51:04.714154",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Period Closing Voucher",

View File

@@ -8,7 +8,6 @@ from frappe.utils import flt
from erpnext.accounts.doctype.accounting_dimension.accounting_dimension import (
get_accounting_dimensions,
get_dimensions,
)
from erpnext.accounts.utils import get_account_currency
from erpnext.controllers.accounts_controller import AccountsController
@@ -20,13 +19,28 @@ class PeriodClosingVoucher(AccountsController):
self.validate_posting_date()
def on_submit(self):
self.db_set("gle_processing_status", "In Progress")
self.make_gl_entries()
def on_cancel(self):
self.db_set("gle_processing_status", "In Progress")
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
from erpnext.accounts.general_ledger import make_reverse_gl_entries
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
gle_count = frappe.db.count(
"GL Entry",
{"voucher_type": "Period Closing Voucher", "voucher_no": self.name, "is_cancelled": 0},
)
if gle_count > 5000:
frappe.enqueue(
make_reverse_gl_entries,
voucher_type="Period Closing Voucher",
voucher_no=self.name,
queue="long",
)
frappe.msgprint(
_("The GL Entries will be cancelled in the background, it can take a few minutes."), alert=True
)
else:
make_reverse_gl_entries(voucher_type="Period Closing Voucher", voucher_no=self.name)
def validate_account_head(self):
closing_account_type = frappe.db.get_value("Account", self.closing_account_head, "root_type")
@@ -67,90 +81,80 @@ class PeriodClosingVoucher(AccountsController):
def make_gl_entries(self):
gl_entries = self.get_gl_entries()
if gl_entries:
from erpnext.accounts.general_ledger import make_gl_entries
make_gl_entries(gl_entries)
if len(gl_entries) > 5000:
frappe.enqueue(process_gl_entries, gl_entries=gl_entries, queue="long")
frappe.msgprint(
_("The GL Entries will be processed in the background, it can take a few minutes."),
alert=True,
)
else:
process_gl_entries(gl_entries)
def get_gl_entries(self):
gl_entries = []
pl_accounts = self.get_pl_balances()
for acc in pl_accounts:
# pl account
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=True):
if flt(acc.bal_in_company_currency):
gl_entries.append(
self.get_gl_dict(
{
"account": acc.account,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) < 0
else 0,
"debit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) < 0
else 0,
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) > 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) > 0
else 0,
},
item=acc,
)
)
gl_entries.append(self.get_gle_for_pl_account(acc))
if gl_entries:
gle_for_net_pl_bal = self.get_pnl_gl_entry(pl_accounts)
gl_entries += gle_for_net_pl_bal
# closing liability account
for acc in self.get_pl_balances_based_on_dimensions(group_by_account=False):
if flt(acc.bal_in_company_currency):
gl_entries.append(self.get_gle_for_closing_account(acc))
return gl_entries
def get_pnl_gl_entry(self, pl_accounts):
company_cost_center = frappe.db.get_value("Company", self.company, "cost_center")
gl_entries = []
def get_gle_for_pl_account(self, acc):
gl_entry = self.get_gl_dict(
{
"account": acc.account,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) < 0
else 0,
"debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0,
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) > 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
},
item=acc,
)
self.update_default_dimensions(gl_entry, acc)
return gl_entry
for acc in pl_accounts:
if flt(acc.bal_in_company_currency):
cost_center = acc.cost_center if self.cost_center_wise_pnl else company_cost_center
gl_entry = self.get_gl_dict(
{
"account": self.closing_account_head,
"cost_center": cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) > 0
else 0,
"debit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) > 0
else 0,
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) < 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency))
if flt(acc.bal_in_company_currency) < 0
else 0,
},
item=acc,
)
def get_gle_for_closing_account(self, acc):
gl_entry = self.get_gl_dict(
{
"account": self.closing_account_head,
"cost_center": acc.cost_center,
"finance_book": acc.finance_book,
"account_currency": acc.account_currency,
"debit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) > 0
else 0,
"debit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) > 0 else 0,
"credit_in_account_currency": abs(flt(acc.bal_in_account_currency))
if flt(acc.bal_in_account_currency) < 0
else 0,
"credit": abs(flt(acc.bal_in_company_currency)) if flt(acc.bal_in_company_currency) < 0 else 0,
},
item=acc,
)
self.update_default_dimensions(gl_entry, acc)
return gl_entry
self.update_default_dimensions(gl_entry)
gl_entries.append(gl_entry)
return gl_entries
def update_default_dimensions(self, gl_entry):
def update_default_dimensions(self, gl_entry, acc):
if not self.accounting_dimensions:
self.accounting_dimensions = get_accounting_dimensions()
_, default_dimensions = get_dimensions()
for dimension in self.accounting_dimensions:
gl_entry.update({dimension: default_dimensions.get(self.company, {}).get(dimension)})
gl_entry.update({dimension: acc.get(dimension)})
def get_pl_balances(self):
def get_pl_balances_based_on_dimensions(self, group_by_account=False):
"""Get balance for dimension-wise pl accounts"""
dimension_fields = ["t1.cost_center", "t1.finance_book"]
@@ -159,20 +163,56 @@ class PeriodClosingVoucher(AccountsController):
for dimension in self.accounting_dimensions:
dimension_fields.append("t1.{0}".format(dimension))
if group_by_account:
dimension_fields.append("t1.account")
return frappe.db.sql(
"""
select
t1.account, t2.account_currency, {dimension_fields},
t2.account_currency,
{dimension_fields},
sum(t1.debit_in_account_currency) - sum(t1.credit_in_account_currency) as bal_in_account_currency,
sum(t1.debit) - sum(t1.credit) as bal_in_company_currency
from `tabGL Entry` t1, `tabAccount` t2
where t1.is_cancelled = 0 and t1.account = t2.name and t2.report_type = 'Profit and Loss'
and t2.docstatus < 2 and t2.company = %s
and t1.posting_date between %s and %s
group by t1.account, {dimension_fields}
where
t1.is_cancelled = 0
and t1.account = t2.name
and t2.report_type = 'Profit and Loss'
and t2.docstatus < 2
and t2.company = %s
and t1.posting_date between %s and %s
group by {dimension_fields}
""".format(
dimension_fields=", ".join(dimension_fields)
),
(self.company, self.get("year_start_date"), self.posting_date),
as_dict=1,
)
def process_gl_entries(gl_entries):
from erpnext.accounts.general_ledger import make_gl_entries
try:
make_gl_entries(gl_entries, merge_entries=False)
frappe.db.set_value(
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Completed"
)
except Exception as e:
frappe.db.rollback()
frappe.log_error(e)
frappe.db.set_value(
"Period Closing Voucher", gl_entries[0].get("voucher_no"), "gle_processing_status", "Failed"
)
def make_reverse_gl_entries(voucher_type, voucher_no):
from erpnext.accounts.general_ledger import make_reverse_gl_entries
try:
make_reverse_gl_entries(voucher_type=voucher_type, voucher_no=voucher_no)
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Completed")
except Exception as e:
frappe.db.rollback()
frappe.log_error(e)
frappe.db.set_value("Period Closing Voucher", voucher_no, "gle_processing_status", "Failed")

View File

@@ -49,7 +49,7 @@ class TestPeriodClosingVoucher(unittest.TestCase):
expected_gle = (
("Cost of Goods Sold - TPC", 0.0, 600.0),
(surplus_account, 600.0, 400.0),
(surplus_account, 200.0, 0.0),
("Sales - TPC", 400.0, 0.0),
)
@@ -59,7 +59,8 @@ class TestPeriodClosingVoucher(unittest.TestCase):
""",
(pcv.name),
)
pcv.reload()
self.assertEqual(pcv.gle_processing_status, "Completed")
self.assertEqual(pcv_gle, expected_gle)
def test_cost_center_wise_posting(self):
@@ -94,7 +95,6 @@ class TestPeriodClosingVoucher(unittest.TestCase):
)
pcv = self.make_period_closing_voucher(submit=False)
pcv.cost_center_wise_pnl = 1
pcv.save()
pcv.submit()
surplus_account = pcv.closing_account_head
@@ -117,6 +117,16 @@ class TestPeriodClosingVoucher(unittest.TestCase):
self.assertEqual(pcv_gle, expected_gle)
pcv.reload()
pcv.cancel()
self.assertFalse(
frappe.db.get_value(
"GL Entry",
{"voucher_type": "Period Closing Voucher", "voucher_no": pcv.name, "is_cancelled": 0},
)
)
def test_period_closing_with_finance_book_entries(self):
frappe.db.sql("delete from `tabGL Entry` where company='Test PCV Company'")

View File

@@ -36,6 +36,15 @@ frappe.ui.form.on('POS Closing Entry', {
});
set_html_data(frm);
if (frm.doc.docstatus == 1) {
if (!frm.doc.posting_date) {
frm.set_value("posting_date", frappe.datetime.nowdate());
}
if (!frm.doc.posting_time) {
frm.set_value("posting_time", frappe.datetime.now_time());
}
}
},
refresh: function(frm) {

View File

@@ -11,6 +11,7 @@
"period_end_date",
"column_break_3",
"posting_date",
"posting_time",
"pos_opening_entry",
"status",
"section_break_5",
@@ -51,7 +52,6 @@
"fieldtype": "Datetime",
"in_list_view": 1,
"label": "Period End Date",
"read_only": 1,
"reqd": 1
},
{
@@ -219,6 +219,13 @@
"fieldtype": "Small Text",
"label": "Error",
"read_only": 1
},
{
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
"no_copy": 1,
"reqd": 1
}
],
"is_submittable": 1,
@@ -228,10 +235,11 @@
"link_fieldname": "pos_closing_entry"
}
],
"modified": "2021-10-20 16:19:25.340565",
"modified": "2022-08-01 11:37:14.991228",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Closing Entry",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
@@ -278,5 +286,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -15,6 +15,9 @@ from erpnext.controllers.status_updater import StatusUpdater
class POSClosingEntry(StatusUpdater):
def validate(self):
self.posting_date = self.posting_date or frappe.utils.nowdate()
self.posting_time = self.posting_time or frappe.utils.nowtime()
if frappe.db.get_value("POS Opening Entry", self.pos_opening_entry, "status") != "Open":
frappe.throw(_("Selected POS Opening Entry should be open."), title=_("Invalid Opening Entry"))

View File

@@ -1572,7 +1572,7 @@
"icon": "fa fa-file-text",
"is_submittable": 1,
"links": [],
"modified": "2022-03-22 13:00:24.166684",
"modified": "2022-09-27 13:00:24.166684",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice",

View File

@@ -222,9 +222,6 @@ class POSInvoice(SalesInvoice):
allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
for d in self.get("items"):
is_service_item = not (frappe.db.get_value("Item", d.get("item_code"), "is_stock_item"))
if is_service_item:
return
if d.serial_no:
self.validate_pos_reserved_serial_nos(d)
self.validate_delivered_serial_nos(d)
@@ -242,14 +239,14 @@ class POSInvoice(SalesInvoice):
frappe.bold(d.warehouse),
frappe.bold(d.qty),
)
if flt(available_stock) <= 0:
if is_stock_item and flt(available_stock) <= 0:
frappe.throw(
_("Row #{}: Item Code: {} is not available under warehouse {}.").format(
d.idx, item_code, warehouse
),
title=_("Item Unavailable"),
)
elif flt(available_stock) < flt(d.qty):
elif is_stock_item and flt(available_stock) < flt(d.qty):
frappe.throw(
_(
"Row #{}: Stock quantity not enough for Item Code: {} under warehouse {}. Available quantity {}."
@@ -637,11 +634,12 @@ def get_stock_availability(item_code, warehouse):
pos_sales_qty = get_pos_reserved_qty(item_code, warehouse)
return bin_qty - pos_sales_qty, is_stock_item
else:
is_stock_item = False
is_stock_item = True
if frappe.db.exists("Product Bundle", item_code):
return get_bundle_availability(item_code, warehouse), is_stock_item
else:
# Is a service item
is_stock_item = False
# Is a service item or non_stock item
return 0, is_stock_item
@@ -655,7 +653,9 @@ def get_bundle_availability(bundle_item_code, warehouse):
available_qty = item_bin_qty - item_pos_reserved_qty
max_available_bundles = available_qty / item.qty
if bundle_bin_qty > max_available_bundles:
if bundle_bin_qty > max_available_bundles and frappe.get_value(
"Item", item.item_code, "is_stock_item"
):
bundle_bin_qty = max_available_bundles
pos_sales_qty = get_pos_reserved_qty(bundle_item_code, warehouse)
@@ -747,3 +747,7 @@ def add_return_modes(doc, pos_profile):
]:
payment_mode = get_mode_of_payment_info(mode_of_payment, doc.company)
append_payment(payment_mode[0])
def on_doctype_update():
frappe.db.add_index("POS Invoice", ["return_against"])

View File

@@ -495,6 +495,67 @@ class TestPOSInvoice(unittest.TestCase):
self.assertRaises(frappe.ValidationError, pos.submit)
def test_value_error_on_serial_no_validation(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
se = make_serialized_item(
company="_Test Company",
target_warehouse="Stores - _TC",
cost_center="Main - _TC",
expense_account="Cost of Goods Sold - _TC",
)
serial_nos = se.get("items")[0].serial_no
# make a pos invoice
pos = create_pos_invoice(
company="_Test Company",
debit_to="Debtors - _TC",
account_for_change_amount="Cash - _TC",
warehouse="Stores - _TC",
income_account="Sales - _TC",
expense_account="Cost of Goods Sold - _TC",
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
qty=1,
do_not_save=1,
)
pos.get("items")[0].has_serial_no = 1
pos.get("items")[0].serial_no = serial_nos.split("\n")[0]
pos.set("payments", [])
pos.append(
"payments", {"mode_of_payment": "Cash", "account": "Cash - _TC", "amount": 1000, "default": 1}
)
pos = pos.save().submit()
# make a return
pos_return = make_sales_return(pos.name)
pos_return.paid_amount = pos_return.grand_total
pos_return.save()
pos_return.submit()
# set docstatus to 2 for pos to trigger this issue
frappe.db.set_value("POS Invoice", pos.name, "docstatus", 2)
pos2 = create_pos_invoice(
company="_Test Company",
debit_to="Debtors - _TC",
account_for_change_amount="Cash - _TC",
warehouse="Stores - _TC",
income_account="Sales - _TC",
expense_account="Cost of Goods Sold - _TC",
cost_center="Main - _TC",
item=se.get("items")[0].item_code,
rate=1000,
qty=1,
do_not_save=1,
)
pos2.get("items")[0].has_serial_no = 1
pos2.get("items")[0].serial_no = serial_nos.split("\n")[0]
# Value error should not be triggered on validation
pos2.save()
def test_loyalty_points(self):
from erpnext.accounts.doctype.loyalty_program.loyalty_program import (
get_loyalty_program_details_with_points,

View File

@@ -6,6 +6,7 @@
"engine": "InnoDB",
"field_order": [
"posting_date",
"posting_time",
"merge_invoices_based_on",
"column_break_3",
"pos_closing_entry",
@@ -105,12 +106,19 @@
"label": "Customer Group",
"mandatory_depends_on": "eval:doc.merge_invoices_based_on == 'Customer Group'",
"options": "Customer Group"
},
{
"fieldname": "posting_time",
"fieldtype": "Time",
"label": "Posting Time",
"no_copy": 1,
"reqd": 1
}
],
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-09-14 11:17:19.001142",
"modified": "2022-08-01 11:36:42.456429",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Invoice Merge Log",
@@ -173,5 +181,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -9,7 +9,7 @@ from frappe import _
from frappe.core.page.background_jobs.background_jobs import get_info
from frappe.model.document import Document
from frappe.model.mapper import map_child_doc, map_doc
from frappe.utils import flt, getdate, nowdate
from frappe.utils import cint, flt, get_time, getdate, nowdate, nowtime
from frappe.utils.background_jobs import enqueue
from frappe.utils.scheduler import is_scheduler_inactive
@@ -79,6 +79,7 @@ class POSInvoiceMergeLog(Document):
if sales:
sales_invoice = self.process_merging_into_sales_invoice(sales)
self.flags.ignore_validate_update_after_submit = True
self.save() # save consolidated_sales_invoice & consolidated_credit_note ref in merge log
self.update_pos_invoices(pos_invoice_docs, sales_invoice, credit_note)
@@ -99,6 +100,7 @@ class POSInvoiceMergeLog(Document):
sales_invoice.is_consolidated = 1
sales_invoice.set_posting_time = 1
sales_invoice.posting_date = getdate(self.posting_date)
sales_invoice.posting_time = get_time(self.posting_time)
sales_invoice.save()
sales_invoice.submit()
@@ -115,6 +117,7 @@ class POSInvoiceMergeLog(Document):
credit_note.is_consolidated = 1
credit_note.set_posting_time = 1
credit_note.posting_date = getdate(self.posting_date)
credit_note.posting_time = get_time(self.posting_time)
# TODO: return could be against multiple sales invoice which could also have been consolidated?
# credit_note.return_against = self.consolidated_invoice
credit_note.save()
@@ -219,6 +222,9 @@ class POSInvoiceMergeLog(Document):
invoice.taxes_and_charges = None
invoice.ignore_pricing_rule = 1
invoice.customer = self.customer
invoice.disable_rounded_total = cint(
frappe.db.get_value("POS Profile", invoice.pos_profile, "disable_rounded_total")
)
if self.merge_invoices_based_on == "Customer Group":
invoice.flags.ignore_pos_profile = True
@@ -399,6 +405,9 @@ def create_merge_logs(invoice_by_customer, closing_entry=None):
merge_log.posting_date = (
getdate(closing_entry.get("posting_date")) if closing_entry else nowdate()
)
merge_log.posting_time = (
get_time(closing_entry.get("posting_time")) if closing_entry else nowtime()
)
merge_log.customer = customer
merge_log.pos_closing_entry = closing_entry.get("name") if closing_entry else None

View File

@@ -43,7 +43,9 @@
"currency",
"write_off_account",
"write_off_cost_center",
"write_off_limit",
"account_for_change_amount",
"disable_rounded_total",
"column_break_23",
"income_account",
"expense_account",
@@ -358,6 +360,21 @@
"fieldname": "validate_stock_on_save",
"fieldtype": "Check",
"label": "Validate Stock on Save"
},
{
"default": "1",
"description": "Auto write off precision loss while consolidation",
"fieldname": "write_off_limit",
"fieldtype": "Currency",
"label": "Write Off Limit",
"reqd": 1
},
{
"default": "0",
"description": "If enabled, the consolidated invoices will have rounded total disabled",
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"label": "Disable Rounded Total"
}
],
"icon": "icon-cog",
@@ -385,7 +402,7 @@
"link_fieldname": "pos_profile"
}
],
"modified": "2022-03-21 13:29:28.480533",
"modified": "2022-08-10 12:57:06.241439",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -269,6 +269,18 @@ def get_serial_no_for_item(args):
return item_details
def update_pricing_rule_uom(pricing_rule, args):
child_doc = {"Item Code": "items", "Item Group": "item_groups", "Brand": "brands"}.get(
pricing_rule.apply_on
)
apply_on_field = frappe.scrub(pricing_rule.apply_on)
for row in pricing_rule.get(child_doc):
if row.get(apply_on_field) == args.get(apply_on_field):
pricing_rule.uom = row.uom
def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=False):
from erpnext.accounts.doctype.pricing_rule.utils import (
get_applied_pricing_rules,
@@ -325,7 +337,8 @@ def get_pricing_rule_for_item(args, price_list_rate=0, doc=None, for_validate=Fa
if isinstance(pricing_rule, string_types):
pricing_rule = frappe.get_cached_doc("Pricing Rule", pricing_rule)
pricing_rule.apply_rule_on_other_items = get_pricing_rule_items(pricing_rule)
update_pricing_rule_uom(pricing_rule, args)
pricing_rule.apply_rule_on_other_items = get_pricing_rule_items(pricing_rule) or []
if pricing_rule.get("suggestion"):
continue
@@ -439,12 +452,15 @@ def apply_price_discount_rule(pricing_rule, item_details, args):
if pricing_rule.currency == args.currency:
pricing_rule_rate = pricing_rule.rate
# TODO https://github.com/frappe/erpnext/pull/23636 solve this in some other way.
if pricing_rule_rate:
is_blank_uom = pricing_rule.get("uom") != args.get("uom")
# Override already set price list rate (from item price)
# if pricing_rule_rate > 0
item_details.update(
{
"price_list_rate": pricing_rule_rate * args.get("conversion_factor", 1),
"price_list_rate": pricing_rule_rate
* (args.get("conversion_factor", 1) if is_blank_uom else 1),
}
)
item_details.update({"discount_percentage": 0.0})

View File

@@ -597,6 +597,121 @@ class TestPricingRule(unittest.TestCase):
frappe.get_doc("Item Price", {"item_code": "Water Flask"}).delete()
item.delete()
def test_item_price_with_blank_uom_pricing_rule(self):
properties = {
"item_code": "Item Blank UOM",
"stock_uom": "Nos",
"sales_uom": "Box",
"uoms": [dict(uom="Box", conversion_factor=10)],
}
item = make_item(properties=properties)
make_item_price("Item Blank UOM", "_Test Price List", 100)
pricing_rule_record = {
"doctype": "Pricing Rule",
"title": "_Test Item Blank UOM Rule",
"apply_on": "Item Code",
"items": [
{
"item_code": "Item Blank UOM",
}
],
"selling": 1,
"currency": "INR",
"rate_or_discount": "Rate",
"rate": 101,
"company": "_Test Company",
}
rule = frappe.get_doc(pricing_rule_record)
rule.insert()
si = create_sales_invoice(
do_not_save=True, item_code="Item Blank UOM", uom="Box", conversion_factor=10
)
si.selling_price_list = "_Test Price List"
si.save()
# If UOM is blank consider it as stock UOM and apply pricing_rule on all UOM.
# rate is 101, Selling UOM is Box that have conversion_factor of 10 so 101 * 10 = 1010
self.assertEqual(si.items[0].price_list_rate, 1010)
self.assertEqual(si.items[0].rate, 1010)
si.delete()
si = create_sales_invoice(do_not_save=True, item_code="Item Blank UOM", uom="Nos")
si.selling_price_list = "_Test Price List"
si.save()
# UOM is blank so consider it as stock UOM and apply pricing_rule on all UOM.
# rate is 101, Selling UOM is Nos that have conversion_factor of 1 so 101 * 1 = 101
self.assertEqual(si.items[0].price_list_rate, 101)
self.assertEqual(si.items[0].rate, 101)
si.delete()
rule.delete()
frappe.get_doc("Item Price", {"item_code": "Item Blank UOM"}).delete()
item.delete()
def test_item_price_with_selling_uom_pricing_rule(self):
properties = {
"item_code": "Item UOM other than Stock",
"stock_uom": "Nos",
"sales_uom": "Box",
"uoms": [dict(uom="Box", conversion_factor=10)],
}
item = make_item(properties=properties)
make_item_price("Item UOM other than Stock", "_Test Price List", 100)
pricing_rule_record = {
"doctype": "Pricing Rule",
"title": "_Test Item UOM other than Stock Rule",
"apply_on": "Item Code",
"items": [
{
"item_code": "Item UOM other than Stock",
"uom": "Box",
}
],
"selling": 1,
"currency": "INR",
"rate_or_discount": "Rate",
"rate": 101,
"company": "_Test Company",
}
rule = frappe.get_doc(pricing_rule_record)
rule.insert()
si = create_sales_invoice(
do_not_save=True, item_code="Item UOM other than Stock", uom="Box", conversion_factor=10
)
si.selling_price_list = "_Test Price List"
si.save()
# UOM is Box so apply pricing_rule only on Box UOM.
# Selling UOM is Box and as both UOM are same no need to multiply by conversion_factor.
self.assertEqual(si.items[0].price_list_rate, 101)
self.assertEqual(si.items[0].rate, 101)
si.delete()
si = create_sales_invoice(do_not_save=True, item_code="Item UOM other than Stock", uom="Nos")
si.selling_price_list = "_Test Price List"
si.save()
# UOM is Box so pricing_rule won't apply as selling_uom is Nos.
# As Pricing Rule is not applied price of 100 will be fetched from Item Price List.
self.assertEqual(si.items[0].price_list_rate, 100)
self.assertEqual(si.items[0].rate, 100)
si.delete()
rule.delete()
frappe.get_doc("Item Price", {"item_code": "Item UOM other than Stock"}).delete()
item.delete()
def test_pricing_rule_for_different_currency(self):
make_item("Test Sanitizer Item")

View File

@@ -111,6 +111,12 @@ def _get_pricing_rules(apply_on, args, values):
)
if apply_on_field == "item_code":
if args.get("uom", None):
item_conditions += (
" and ({child_doc}.uom='{item_uom}' or IFNULL({child_doc}.uom, '')='')".format(
child_doc=child_doc, item_uom=args.get("uom")
)
)
if "variant_of" not in args:
args.variant_of = frappe.get_cached_value("Item", args.item_code, "variant_of")

View File

@@ -34,4 +34,4 @@ class ProcessDeferredAccounting(Document):
filters={"against_voucher_type": self.doctype, "against_voucher": self.name},
)
make_gl_entries(gl_entries=gl_entries, cancel=1)
make_gl_entries(gl_map=gl_entries, cancel=1)

View File

@@ -57,3 +57,16 @@ class TestProcessDeferredAccounting(unittest.TestCase):
]
check_gl_entries(self, si.name, expected_gle, "2019-01-10")
def test_pda_submission_and_cancellation(self):
pda = frappe.get_doc(
dict(
doctype="Process Deferred Accounting",
posting_date="2019-01-01",
start_date="2019-01-01",
end_date="2019-01-31",
type="Income",
)
)
pda.submit()
pda.cancel()

View File

@@ -25,7 +25,7 @@
</div>
<br>
<table class="table table-bordered">
<table class="table table-bordered" style="font-size: 10px">
<thead>
<tr>
<th style="width: 12%">{{ _("Date") }}</th>

View File

@@ -31,7 +31,7 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
this._super();
// Ignore linked advances
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry', 'Purchase Invoice'];
if(!this.frm.doc.__islocal) {
// show credit_to in print format
@@ -539,7 +539,7 @@ frappe.ui.form.on("Purchase Invoice", {
},
add_custom_buttons: function(frm) {
if (frm.doc.per_received < 100) {
if (frm.doc.docstatus == 1 && frm.doc.per_received < 100) {
frm.add_custom_button(__('Purchase Receipt'), () => {
frm.events.make_purchase_receipt(frm);
}, __('Create'));

View File

@@ -83,6 +83,8 @@
"section_break_51",
"taxes_and_charges",
"taxes",
"tax_withheld_vouchers_section",
"tax_withheld_vouchers",
"sec_tax_breakup",
"other_charges_calculation",
"totals",
@@ -511,7 +513,6 @@
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"label": "Ignore Pricing Rule",
"no_copy": 1,
"permlevel": 1,
"print_hide": 1
},
@@ -1417,13 +1418,26 @@
"label": "Advance Tax",
"options": "Advance Tax",
"read_only": 1
},
{
"fieldname": "tax_withheld_vouchers_section",
"fieldtype": "Section Break",
"label": "Tax Withheld Vouchers"
},
{
"fieldname": "tax_withheld_vouchers",
"fieldtype": "Table",
"label": "Tax Withheld Vouchers",
"no_copy": 1,
"options": "Tax Withheld Vouchers",
"read_only": 1
}
],
"icon": "fa fa-file-text",
"idx": 204,
"is_submittable": 1,
"links": [],
"modified": "2021-11-25 13:31:02.716727",
"modified": "2022-10-07 14:19:14.214157",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice",
@@ -1483,7 +1497,8 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"timeline_field": "supplier",
"title_field": "title",
"track_changes": 1
}
}

View File

@@ -158,6 +158,7 @@ class PurchaseInvoice(BuyingController):
if tds_category and not for_validate:
self.apply_tds = 1
self.tax_withholding_category = tds_category
self.set_onload("supplier_tds", tds_category)
super(PurchaseInvoice, self).set_missing_values(for_validate)
@@ -566,7 +567,6 @@ class PurchaseInvoice(BuyingController):
self.make_supplier_gl_entry(gl_entries)
self.make_item_gl_entries(gl_entries)
self.make_discount_gl_entries(gl_entries)
if self.check_asset_cwip_enabled():
self.get_asset_gl_entry(gl_entries)
@@ -695,6 +695,10 @@ class PurchaseInvoice(BuyingController):
)
)
credit_amount = item.base_net_amount
if self.is_internal_supplier and item.valuation_rate:
credit_amount = flt(item.valuation_rate * item.stock_qty)
# Intentionally passed negative debit amount to avoid incorrect GL Entry validation
gl_entries.append(
self.get_gl_dict(
@@ -704,7 +708,7 @@ class PurchaseInvoice(BuyingController):
"cost_center": item.cost_center,
"project": item.project or self.project,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"debit": -1 * flt(item.base_net_amount, item.precision("base_net_amount")),
"debit": -1 * flt(credit_amount, item.precision("base_net_amount")),
},
warehouse_account[item.from_warehouse]["account_currency"],
item=item,
@@ -793,7 +797,7 @@ class PurchaseInvoice(BuyingController):
)
if not item.is_fixed_asset:
dummy, amount = self.get_amount_and_base_amount(item, self.enable_discount_accounting)
dummy, amount = self.get_amount_and_base_amount(item, None)
else:
amount = flt(item.base_net_amount + item.item_tax_amount, item.precision("base_net_amount"))
@@ -1109,7 +1113,7 @@ class PurchaseInvoice(BuyingController):
valuation_tax = {}
for tax in self.get("taxes"):
amount, base_amount = self.get_tax_amounts(tax, self.enable_discount_accounting)
amount, base_amount = self.get_tax_amounts(tax, None)
if tax.category in ("Total", "Valuation and Total") and flt(base_amount):
account_currency = get_account_currency(tax.account_head)
@@ -1364,7 +1368,14 @@ class PurchaseInvoice(BuyingController):
frappe.db.set(self, "status", "Cancelled")
unlink_inter_company_doc(self.doctype, self.name, self.inter_company_invoice_reference)
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry", "Repost Item Valuation")
self.ignore_linked_doctypes = (
"GL Entry",
"Stock Ledger Entry",
"Repost Item Valuation",
"Purchase Invoice",
)
self.update_advance_tax_references(cancel=1)
def update_project(self):
@@ -1457,7 +1468,7 @@ class PurchaseInvoice(BuyingController):
if not self.tax_withholding_category:
return
tax_withholding_details, advance_taxes = get_party_tax_withholding_details(
tax_withholding_details, advance_taxes, voucher_wise_amount = get_party_tax_withholding_details(
self, self.tax_withholding_category
)
@@ -1486,6 +1497,19 @@ class PurchaseInvoice(BuyingController):
for d in to_remove:
self.remove(d)
## Add pending vouchers on which tax was withheld
self.set("tax_withheld_vouchers", [])
for voucher_no, voucher_details in voucher_wise_amount.items():
self.append(
"tax_withheld_vouchers",
{
"voucher_name": voucher_no,
"voucher_type": voucher_details.get("voucher_type"),
"taxable_amount": voucher_details.get("amount"),
},
)
# calculate totals again after applying TDS
self.calculate_taxes_and_totals()
@@ -1688,4 +1712,6 @@ def make_purchase_receipt(source_name, target_doc=None):
target_doc,
)
doc.set_onload("ignore_price_list", True)
return doc

View File

@@ -304,59 +304,6 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
self.assertEqual(expected_values[gle.account][1], gle.debit)
self.assertEqual(expected_values[gle.account][2], gle.credit)
def test_purchase_invoice_with_discount_accounting_enabled(self):
enable_discount_accounting()
discount_account = create_account(
account_name="Discount Account",
parent_account="Indirect Expenses - _TC",
company="_Test Company",
)
pi = make_purchase_invoice(discount_account=discount_account, rate=45)
expected_gle = [
["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, nowdate()],
["Creditors - _TC", 0.0, 225.0, nowdate()],
["Discount Account - _TC", 0.0, 25.0, nowdate()],
]
check_gl_entries(self, pi.name, expected_gle, nowdate())
enable_discount_accounting(enable=0)
def test_additional_discount_for_purchase_invoice_with_discount_accounting_enabled(self):
enable_discount_accounting()
additional_discount_account = create_account(
account_name="Discount Account",
parent_account="Indirect Expenses - _TC",
company="_Test Company",
)
pi = make_purchase_invoice(do_not_save=1, parent_cost_center="Main - _TC")
pi.apply_discount_on = "Grand Total"
pi.additional_discount_account = additional_discount_account
pi.additional_discount_percentage = 10
pi.disable_rounded_total = 1
pi.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "_Test Account VAT - _TC",
"cost_center": "Main - _TC",
"description": "Test",
"rate": 10,
},
)
pi.submit()
expected_gle = [
["_Test Account Cost for Goods Sold - _TC", 250.0, 0.0, nowdate()],
["_Test Account VAT - _TC", 25.0, 0.0, nowdate()],
["Creditors - _TC", 0.0, 247.5, nowdate()],
["Discount Account - _TC", 0.0, 27.5, nowdate()],
]
check_gl_entries(self, pi.name, expected_gle, nowdate())
def test_purchase_invoice_change_naming_series(self):
pi = frappe.copy_doc(test_records[1])
pi.insert()
@@ -1602,6 +1549,37 @@ class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
pi.save()
self.assertEqual(pi.items[0].conversion_factor, 1000)
def test_batch_expiry_for_purchase_invoice(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
item = self.make_item(
"_Test Batch Item For Return Check",
{
"is_purchase_item": 1,
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TBIRC.#####",
},
)
pi = make_purchase_invoice(
qty=1,
item_code=item.name,
update_stock=True,
)
pi.load_from_db()
batch_no = pi.items[0].batch_no
self.assertTrue(batch_no)
frappe.db.set_value("Batch", batch_no, "expiry_date", add_days(nowdate(), -1))
return_pi = make_return_doc(pi.doctype, pi.name)
return_pi.save().submit()
self.assertTrue(return_pi.docstatus == 1)
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
gl_entries = frappe.db.sql(

View File

@@ -706,6 +706,7 @@
"label": "Valuation Rate",
"no_copy": 1,
"options": "Company:company:default_currency",
"precision": "6",
"print_hide": 1,
"read_only": 1
},
@@ -871,7 +872,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2021-11-15 17:04:07.191013",
"modified": "2022-10-12 03:37:29.032732",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Purchase Invoice Item",

View File

@@ -476,7 +476,19 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
});
this.frm.trigger("calculate_timesheet_totals");
}
},
is_cash_or_non_trade_discount() {
this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount);
this.frm.set_df_property("additional_discount_account", "reqd", this.frm.doc.is_cash_or_non_trade_discount);
if (!this.frm.doc.is_cash_or_non_trade_discount) {
this.frm.set_value("additional_discount_account", "");
}
this.calculate_taxes_and_totals();
}
});
// for backward compatibility: combine new and previous states

View File

@@ -106,6 +106,7 @@
"loyalty_redemption_cost_center",
"section_break_49",
"apply_discount_on",
"is_cash_or_non_trade_discount",
"base_discount_amount",
"additional_discount_account",
"column_break_51",
@@ -413,7 +414,7 @@
},
{
"default": "0",
"depends_on": "eval: doc.is_return && doc.return_against",
"depends_on": "eval: doc.is_return",
"fieldname": "update_billed_amount_in_sales_order",
"fieldtype": "Check",
"hide_days": 1,
@@ -650,7 +651,6 @@
"hide_days": 1,
"hide_seconds": 1,
"label": "Ignore Pricing Rule",
"no_copy": 1,
"print_hide": 1
},
{
@@ -1790,8 +1790,6 @@
"width": "50%"
},
{
"fetch_from": "sales_partner.commission_rate",
"fetch_if_empty": 1,
"fieldname": "commission_rate",
"fieldtype": "Float",
"hide_days": 1,
@@ -1990,7 +1988,7 @@
{
"fieldname": "additional_discount_account",
"fieldtype": "Link",
"label": "Additional Discount Account",
"label": "Discount Account",
"options": "Account"
},
{
@@ -2028,6 +2026,13 @@
"fieldtype": "Currency",
"label": "Amount Eligible for Commission",
"read_only": 1
},
{
"default": "0",
"depends_on": "eval: doc.apply_discount_on == \"Grand Total\"",
"fieldname": "is_cash_or_non_trade_discount",
"fieldtype": "Check",
"label": "Is Cash or Non Trade Discount"
}
],
"icon": "fa fa-file-text",
@@ -2040,7 +2045,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2022-06-10 03:52:51.409913",
"modified": "2022-09-16 17:44:22.227332",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -1040,7 +1040,7 @@ class SalesInvoice(SellingController):
)
if grand_total and not self.is_internal_transfer():
# Didnot use base_grand_total to book rounding loss gle
# Did not use base_grand_total to book rounding loss gle
gl_entries.append(
self.get_gl_dict(
{
@@ -2157,11 +2157,13 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
target_detail_field = "sales_invoice_item" if doctype == "Sales Invoice" else "sales_order_item"
source_document_warehouse_field = "target_warehouse"
target_document_warehouse_field = "from_warehouse"
received_items = get_received_items(source_name, target_doctype, target_detail_field)
else:
source_doc = frappe.get_doc(doctype, source_name)
target_doctype = "Sales Invoice" if doctype == "Purchase Invoice" else "Sales Order"
source_document_warehouse_field = "from_warehouse"
target_document_warehouse_field = "target_warehouse"
received_items = {}
validate_inter_company_transaction(source_doc, doctype)
details = get_inter_company_details(source_doc, doctype)
@@ -2227,12 +2229,17 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
shipping_address_name=target_doc.shipping_address_name,
)
def update_item(source, target, source_parent):
target.qty = flt(source.qty) - received_items.get(source.name, 0.0)
item_field_map = {
"doctype": target_doctype + " Item",
"field_no_map": ["income_account", "expense_account", "cost_center", "warehouse"],
"field_map": {
"rate": "rate",
},
"postprocess": update_item,
"condition": lambda doc: doc.qty > 0,
}
if doctype in ["Sales Invoice", "Sales Order"]:
@@ -2270,6 +2277,28 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
return doclist
def get_received_items(reference_name, doctype, reference_fieldname):
target_doctypes = frappe.get_all(
doctype,
filters={"inter_company_invoice_reference": reference_name, "docstatus": 1},
as_list=True,
)
if target_doctypes:
target_doctypes = list(target_doctypes[0])
received_items_map = frappe._dict(
frappe.get_all(
doctype + " Item",
filters={"parent": ("in", target_doctypes)},
fields=[reference_fieldname, "qty"],
as_list=1,
)
)
return received_items_map
def set_purchase_references(doc):
# add internal PO or PR links if any
if doc.is_internal_transfer():

View File

@@ -11,6 +11,7 @@ def get_data():
"Payment Request": "reference_name",
"Sales Invoice": "return_against",
"Auto Repeat": "reference_document",
"Purchase Invoice": "inter_company_invoice_reference",
},
"internal_links": {
"Sales Order": ["items", "sales_order"],
@@ -30,5 +31,6 @@ def get_data():
{"label": _("Reference"), "items": ["Timesheet", "Delivery Note", "Sales Order"]},
{"label": _("Returns"), "items": ["Sales Invoice"]},
{"label": _("Subscription"), "items": ["Auto Repeat"]},
{"label": _("Internal Transfers"), "items": ["Purchase Invoice"]},
],
}

View File

@@ -7,7 +7,7 @@ import unittest
import frappe
from frappe.model.dynamic_links import get_dynamic_link_map
from frappe.model.naming import make_autoname
from frappe.utils import add_days, flt, getdate, nowdate
from frappe.utils import add_days, flt, getdate, nowdate, today
from six import iteritems
from erpnext.accounts.doctype.account.test_account import create_account, get_inventory_account
@@ -31,10 +31,20 @@ from erpnext.stock.doctype.stock_entry.test_stock_entry import (
get_qty_after_transaction,
make_stock_entry,
)
from erpnext.stock.utils import get_incoming_rate
from erpnext.stock.doctype.stock_reconciliation.test_stock_reconciliation import (
create_stock_reconciliation,
)
from erpnext.stock.utils import get_incoming_rate, get_stock_balance
class TestSalesInvoice(unittest.TestCase):
def setUp(self):
from erpnext.stock.doctype.stock_ledger_entry.test_stock_ledger_entry import create_items
create_items(["_Test Internal Transfer Item"], uoms=[{"uom": "Box", "conversion_factor": 10}])
create_internal_parties()
setup_accounts()
def make(self):
w = frappe.copy_doc(test_records[0])
w.is_pos = 0
@@ -1687,7 +1697,7 @@ class TestSalesInvoice(unittest.TestCase):
si.save()
self.assertEqual(si.get("items")[0].rate, flt((price_list_rate * 25) / 100 + price_list_rate))
def test_outstanding_amount_after_advance_jv_cancelation(self):
def test_outstanding_amount_after_advance_jv_cancellation(self):
from erpnext.accounts.doctype.journal_entry.test_journal_entry import (
test_records as jv_test_records,
)
@@ -1731,7 +1741,7 @@ class TestSalesInvoice(unittest.TestCase):
flt(si.rounded_total + si.total_advance, si.precision("outstanding_amount")),
)
def test_outstanding_amount_after_advance_payment_entry_cancelation(self):
def test_outstanding_amount_after_advance_payment_entry_cancellation(self):
pe = frappe.get_doc(
{
"doctype": "Payment Entry",
@@ -2369,29 +2379,6 @@ class TestSalesInvoice(unittest.TestCase):
acc_settings.save()
def test_inter_company_transaction(self):
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
create_internal_customer(
customer_name="_Test Internal Customer",
represents_company="_Test Company 1",
allowed_to_interact_with="Wind Power LLC",
)
if not frappe.db.exists("Supplier", "_Test Internal Supplier"):
supplier = frappe.get_doc(
{
"supplier_group": "_Test Supplier Group",
"supplier_name": "_Test Internal Supplier",
"doctype": "Supplier",
"is_internal_supplier": 1,
"represents_company": "Wind Power LLC",
}
)
supplier.append("companies", {"company": "_Test Company 1"})
supplier.insert()
si = create_sales_invoice(
company="Wind Power LLC",
customer="_Test Internal Customer",
@@ -2451,34 +2438,9 @@ class TestSalesInvoice(unittest.TestCase):
se.cancel()
def test_internal_transfer_gl_entry(self):
## Create internal transfer account
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
account = create_account(
account_name="Unrealized Profit",
parent_account="Current Liabilities - TCP1",
company="_Test Company with perpetual inventory",
)
frappe.db.set_value(
"Company", "_Test Company with perpetual inventory", "unrealized_profit_loss_account", account
)
customer = create_internal_customer(
"_Test Internal Customer 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)
create_internal_supplier(
"_Test Internal Supplier 2",
"_Test Company with perpetual inventory",
"_Test Company with perpetual inventory",
)
si = create_sales_invoice(
company="_Test Company with perpetual inventory",
customer=customer,
customer="_Test Internal Customer 2",
debit_to="Debtors - TCP1",
warehouse="Stores - TCP1",
income_account="Sales - TCP1",
@@ -2492,7 +2454,7 @@ class TestSalesInvoice(unittest.TestCase):
si.update_stock = 1
si.items[0].target_warehouse = "Work In Progress - TCP1"
# Add stock to stores for succesful stock transfer
# Add stock to stores for successful stock transfer
make_stock_entry(
target="Stores - TCP1", company="_Test Company with perpetual inventory", qty=1, basic_rate=100
)
@@ -2620,6 +2582,287 @@ class TestSalesInvoice(unittest.TestCase):
einvoice = make_einvoice(si)
validate_totals(einvoice)
def test_einvoice_discounts(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
frappe.db.set_single_value("E Invoice Settings", "dont_show_discounts_in_e_invoice", False)
# Normal Itemized Discount
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[0].price_list_rate = 12
si.items[0].discount_percentage = 16.6666666667
si.items[0].rate = 10
si.items[1].price_list_rate = 15
si.items[1].discount_amount = 5
si.items[1].rate = 10
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 4000)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 2100)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 222)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5555)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on net total
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Net Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 253.61)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 66.57)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 243.11)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5613.71)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on grand total (Itemized Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 214.93)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 56.42)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 239.89)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5604.75)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on grand total (Cash/Non-Trade Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 222.0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5555.0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 400)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[1].price_list_rate = 15
si.items[1].discount_amount = -5
si.items[1].rate = 20
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 20)
def test_einvoice_without_discounts(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
frappe.db.set_single_value("E Invoice Settings", "dont_show_discounts_in_e_invoice", True)
# Normal Itemized Discount
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[0].price_list_rate = 12
si.items[0].discount_percentage = 16.6666666667
si.items[0].rate = 10
si.items[1].price_list_rate = 15
si.items[1].discount_amount = 5
si.items[1].rate = 10
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 10)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 10)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 18)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 5)
# Invoice Discount on net total
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Net Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 11.87)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 14.84)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 17.81)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 4.95)
# Invoice Discount on grand total (Itemized Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 11.89)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 14.87)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 17.84)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 4.96)
# Invoice Discount on grand total (Cash/Non-Trade Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 400)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 18)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 5)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[1].price_list_rate = 15
si.items[1].discount_amount = -5
si.items[1].rate = 20
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 20)
def test_internal_transfer_gl_precision_issues(self):
# Make a stock queue of an item with two valuations
# Remove all existing stock for this
if get_stock_balance("_Test Internal Transfer Item", "Stores - TCP1", "2022-04-10"):
create_stock_reconciliation(
item_code="_Test Internal Transfer Item",
warehouse="Stores - TCP1",
qty=0,
rate=0,
company="_Test Company with perpetual inventory",
expense_account="Stock Adjustment - TCP1"
if frappe.get_all("Stock Ledger Entry")
else "Temporary Opening - TCP1",
posting_date="2020-04-10",
posting_time="14:00",
)
make_stock_entry(
item_code="_Test Internal Transfer Item",
target="Stores - TCP1",
qty=9000000,
basic_rate=52.0,
posting_date="2020-04-10",
posting_time="14:00",
)
make_stock_entry(
item_code="_Test Internal Transfer Item",
target="Stores - TCP1",
qty=60000000,
basic_rate=52.349777,
posting_date="2020-04-10",
posting_time="14:00",
)
# Make an internal transfer Sales Invoice Stock in non stock uom to check
# for rounding errors while converting to stock uom
si = create_sales_invoice(
company="_Test Company with perpetual inventory",
customer="_Test Internal Customer 2",
item_code="_Test Internal Transfer Item",
qty=5000000,
uom="Box",
debit_to="Debtors - TCP1",
warehouse="Stores - TCP1",
income_account="Sales - TCP1",
expense_account="Cost of Goods Sold - TCP1",
cost_center="Main - TCP1",
currency="INR",
do_not_save=1,
)
# Check GL Entries with precision
si.update_stock = 1
si.items[0].target_warehouse = "Work In Progress - TCP1"
si.items[0].conversion_factor = 10
si.save()
si.submit()
# Check if adjustment entry is created
self.assertTrue(
frappe.db.exists(
"GL Entry",
{
"voucher_type": "Sales Invoice",
"voucher_no": si.name,
"remarks": "Rounding gain/loss Entry for Stock Transfer",
},
)
)
def test_item_tax_net_range(self):
item = create_item("T Shirt")
@@ -3068,7 +3311,7 @@ class TestSalesInvoice(unittest.TestCase):
[deferred_account, 2022.47, 0.0, "2019-03-15"],
]
gl_entries = gl_entries = frappe.db.sql(
gl_entries = frappe.db.sql(
"""select account, debit, credit, posting_date
from `tabGL Entry`
where voucher_type='Journal Entry' and voucher_detail_no=%s and posting_date <= %s
@@ -3186,6 +3429,37 @@ class TestSalesInvoice(unittest.TestCase):
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
)
def test_batch_expiry_for_sales_invoice_return(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.item.test_item import make_item
item = make_item(
"_Test Batch Item For Return Check",
{
"is_purchase_item": 1,
"is_stock_item": 1,
"has_batch_no": 1,
"create_new_batch": 1,
"batch_number_series": "TBIRC.#####",
},
)
pr = make_purchase_receipt(qty=1, item_code=item.name)
batch_no = pr.items[0].batch_no
si = create_sales_invoice(qty=1, item_code=item.name, update_stock=1, batch_no=batch_no)
si.load_from_db()
batch_no = si.items[0].batch_no
self.assertTrue(batch_no)
frappe.db.set_value("Batch", batch_no, "expiry_date", add_days(today(), -1))
return_si = make_return_doc(si.doctype, si.name)
return_si.save().submit()
self.assertTrue(return_si.docstatus == 1)
def get_sales_invoice_for_e_invoice():
si = make_sales_invoice_for_ewaybill()
@@ -3219,6 +3493,36 @@ def get_sales_invoice_for_e_invoice():
},
)
si.append(
"items",
{
"item_code": "_Test Item",
"uom": "Nos",
"warehouse": "_Test Warehouse - _TC",
"qty": 111,
"price_list_rate": 20,
"discount_percentage": 10,
"income_account": "Sales - _TC",
"expense_account": "Cost of Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
},
)
si.append(
"items",
{
"item_code": "_Test Item 2",
"uom": "Nos",
"warehouse": "_Test Warehouse - _TC",
"qty": 1111,
"price_list_rate": 10,
"rate": 5,
"income_account": "Sales - _TC",
"expense_account": "Cost of Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
},
)
return si
@@ -3412,6 +3716,7 @@ def create_sales_invoice(**args):
"description": args.description or "_Test Item",
"gst_hsn_code": "999800",
"warehouse": args.warehouse or "_Test Warehouse - _TC",
"target_warehouse": args.target_warehouse,
"qty": args.qty or 1,
"uom": args.uom or "Nos",
"stock_uom": args.uom or "Nos",
@@ -3424,8 +3729,9 @@ def create_sales_invoice(**args):
"discount_amount": args.discount_amount or 0,
"cost_center": args.cost_center or "_Test Cost Center - _TC",
"serial_no": args.serial_no,
"conversion_factor": 1,
"conversion_factor": args.get("conversion_factor", 1),
"incoming_rate": args.incoming_rate or 0,
"batch_no": args.batch_no or None,
},
)
@@ -3537,6 +3843,34 @@ def get_taxes_and_charges():
]
def create_internal_parties():
from erpnext.selling.doctype.customer.test_customer import create_internal_customer
create_internal_customer(
customer_name="_Test Internal Customer",
represents_company="_Test Company 1",
allowed_to_interact_with="Wind Power LLC",
)
create_internal_customer(
customer_name="_Test Internal Customer 2",
represents_company="_Test Company with perpetual inventory",
allowed_to_interact_with="_Test Company with perpetual inventory",
)
create_internal_supplier(
supplier_name="_Test Internal Supplier",
represents_company="Wind Power LLC",
allowed_to_interact_with="_Test Company 1",
)
create_internal_supplier(
supplier_name="_Test Internal Supplier 2",
represents_company="_Test Company with perpetual inventory",
allowed_to_interact_with="_Test Company with perpetual inventory",
)
def create_internal_supplier(supplier_name, represents_company, allowed_to_interact_with):
if not frappe.db.exists("Supplier", supplier_name):
supplier = frappe.get_doc(
@@ -3559,6 +3893,19 @@ def create_internal_supplier(supplier_name, represents_company, allowed_to_inter
return supplier_name
def setup_accounts():
## Create internal transfer account
account = create_account(
account_name="Unrealized Profit",
parent_account="Current Liabilities - TCP1",
company="_Test Company with perpetual inventory",
)
frappe.db.set_value(
"Company", "_Test Company with perpetual inventory", "unrealized_profit_loss_account", account
)
def add_taxes(doc):
doc.append(
"taxes",

View File

@@ -279,7 +279,6 @@
"label": "Discount (%) on Price List Rate with Margin",
"oldfieldname": "adj_rate",
"oldfieldtype": "Float",
"precision": "2",
"print_hide": 1
},
{
@@ -813,6 +812,8 @@
"fieldtype": "Currency",
"label": "Incoming Rate (Costing)",
"no_copy": 1,
"options": "Company:company:default_currency",
"precision": "6",
"print_hide": 1
},
{
@@ -842,7 +843,7 @@
"idx": 1,
"istable": 1,
"links": [],
"modified": "2022-02-24 14:41:36.392560",
"modified": "2022-10-10 20:57:38.340026",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice Item",

View File

@@ -0,0 +1,49 @@
{
"actions": [],
"autoname": "autoincrement",
"creation": "2022-09-13 16:18:59.404842",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
"field_order": [
"voucher_type",
"voucher_name",
"taxable_amount"
],
"fields": [
{
"fieldname": "voucher_type",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Voucher Type",
"options": "DocType"
},
{
"fieldname": "voucher_name",
"fieldtype": "Dynamic Link",
"in_list_view": 1,
"label": "Voucher Name",
"options": "voucher_type"
},
{
"fieldname": "taxable_amount",
"fieldtype": "Currency",
"in_list_view": 1,
"label": "Taxable Amount",
"options": "Company:company:default_currency"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2022-09-13 23:40:41.479208",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Tax Withheld Vouchers",
"naming_rule": "Autoincrement",
"owner": "Administrator",
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

View File

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

View File

@@ -100,7 +100,7 @@ def get_party_tax_withholding_details(inv, tax_withholding_category=None):
).format(tax_withholding_category, inv.company, party)
)
tax_amount, tax_deducted, tax_deducted_on_advances = get_tax_amount(
tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount = get_tax_amount(
party_type, parties, inv, tax_details, posting_date, pan_no
)
@@ -110,7 +110,7 @@ def get_party_tax_withholding_details(inv, tax_withholding_category=None):
tax_row = get_tax_row_for_tcs(inv, tax_details, tax_amount, tax_deducted)
if inv.doctype == "Purchase Invoice":
return tax_row, tax_deducted_on_advances
return tax_row, tax_deducted_on_advances, voucher_wise_amount
else:
return tax_row
@@ -208,7 +208,9 @@ def get_lower_deduction_certificate(tax_details, pan_no):
def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=None):
vouchers = get_invoice_vouchers(parties, tax_details, inv.company, party_type=party_type)
vouchers, voucher_wise_amount = get_invoice_vouchers(
parties, tax_details, inv.company, party_type=party_type
)
advance_vouchers = get_advance_vouchers(
parties,
company=inv.company,
@@ -227,6 +229,7 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
tax_deducted = get_deducted_tax(taxable_vouchers, tax_details)
tax_amount = 0
if party_type == "Supplier":
ldc = get_lower_deduction_certificate(tax_details, pan_no)
if tax_deducted:
@@ -237,6 +240,9 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
)
else:
tax_amount = net_total * tax_details.rate / 100 if net_total > 0 else 0
# once tds is deducted, not need to add vouchers in the invoice
voucher_wise_amount = {}
else:
tax_amount = get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers)
@@ -252,12 +258,13 @@ def get_tax_amount(party_type, parties, inv, tax_details, posting_date, pan_no=N
if cint(tax_details.round_off_tax_amount):
tax_amount = round(tax_amount)
return tax_amount, tax_deducted, tax_deducted_on_advances
return tax_amount, tax_deducted, tax_deducted_on_advances, voucher_wise_amount
def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"):
dr_or_cr = "credit" if party_type == "Supplier" else "debit"
doctype = "Purchase Invoice" if party_type == "Supplier" else "Sales Invoice"
voucher_wise_amount = {}
vouchers = []
filters = {
"company": company,
@@ -272,29 +279,40 @@ def get_invoice_vouchers(parties, tax_details, company, party_type="Supplier"):
{"apply_tds": 1, "tax_withholding_category": tax_details.get("tax_withholding_category")}
)
invoices = frappe.get_all(doctype, filters=filters, pluck="name") or [""]
invoices_details = frappe.get_all(doctype, filters=filters, fields=["name", "base_net_total"])
journal_entries = frappe.db.sql(
for d in invoices_details:
vouchers.append(d.name)
voucher_wise_amount.update({d.name: {"amount": d.base_net_total, "voucher_type": doctype}})
journal_entries_details = frappe.db.sql(
"""
SELECT j.name
SELECT j.name, ja.credit - ja.debit AS amount
FROM `tabJournal Entry` j, `tabJournal Entry Account` ja
WHERE
j.docstatus = 1
j.name = ja.parent
AND j.docstatus = 1
AND j.is_opening = 'No'
AND j.posting_date between %s and %s
AND ja.{dr_or_cr} > 0
AND ja.party in %s
""".format(
dr_or_cr=dr_or_cr
AND j.apply_tds = 1
AND j.tax_withholding_category = %s
""",
(
tax_details.from_date,
tax_details.to_date,
tuple(parties),
tax_details.get("tax_withholding_category"),
),
(tax_details.from_date, tax_details.to_date, tuple(parties)),
as_list=1,
as_dict=1,
)
if journal_entries:
journal_entries = journal_entries[0]
if journal_entries_details:
for d in journal_entries_details:
vouchers.append(d.name)
voucher_wise_amount.update({d.name: {"amount": d.amount, "voucher_type": "Journal Entry"}})
return invoices + journal_entries
return vouchers, voucher_wise_amount
def get_advance_vouchers(
@@ -309,9 +327,11 @@ def get_advance_vouchers(
"is_cancelled": 0,
"party_type": party_type,
"party": ["in", parties],
"against_voucher": ["is", "not set"],
}
if party_type == "Customer":
filters.update({"against_voucher": ["is", "not set"]})
if company:
filters["company"] = company
if from_date and to_date:
@@ -321,23 +341,25 @@ def get_advance_vouchers(
def get_taxes_deducted_on_advances_allocated(inv, tax_details):
advances = [d.reference_name for d in inv.get("advances")]
tax_info = []
if advances:
pe = frappe.qb.DocType("Payment Entry").as_("pe")
at = frappe.qb.DocType("Advance Taxes and Charges").as_("at")
if inv.get("advances"):
advances = [d.reference_name for d in inv.get("advances")]
tax_info = (
frappe.qb.from_(at)
.inner_join(pe)
.on(pe.name == at.parent)
.select(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)
.run(as_dict=True)
)
if advances:
pe = frappe.qb.DocType("Payment Entry").as_("pe")
at = frappe.qb.DocType("Advance Taxes and Charges").as_("at")
tax_info = (
frappe.qb.from_(at)
.inner_join(pe)
.on(pe.name == at.parent)
.select(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)
.run(as_dict=True)
)
return tax_info
@@ -359,6 +381,9 @@ def get_deducted_tax(taxable_vouchers, tax_details):
def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
tds_amount = 0
supp_credit_amt = 0.0
supp_jv_credit_amt = 0.0
invoice_filters = {"name": ("in", vouchers), "docstatus": 1, "apply_tds": 1}
field = "sum(net_total)"
@@ -367,30 +392,25 @@ def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
invoice_filters.pop("apply_tds", None)
field = "sum(grand_total)"
supp_credit_amt = frappe.db.get_value("Purchase Invoice", invoice_filters, field) or 0.0
if vouchers:
supp_credit_amt = frappe.db.get_value("Purchase Invoice", invoice_filters, field) or 0.0
supp_jv_credit_amt = (
frappe.db.get_value(
"Journal Entry Account",
{
"parent": ("in", vouchers),
"docstatus": 1,
"party": ("in", parties),
"reference_type": ("!=", "Purchase Invoice"),
},
"sum(credit_in_account_currency)",
)
or 0.0
)
supp_jv_credit_amt = (
frappe.db.get_value(
"Journal Entry Account",
{
"parent": ("in", vouchers),
"docstatus": 1,
"party": ("in", parties),
"reference_type": ("!=", "Purchase Invoice"),
},
"sum(credit_in_account_currency)",
)
) or 0.0
supp_credit_amt += supp_jv_credit_amt
supp_credit_amt += inv.net_total
debit_note_amount = get_debit_note_amount(
parties, tax_details.from_date, tax_details.to_date, inv.company
)
supp_credit_amt -= debit_note_amount
threshold = tax_details.get("threshold", 0)
cumulative_threshold = tax_details.get("cumulative_threshold", 0)
@@ -402,7 +422,10 @@ def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
):
# Get net total again as TDS is calculated on net total
# Grand is used to just check for threshold breach
net_total = frappe.db.get_value("Purchase Invoice", invoice_filters, "sum(net_total)") or 0.0
net_total = 0
if vouchers:
net_total = frappe.db.get_value("Purchase Invoice", invoice_filters, "sum(net_total)")
net_total += inv.net_total
supp_credit_amt = net_total - cumulative_threshold
@@ -423,36 +446,40 @@ def get_tds_amount(ldc, parties, inv, tax_details, tax_deducted, vouchers):
def get_tcs_amount(parties, inv, tax_details, vouchers, adv_vouchers):
tcs_amount = 0
invoiced_amt = 0
advance_amt = 0
# sum of debit entries made from sales invoices
invoiced_amt = (
frappe.db.get_value(
"GL Entry",
{
"is_cancelled": 0,
"party": ["in", parties],
"company": inv.company,
"voucher_no": ["in", vouchers],
},
"sum(debit)",
if vouchers:
invoiced_amt = (
frappe.db.get_value(
"GL Entry",
{
"is_cancelled": 0,
"party": ["in", parties],
"company": inv.company,
"voucher_no": ["in", vouchers],
},
"sum(debit)",
)
or 0.0
)
or 0.0
)
# sum of credit entries made from PE / JV with unset 'against voucher'
advance_amt = (
frappe.db.get_value(
"GL Entry",
{
"is_cancelled": 0,
"party": ["in", parties],
"company": inv.company,
"voucher_no": ["in", adv_vouchers],
},
"sum(credit)",
if advance_amt:
advance_amt = (
frappe.db.get_value(
"GL Entry",
{
"is_cancelled": 0,
"party": ["in", parties],
"company": inv.company,
"voucher_no": ["in", adv_vouchers],
},
"sum(credit)",
)
or 0.0
)
or 0.0
)
# sum of credit entries made from sales invoice
credit_note_amt = sum(
@@ -507,22 +534,6 @@ def get_tds_amount_from_ldc(ldc, parties, pan_no, tax_details, posting_date, net
return tds_amount
def get_debit_note_amount(suppliers, from_date, to_date, company=None):
filters = {
"supplier": ["in", suppliers],
"is_return": 1,
"docstatus": 1,
"posting_date": ["between", (from_date, to_date)],
}
fields = ["abs(sum(net_total)) as net_total"]
if company:
filters["company"] = company
return frappe.get_all("Purchase Invoice", filters, fields)[0].get("net_total") or 0.0
def get_ltds_amount(current_amount, deducted_amount, certificate_limit, rate, tax_details):
if current_amount < (certificate_limit - deducted_amount):
return current_amount * rate / 100

View File

@@ -52,7 +52,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
invoices.append(pi)
# delete invoices to avoid clashing
for d in invoices:
for d in reversed(invoices):
d.cancel()
def test_single_threshold_tds(self):
@@ -88,7 +88,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
self.assertEqual(pi.taxes_and_charges_deducted, 1000)
# delete invoices to avoid clashing
for d in invoices:
for d in reversed(invoices):
d.cancel()
def test_tax_withholding_category_checks(self):
@@ -114,7 +114,7 @@ class TestTaxWithholdingCategory(unittest.TestCase):
# TDS should be applied only on 1000
self.assertEqual(pi1.taxes[0].tax_amount, 1000)
for d in invoices:
for d in reversed(invoices):
d.cancel()
def test_cumulative_threshold_tcs(self):
@@ -148,8 +148,8 @@ class TestTaxWithholdingCategory(unittest.TestCase):
self.assertEqual(tcs_charged, 500)
invoices.append(si)
# delete invoices to avoid clashing
for d in invoices:
# cancel invoices to avoid clashing
for d in reversed(invoices):
d.cancel()
def test_tds_calculation_on_net_total(self):
@@ -182,8 +182,8 @@ class TestTaxWithholdingCategory(unittest.TestCase):
self.assertEqual(pi1.taxes[0].tax_amount, 4000)
# delete invoices to avoid clashing
for d in invoices:
# cancel invoices to avoid clashing
for d in reversed(invoices):
d.cancel()
def test_multi_category_single_supplier(self):
@@ -207,8 +207,50 @@ class TestTaxWithholdingCategory(unittest.TestCase):
self.assertEqual(pi1.taxes[0].tax_amount, 250)
# delete invoices to avoid clashing
for d in invoices:
# cancel invoices to avoid clashing
for d in reversed(invoices):
d.cancel()
def test_tax_withholding_category_voucher_display(self):
frappe.db.set_value(
"Supplier", "Test TDS Supplier6", "tax_withholding_category", "Test Multi Invoice Category"
)
invoices = []
pi = create_purchase_invoice(supplier="Test TDS Supplier6", rate=4000, do_not_save=True)
pi.apply_tds = 1
pi.tax_withholding_category = "Test Multi Invoice Category"
pi.save()
pi.submit()
invoices.append(pi)
pi1 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=2000, do_not_save=True)
pi1.apply_tds = 1
pi1.is_return = 1
pi1.items[0].qty = -1
pi1.tax_withholding_category = "Test Multi Invoice Category"
pi1.save()
pi1.submit()
invoices.append(pi1)
pi2 = create_purchase_invoice(supplier="Test TDS Supplier6", rate=9000, do_not_save=True)
pi2.apply_tds = 1
pi2.tax_withholding_category = "Test Multi Invoice Category"
pi2.save()
pi2.submit()
invoices.append(pi2)
pi2.load_from_db()
self.assertTrue(pi2.taxes[0].tax_amount, 1100)
self.assertTrue(pi2.tax_withheld_vouchers[0].voucher_name == pi1.name)
self.assertTrue(pi2.tax_withheld_vouchers[0].taxable_amount == pi1.net_total)
self.assertTrue(pi2.tax_withheld_vouchers[1].voucher_name == pi.name)
self.assertTrue(pi2.tax_withheld_vouchers[1].taxable_amount == pi.net_total)
# cancel invoices to avoid clashing
for d in reversed(invoices):
d.cancel()
@@ -308,6 +350,7 @@ def create_records():
"Test TDS Supplier3",
"Test TDS Supplier4",
"Test TDS Supplier5",
"Test TDS Supplier6",
]:
if frappe.db.exists("Supplier", name):
continue
@@ -498,3 +541,22 @@ def create_tax_with_holding_category():
"accounts": [{"company": "_Test Company", "account": "TDS - _TC"}],
}
).insert()
if not frappe.db.exists("Tax Withholding Category", "Test Multi Invoice Category"):
frappe.get_doc(
{
"doctype": "Tax Withholding Category",
"name": "Test Multi Invoice Category",
"category_name": "Test Multi Invoice Category",
"rates": [
{
"from_date": fiscal_year[1],
"to_date": fiscal_year[2],
"tax_withholding_rate": 10,
"single_threshold": 5000,
"cumulative_threshold": 10000,
}
],
"accounts": [{"company": "_Test Company", "account": "TDS - _TC"}],
}
).insert()

View File

@@ -148,6 +148,7 @@ def update_net_values(entry):
def merge_similar_entries(gl_map, precision=None):
merged_gl_map = []
accounting_dimensions = get_accounting_dimensions()
for entry in gl_map:
# if there is already an entry in this account then just add it
# to that entry
@@ -229,9 +230,10 @@ def make_entry(args, adv_adj, update_outstanding, from_repost=False):
gle.flags.from_repost = from_repost
gle.flags.adv_adj = adv_adj
gle.flags.update_outstanding = update_outstanding or "Yes"
gle.flags.notify_update = False
gle.submit()
if not from_repost:
if not from_repost and gle.voucher_type != "Period Closing Voucher":
validate_expense_against_budget(args)

View File

@@ -208,7 +208,7 @@ def set_address_details(
)
if company_address:
party_details.update({"company_address": company_address})
party_details.company_address = company_address
else:
party_details.update(get_company_address(company))
@@ -220,12 +220,37 @@ def set_address_details(
get_regional_address_details(party_details, doctype, company)
elif doctype and doctype in ["Purchase Invoice", "Purchase Order", "Purchase Receipt"]:
if party_details.company_address:
party_details["shipping_address"] = shipping_address or party_details["company_address"]
party_details.shipping_address_display = get_address_display(party_details["shipping_address"])
if shipping_address:
party_details.update(
get_fetch_values(doctype, "shipping_address", party_details.shipping_address)
{
"shipping_address": shipping_address,
"shipping_address_display": get_address_display(shipping_address),
**get_fetch_values(doctype, "shipping_address", shipping_address),
}
)
if party_details.company_address:
# billing address
party_details.update(
{
"billing_address": party_details.company_address,
"billing_address_display": (
party_details.company_address_display or get_address_display(party_details.company_address)
),
**get_fetch_values(doctype, "billing_address", party_details.company_address),
}
)
# shipping address - if not already set
if not party_details.shipping_address:
party_details.update(
{
"shipping_address": party_details.billing_address,
"shipping_address_display": party_details.billing_address_display,
**get_fetch_values(doctype, "shipping_address", party_details.billing_address),
}
)
get_regional_address_details(party_details, doctype, company)
return party_details.get(billing_address_field), party_details.shipping_address_name

View File

@@ -535,7 +535,11 @@ def get_accounts(root_type, companies):
):
if account.account_name not in added_accounts:
accounts.append(account)
added_accounts.append(account.account_name)
if account.account_number:
account_key = account.account_number + "-" + account.account_name
else:
account_key = account.account_name
added_accounts.append(account_key)
return accounts

View File

@@ -280,9 +280,9 @@ def get_conditions(filters):
or filters.get("party")
or filters.get("group_by") in ["Group by Account", "Group by Party"]
):
conditions.append("posting_date >=%(from_date)s")
conditions.append("(posting_date >=%(from_date)s or is_opening = 'Yes')")
conditions.append("(posting_date <=%(to_date)s or is_opening = 'Yes')")
conditions.append("(posting_date <=%(to_date)s)")
if filters.get("project"):
conditions.append("project in %(project)s")

View File

@@ -155,7 +155,6 @@ def adjust_account(data, period_list, consolidated=False):
for d in data:
for period in period_list:
key = period if consolidated else period.key
d[key] = totals[d["account"]]
d["total"] = totals[d["account"]]
return data

View File

@@ -44,14 +44,14 @@ frappe.query_reports["Gross Profit"] = {
"parent_field": "parent_invoice",
"initial_depth": 3,
"formatter": function(value, row, column, data, default_formatter) {
if (column.fieldname == "sales_invoice" && column.options == "Item" && data.indent == 0) {
if (column.fieldname == "sales_invoice" && column.options == "Item" && data && data.indent == 0) {
column._options = "Sales Invoice";
} else {
column._options = "Item";
}
value = default_formatter(value, row, column, data);
if (data && (data.indent == 0.0 || row[1].content == "Total")) {
if (data && (data.indent == 0.0 || (row[1] && row[1].content == "Total"))) {
value = $(`<span>${value}</span>`);
var $value = $(value).css("font-weight", "bold");
value = $value.wrap("<p></p>").parent().html();

View File

@@ -561,7 +561,7 @@ class GrossProfitGenerator(object):
previous_stock_value = len(my_sle) > i + 1 and flt(my_sle[i + 1].stock_value) or 0.0
if previous_stock_value:
return (previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
return abs(previous_stock_value - flt(sle.stock_value)) * flt(row.qty) / abs(flt(sle.qty))
else:
return flt(row.qty) * self.get_average_buying_rate(row, item_code)
else:

View File

@@ -19,14 +19,19 @@ def execute(filters=None):
return _execute(filters)
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
def _execute(
filters=None,
additional_table_columns=None,
additional_query_columns=None,
additional_conditions=None,
):
if not filters:
filters = {}
columns = get_columns(additional_table_columns, filters)
company_currency = frappe.get_cached_value("Company", filters.get("company"), "default_currency")
item_list = get_items(filters, additional_query_columns)
item_list = get_items(filters, additional_query_columns, additional_conditions)
if item_list:
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
@@ -97,6 +102,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
row.update({"rate": d.base_net_rate, "amount": d.base_net_amount})
total_tax = 0
total_other_charges = 0
for tax in tax_columns:
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
row.update(
@@ -105,10 +111,18 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
frappe.scrub(tax + " Amount"): item_tax.get("tax_amount", 0),
}
)
total_tax += flt(item_tax.get("tax_amount"))
if item_tax.get("is_other_charges"):
total_other_charges += flt(item_tax.get("tax_amount"))
else:
total_tax += flt(item_tax.get("tax_amount"))
row.update(
{"total_tax": total_tax, "total": d.base_net_amount + total_tax, "currency": company_currency}
{
"total_tax": total_tax,
"total_other_charges": total_other_charges,
"total": d.base_net_amount + total_tax,
"currency": company_currency,
}
)
if filters.get("group_by"):
@@ -319,7 +333,7 @@ def get_columns(additional_table_columns, filters):
return columns
def get_conditions(filters):
def get_conditions(filters, additional_conditions=None):
conditions = ""
for opts in (
@@ -332,6 +346,9 @@ def get_conditions(filters):
if filters.get(opts[0]):
conditions += opts[1]
if additional_conditions:
conditions += additional_conditions
if filters.get("mode_of_payment"):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=`tabSales Invoice`.name
@@ -367,8 +384,8 @@ def get_group_by_conditions(filters, doctype):
return "ORDER BY `tab{0}`.{1}".format(doctype, frappe.scrub(filters.get("group_by")))
def get_items(filters, additional_query_columns):
conditions = get_conditions(filters)
def get_items(filters, additional_query_columns, additional_conditions=None):
conditions = get_conditions(filters, additional_conditions)
if additional_query_columns:
additional_query_columns = ", " + ", ".join(additional_query_columns)
@@ -477,7 +494,7 @@ def get_tax_accounts(
tax_details = frappe.db.sql(
"""
select
name, parent, description, item_wise_tax_detail,
name, parent, description, item_wise_tax_detail, account_head,
charge_type, {add_deduct_tax}, base_tax_amount_after_discount_amount
from `tab%s`
where
@@ -493,11 +510,22 @@ def get_tax_accounts(
tuple([doctype] + list(invoice_item_row)),
)
account_doctype = frappe.qb.DocType("Account")
query = (
frappe.qb.from_(account_doctype)
.select(account_doctype.name)
.where((account_doctype.account_type == "Tax"))
)
tax_accounts = query.run()
for (
name,
parent,
description,
item_wise_tax_detail,
account_head,
charge_type,
add_deduct_tax,
tax_amount,
@@ -540,7 +568,11 @@ def get_tax_accounts(
)
itemised_tax.setdefault(d.name, {})[description] = frappe._dict(
{"tax_rate": tax_rate, "tax_amount": tax_value}
{
"tax_rate": tax_rate,
"tax_amount": tax_value,
"is_other_charges": 0 if tuple([account_head]) in tax_accounts else 1,
}
)
except ValueError:
@@ -583,6 +615,13 @@ def get_tax_accounts(
"options": "currency",
"width": 100,
},
{
"label": _("Total Other Charges"),
"fieldname": "total_other_charges",
"fieldtype": "Currency",
"options": "currency",
"width": 100,
},
{
"label": _("Total"),
"fieldname": "total",

View File

@@ -370,7 +370,7 @@ def get_conditions(filters):
where parent=`tabSales Invoice`.name
and ifnull(`tab{table}`.{field}, '') = %({field})s)"""
conditions += get_sales_invoice_item_field_condition("mode_of_payments", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("mode_of_payment", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("cost_center")
conditions += get_sales_invoice_item_field_condition("warehouse")
conditions += get_sales_invoice_item_field_condition("brand")

View File

@@ -14,9 +14,9 @@ def execute(filters=None):
filters.naming_series = frappe.db.get_single_value("Buying Settings", "supp_master_name")
columns = get_columns(filters)
tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters)
tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
res = get_result(filters, tds_docs, tds_accounts, tax_category_map)
res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
final_result = group_by_supplier_and_category(res)
return columns, final_result

View File

@@ -8,11 +8,11 @@ from frappe import _
def execute(filters=None):
validate_filters(filters)
tds_docs, tds_accounts, tax_category_map = get_tds_docs(filters)
tds_docs, tds_accounts, tax_category_map, journal_entry_party_map = get_tds_docs(filters)
columns = get_columns(filters)
res = get_result(filters, tds_docs, tds_accounts, tax_category_map)
res = get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map)
return columns, res
@@ -22,7 +22,7 @@ def validate_filters(filters):
frappe.throw(_("From Date must be before To Date"))
def get_result(filters, tds_docs, tds_accounts, tax_category_map):
def get_result(filters, tds_docs, tds_accounts, tax_category_map, journal_entry_party_map):
supplier_map = get_supplier_pan_map()
tax_rate_map = get_tax_rate_map(filters)
gle_map = get_gle_map(tds_docs)
@@ -38,6 +38,11 @@ def get_result(filters, tds_docs, tds_accounts, tax_category_map):
posting_date = entry.posting_date
voucher_type = entry.voucher_type
if voucher_type == "Journal Entry":
suppliers = journal_entry_party_map.get(name)
if suppliers:
supplier = suppliers[0]
if not tax_withholding_category:
tax_withholding_category = supplier_map.get(supplier, {}).get("tax_withholding_category")
rate = tax_rate_map.get(tax_withholding_category)
@@ -176,6 +181,7 @@ def get_tds_docs(filters):
journal_entries = []
tax_category_map = {}
or_filters = {}
journal_entry_party_map = {}
bank_accounts = frappe.get_all("Account", {"is_group": 0, "account_type": "Bank"}, pluck="name")
tds_accounts = frappe.get_all(
@@ -218,9 +224,24 @@ def get_tds_docs(filters):
get_tax_category_map(payment_entries, "Payment Entry", tax_category_map)
if journal_entries:
journal_entry_party_map = get_journal_entry_party_map(journal_entries)
get_tax_category_map(journal_entries, "Journal Entry", tax_category_map)
return tds_documents, tds_accounts, tax_category_map
return tds_documents, tds_accounts, tax_category_map, journal_entry_party_map
def get_journal_entry_party_map(journal_entries):
journal_entry_party_map = {}
for d in frappe.db.get_all(
"Journal Entry Account",
{"parent": ("in", journal_entries), "party_type": "Supplier", "party": ("is", "set")},
["parent", "party"],
):
if d.parent not in journal_entry_party_map:
journal_entry_party_map[d.parent] = []
journal_entry_party_map[d.parent].append(d.party)
return journal_entry_party_map
def get_tax_category_map(vouchers, doctype, tax_category_map):

View File

@@ -172,6 +172,7 @@ def get_rootwise_opening_balances(filters, report_type):
query_filters = {
"company": filters.company,
"from_date": filters.from_date,
"to_date": filters.to_date,
"report_type": report_type,
"year_start_date": filters.year_start_date,
"project": filters.project,
@@ -200,7 +201,7 @@ def get_rootwise_opening_balances(filters, report_type):
where
company=%(company)s
{additional_conditions}
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
and (posting_date < %(from_date)s or (ifnull(is_opening, 'No') = 'Yes' and posting_date <= %(to_date)s))
and account in (select name from `tabAccount` where report_type=%(report_type)s)
and is_cancelled = 0
group by account""".format(

View File

@@ -106,12 +106,17 @@ def get_opening_balances(filters):
where company=%(company)s
and is_cancelled=0
and ifnull(party_type, '') = %(party_type)s and ifnull(party, '') != ''
and (posting_date < %(from_date)s or ifnull(is_opening, 'No') = 'Yes')
and (posting_date < %(from_date)s or (ifnull(is_opening, 'No') = 'Yes' and posting_date <= %(to_date)s))
{account_filter}
group by party""".format(
account_filter=account_filter
),
{"company": filters.company, "from_date": filters.from_date, "party_type": filters.party_type},
{
"company": filters.company,
"from_date": filters.from_date,
"to_date": filters.to_date,
"party_type": filters.party_type,
},
as_dict=True,
)

View File

@@ -818,6 +818,31 @@ def get_held_invoices(party_type, party):
return held_invoices
def remove_return_pos_invoices(party_type, party, invoice_list):
if invoice_list:
if party_type == "Customer":
sinv = frappe.qb.DocType("Sales Invoice")
return_pos = (
frappe.qb.from_(sinv)
.select(sinv.name)
.where((sinv.is_pos == 1) & (sinv.docstatus == 1) & (sinv.is_return == 1))
.run()
)
if return_pos:
return_pos = [x[0] for x in return_pos]
else:
return invoice_list
# remove pos return invoices from invoice_list
for idx, inv in enumerate(invoice_list, 0):
if inv.voucher_no in return_pos:
del invoice_list[idx]
return invoice_list
def get_outstanding_invoices(party_type, party, account, condition=None, filters=None):
outstanding_invoices = []
precision = frappe.get_precision("Sales Invoice", "outstanding_amount") or 2
@@ -868,6 +893,8 @@ def get_outstanding_invoices(party_type, party, account, condition=None, filters
as_dict=True,
)
invoice_list = remove_return_pos_invoices(party_type, party, invoice_list)
payment_entries = frappe.db.sql(
"""
select against_voucher_type, against_voucher,

View File

@@ -38,7 +38,6 @@
"purchase_date",
"section_break_23",
"calculate_depreciation",
"allow_monthly_depreciation",
"column_break_33",
"opening_accumulated_depreciation",
"number_of_depreciations_booked",
@@ -454,13 +453,6 @@
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"default": "0",
"depends_on": "calculate_depreciation",
"fieldname": "allow_monthly_depreciation",
"fieldtype": "Check",
"label": "Allow Monthly Depreciation"
},
{
"collapsible": 1,
"collapsible_depends_on": "is_existing_asset",
@@ -503,7 +495,7 @@
"link_fieldname": "asset"
}
],
"modified": "2022-01-30 20:19:24.680027",
"modified": "2022-07-20 16:22:44.437579",
"modified_by": "Administrator",
"module": "Assets",
"name": "Asset",
@@ -545,4 +537,4 @@
"sort_order": "DESC",
"title_field": "asset_name",
"track_changes": 1
}
}

View File

@@ -353,61 +353,16 @@ class Asset(AccountsController):
skip_row = True
if depreciation_amount > 0:
# With monthly depreciation, each depreciation is divided by months remaining until next date
if self.allow_monthly_depreciation:
# month range is 1 to 12
# In pro rata case, for first and last depreciation, month range would be different
if (has_pro_rata and n == 0 and not self.number_of_depreciations_booked) or (
has_pro_rata and n == cint(number_of_pending_depreciations) - 1
):
month_range = months
else:
month_range = finance_book.frequency_of_depreciation
for r in range(month_range):
if has_pro_rata and n == 0 and not self.number_of_depreciations_booked:
# For first entry of monthly depr
if r == 0:
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date) + 1
per_day_amt = depreciation_amount / days
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
depreciation_amount -= depreciation_amount_for_current_month
date = monthly_schedule_date
amount = depreciation_amount_for_current_month
else:
date = add_months(monthly_schedule_date, r)
amount = depreciation_amount / (month_range - 1)
elif (has_pro_rata and n == cint(number_of_pending_depreciations) - 1) and r == cint(
month_range
) - 1:
# For last entry of monthly depr
date = last_schedule_date
amount = depreciation_amount / month_range
else:
date = add_months(monthly_schedule_date, r)
amount = depreciation_amount / month_range
self.append(
"schedules",
{
"schedule_date": date,
"depreciation_amount": amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
else:
self.append(
"schedules",
{
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
self.append(
"schedules",
{
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
# depreciation schedules need to be cleared before modification due to increase in asset life/asset sales
# JE: Journal Entry, FB: Finance Book
@@ -853,7 +808,7 @@ class Asset(AccountsController):
depreciation_rate = math.pow(value, 1.0 / flt(args.get("total_number_of_depreciations"), 2))
return 100 * (1 - flt(depreciation_rate, float_precision))
return flt((100 * (1 - depreciation_rate)), float_precision)
def get_pro_rata_amt(self, row, depreciation_amount, from_date, to_date):
days = date_diff(to_date, from_date)
@@ -864,7 +819,9 @@ class Asset(AccountsController):
def update_maintenance_status():
assets = frappe.get_all("Asset", filters={"docstatus": 1, "maintenance_required": 1})
assets = frappe.get_all(
"Asset", filters={"docstatus": 1, "maintenance_required": 1, "disposal_date": ("is", "not set")}
)
for asset in assets:
asset = frappe.get_doc("Asset", asset.name)

View File

@@ -7,7 +7,7 @@ import frappe
from frappe.utils import add_days, add_months, cstr, flt, get_last_day, getdate, nowdate
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.assets.doctype.asset.asset import make_sales_invoice
from erpnext.assets.doctype.asset.asset import make_sales_invoice, update_maintenance_status
from erpnext.assets.doctype.asset.depreciation import (
post_depreciation_entries,
restore_asset,
@@ -145,6 +145,7 @@ class TestAsset(AssetSetup):
def test_is_fixed_asset_set(self):
asset = create_asset(is_existing_asset=1)
doc = frappe.new_doc("Purchase Invoice")
doc.company = "_Test Company"
doc.supplier = "_Test Supplier"
doc.append("items", {"item_code": "Macbook Pro", "qty": 1, "asset": asset.name})
@@ -237,6 +238,34 @@ class TestAsset(AssetSetup):
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Partially Depreciated")
def test_asset_with_maintenance_required_status_after_sale(self):
asset = create_asset(
calculate_depreciation=1,
available_for_use_date="2020-06-06",
purchase_date="2020-01-01",
expected_value_after_useful_life=10000,
total_number_of_depreciations=3,
frequency_of_depreciation=10,
maintenance_required=1,
depreciation_start_date="2020-12-31",
submit=1,
)
post_depreciation_entries(date="2021-01-01")
si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company")
si.customer = "_Test Customer"
si.due_date = nowdate()
si.get("items")[0].rate = 25000
si.insert()
si.submit()
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")
update_maintenance_status()
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")
def test_expense_head(self):
pr = make_purchase_receipt(
item_code="Macbook Pro", qty=2, rate=200000.0, location="Test Location"
@@ -702,6 +731,8 @@ class TestDepreciationMethods(AssetSetup):
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
def test_monthly_depreciation_by_wdv_method(self):
existing_precision = frappe.db.get_default("float_precision")
frappe.db.set_default("float_precision", 3)
asset = create_asset(
calculate_depreciation=1,
available_for_use_date="2022-02-15",
@@ -715,12 +746,12 @@ class TestDepreciationMethods(AssetSetup):
)
expected_schedules = [
["2022-02-28", 645.0, 645.0],
["2022-03-31", 1206.8, 1851.8],
["2022-04-30", 1051.12, 2902.92],
["2022-05-31", 915.52, 3818.44],
["2022-06-30", 797.42, 4615.86],
["2022-07-15", 384.14, 5000.0],
["2022-02-28", 647.25, 647.25],
["2022-03-31", 1210.71, 1857.96],
["2022-04-30", 1053.99, 2911.95],
["2022-05-31", 917.55, 3829.5],
["2022-06-30", 798.77, 4628.27],
["2022-07-15", 371.73, 5000.0],
]
schedules = [
@@ -731,8 +762,8 @@ class TestDepreciationMethods(AssetSetup):
]
for d in asset.get("schedules")
]
self.assertEqual(schedules, expected_schedules)
frappe.db.set_default("float_precision", existing_precision)
class TestDepreciationBasics(AssetSetup):
@@ -1350,6 +1381,7 @@ def create_asset(**args):
"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,
"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",
"location": args.location or "Test Location",

View File

@@ -425,7 +425,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
company: me.frm.doc.company
},
allow_child_item_selection: true,
child_fielname: "items",
child_fieldname: "items",
child_columns: ["item_code", "qty"]
})
}, __("Get Items From"));

View File

@@ -439,7 +439,6 @@
"fieldname": "ignore_pricing_rule",
"fieldtype": "Check",
"label": "Ignore Pricing Rule",
"no_copy": 1,
"permlevel": 1,
"print_hide": 1
},
@@ -1170,7 +1169,7 @@
"idx": 105,
"is_submittable": 1,
"links": [],
"modified": "2022-04-26 12:16:38.694276",
"modified": "2022-09-16 17:45:04.954055",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",

View File

@@ -18,7 +18,7 @@ from erpnext.accounts.doctype.sales_invoice.sales_invoice import (
from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category import (
get_party_tax_withholding_details,
)
from erpnext.accounts.party import get_party_account_currency
from erpnext.accounts.party import get_party_account, get_party_account_currency
from erpnext.buying.utils import check_on_hold_or_closed_status, validate_for_items
from erpnext.controllers.buying_controller import BuyingController
from erpnext.setup.doctype.item_group.item_group import get_item_group_defaults
@@ -323,6 +323,7 @@ class PurchaseOrder(BuyingController):
update_linked_doc(self.doctype, self.name, self.inter_company_order_reference)
def on_cancel(self):
self.ignore_linked_doctypes = ("GL Entry", "Payment Ledger Entry")
super(PurchaseOrder, self).on_cancel()
if self.is_against_so():
@@ -532,6 +533,7 @@ def get_mapped_purchase_invoice(source_name, target_doc=None, ignore_permissions
target.set_advances()
target.set_payment_schedule()
target.credit_to = get_party_account("Supplier", source.supplier, source.company)
def update_item(obj, target, source_parent):
target.amount = flt(obj.amount) - flt(obj.billed_amt)

View File

@@ -15,9 +15,12 @@ frappe.ui.form.on("Request for Quotation",{
frm.fields_dict["suppliers"].grid.get_field("contact").get_query = function(doc, cdt, cdn) {
let d = locals[cdt][cdn];
return {
query: "erpnext.buying.doctype.request_for_quotation.request_for_quotation.get_supplier_contacts",
filters: {'supplier': d.supplier}
}
query: "frappe.contacts.doctype.contact.contact.contact_query",
filters: {
link_doctype: "Supplier",
link_name: d.supplier || ""
}
};
}
},

View File

@@ -113,7 +113,7 @@ class RequestforQuotation(BuyingController):
def get_link(self):
# RFQ link for supplier portal
return get_url("/rfq/" + self.name)
return get_url("/app/request-for-quotation/" + self.name)
def update_supplier_part_no(self, supplier):
self.vendor = supplier
@@ -181,12 +181,20 @@ class RequestforQuotation(BuyingController):
doc_args = self.as_dict()
doc_args.update({"supplier": data.get("supplier"), "supplier_name": data.get("supplier_name")})
# Get Contact Full Name
supplier_name = None
if data.get("contact"):
contact_name = frappe.db.get_value(
"Contact", data.get("contact"), ["first_name", "middle_name", "last_name"]
)
supplier_name = (" ").join(x for x in contact_name if x) # remove any blank values
args = {
"update_password_link": update_password_link,
"message": frappe.render_template(self.message_for_supplier, doc_args),
"rfq_link": rfq_link,
"user_fullname": full_name,
"supplier_name": data.get("supplier_name"),
"supplier_name": supplier_name or data.get("supplier_name"),
"supplier_salutation": self.salutation or "Dear Mx.",
}
@@ -279,18 +287,6 @@ def get_list_context(context=None):
return list_context
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_supplier_contacts(doctype, txt, searchfield, start, page_len, filters):
return frappe.db.sql(
"""select `tabContact`.name from `tabContact`, `tabDynamic Link`
where `tabDynamic Link`.link_doctype = 'Supplier' and (`tabDynamic Link`.link_name=%(name)s
and `tabDynamic Link`.link_name like %(txt)s) and `tabContact`.name = `tabDynamic Link`.parent
limit %(start)s, %(page_len)s""",
{"start": start, "page_len": page_len, "txt": "%%%s%%" % txt, "name": filters.get("supplier")},
)
@frappe.whitelist()
def make_supplier_quotation_from_rfq(source_name, target_doc=None, for_supplier=None):
def postprocess(source, target_doc):

View File

@@ -65,7 +65,6 @@ class TestRequestforQuotation(FrappeTestCase):
)
sq.submit()
frappe.form_dict = frappe.local("form_dict")
frappe.form_dict.name = rfq.name
self.assertEqual(check_supplier_has_docname_access(supplier_wt_appos[0].get("supplier")), True)

View File

@@ -1105,17 +1105,17 @@ class AccountsController(TransactionBase):
frappe.db.get_single_value("Accounts Settings", "enable_discount_accounting")
)
if self.doctype == "Purchase Invoice":
dr_or_cr = "credit"
rev_dr_cr = "debit"
supplier_or_customer = self.supplier
else:
dr_or_cr = "debit"
rev_dr_cr = "credit"
supplier_or_customer = self.customer
if enable_discount_accounting:
if self.doctype == "Purchase Invoice":
dr_or_cr = "credit"
rev_dr_cr = "debit"
supplier_or_customer = self.supplier
else:
dr_or_cr = "debit"
rev_dr_cr = "credit"
supplier_or_customer = self.customer
for item in self.get("items"):
if item.get("discount_amount") and item.get("discount_account"):
discount_amount = item.discount_amount * item.qty
@@ -1169,18 +1169,22 @@ class AccountsController(TransactionBase):
)
)
if self.get("discount_amount") and self.get("additional_discount_account"):
gl_entries.append(
self.get_gl_dict(
{
"account": self.additional_discount_account,
"against": supplier_or_customer,
dr_or_cr: self.discount_amount,
"cost_center": self.cost_center,
},
item=self,
)
if (
(enable_discount_accounting or self.get("is_cash_or_non_trade_discount"))
and self.get("additional_discount_account")
and self.get("discount_amount")
):
gl_entries.append(
self.get_gl_dict(
{
"account": self.additional_discount_account,
"against": supplier_or_customer,
dr_or_cr: self.discount_amount,
"cost_center": self.cost_center,
},
item=self,
)
)
def validate_multiple_billing(self, ref_dt, item_ref_dn, based_on, parentfield):
from erpnext.controllers.status_updater import get_allowance_for
@@ -1470,8 +1474,15 @@ class AccountsController(TransactionBase):
self.get("debit_to") if self.doctype == "Sales Invoice" else self.get("credit_to")
)
party_account_currency = get_account_currency(party_account)
allow_multi_currency_invoices_against_single_party_account = frappe.db.get_singles_value(
"Accounts Settings", "allow_multi_currency_invoices_against_single_party_account"
)
if not party_gle_currency and (party_account_currency != self.currency):
if (
not party_gle_currency
and (party_account_currency != self.currency)
and not allow_multi_currency_invoices_against_single_party_account
):
frappe.throw(
_("Party Account {0} currency ({1}) and document currency ({2}) should be same").format(
frappe.bold(party_account), party_account_currency, self.currency

View File

@@ -86,6 +86,7 @@ class BuyingController(StockController, Subcontracting):
company=self.company,
party_address=self.get("supplier_address"),
shipping_address=self.get("shipping_address"),
company_address=self.get("billing_address"),
fetch_payment_terms_template=not self.get("ignore_default_payment_terms_template"),
ignore_permissions=self.flags.ignore_permissions,
)
@@ -192,16 +193,16 @@ class BuyingController(StockController, Subcontracting):
if self.meta.get_field("base_in_words"):
if self.meta.get_field("base_rounded_total") and not self.is_rounded_total_disabled():
amount = self.base_rounded_total
amount = abs(self.base_rounded_total)
else:
amount = self.base_grand_total
amount = abs(self.base_grand_total)
self.base_in_words = money_in_words(amount, self.company_currency)
if self.meta.get_field("in_words"):
if self.meta.get_field("rounded_total") and not self.is_rounded_total_disabled():
amount = self.rounded_total
amount = abs(self.rounded_total)
else:
amount = self.grand_total
amount = abs(self.grand_total)
self.in_words = money_in_words(amount, self.currency)
@@ -299,9 +300,14 @@ class BuyingController(StockController, Subcontracting):
raise_error_if_no_rate=False,
)
rate = flt(outgoing_rate * d.conversion_factor, d.precision("rate"))
rate = flt(outgoing_rate * (d.conversion_factor or 1), d.precision("rate"))
else:
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), "rate")
field = "incoming_rate" if self.get("is_internal_supplier") else "rate"
rate = flt(
frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), field)
* (d.conversion_factor or 1),
d.precision("rate"),
)
if self.is_internal_transfer():
if rate != d.rate:

View File

@@ -18,8 +18,9 @@ from erpnext.stock.get_item_details import _get_item_tax_template
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def employee_query(doctype, txt, searchfield, start, page_len, filters):
doctype = "Employee"
conditions = []
fields = get_fields("Employee", ["name", "employee_name"])
fields = get_fields(doctype, ["name", "employee_name"])
return frappe.db.sql(
"""select {fields} from `tabEmployee`
@@ -49,7 +50,8 @@ def employee_query(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def lead_query(doctype, txt, searchfield, start, page_len, filters):
fields = get_fields("Lead", ["name", "lead_name", "company_name"])
doctype = "Lead"
fields = get_fields(doctype, ["name", "lead_name", "company_name"])
return frappe.db.sql(
"""select {fields} from `tabLead`
@@ -77,6 +79,7 @@ def lead_query(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def customer_query(doctype, txt, searchfield, start, page_len, filters):
doctype = "Customer"
conditions = []
cust_master_name = frappe.defaults.get_user_default("cust_master_name")
@@ -85,9 +88,9 @@ def customer_query(doctype, txt, searchfield, start, page_len, filters):
else:
fields = ["name", "customer_name", "customer_group", "territory"]
fields = get_fields("Customer", fields)
fields = get_fields(doctype, fields)
searchfields = frappe.get_meta("Customer").get_search_fields()
searchfields = frappe.get_meta(doctype).get_search_fields()
searchfields = " or ".join(field + " like %(txt)s" for field in searchfields)
return frappe.db.sql(
@@ -116,6 +119,7 @@ def customer_query(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def supplier_query(doctype, txt, searchfield, start, page_len, filters):
doctype = "Supplier"
supp_master_name = frappe.defaults.get_user_default("supp_master_name")
if supp_master_name == "Supplier Name":
@@ -123,7 +127,7 @@ def supplier_query(doctype, txt, searchfield, start, page_len, filters):
else:
fields = ["name", "supplier_name", "supplier_group"]
fields = get_fields("Supplier", fields)
fields = get_fields(doctype, fields)
return frappe.db.sql(
"""select {field} from `tabSupplier`
@@ -147,6 +151,7 @@ def supplier_query(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
doctype = "Account"
company_currency = erpnext.get_company_currency(filters.get("company"))
def get_accounts(with_account_type_filter):
@@ -197,13 +202,14 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=False):
doctype = "Item"
conditions = []
if isinstance(filters, str):
filters = json.loads(filters)
# Get searchfields from meta and use in Item Link field query
meta = frappe.get_meta("Item", cached=True)
meta = frappe.get_meta(doctype, cached=True)
searchfields = meta.get_search_fields()
# these are handled separately
@@ -257,7 +263,7 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
filters.pop("supplier", None)
description_cond = ""
if frappe.db.count("Item", cache=True) < 50000:
if frappe.db.count(doctype, cache=True) < 50000:
# scan description only if items are less than 50000
description_cond = "or tabItem.description LIKE %(txt)s"
return frappe.db.sql(
@@ -300,8 +306,9 @@ def item_query(doctype, txt, searchfield, start, page_len, filters, as_dict=Fals
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def bom(doctype, txt, searchfield, start, page_len, filters):
doctype = "BOM"
conditions = []
fields = get_fields("BOM", ["name", "item"])
fields = get_fields(doctype, ["name", "item"])
return frappe.db.sql(
"""select {fields}
@@ -331,6 +338,7 @@ def bom(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_project_name(doctype, txt, searchfield, start, page_len, filters):
doctype = "Project"
cond = ""
if filters and filters.get("customer"):
cond = """(`tabProject`.customer = %s or
@@ -338,9 +346,9 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters):
frappe.db.escape(filters.get("customer"))
)
fields = get_fields("Project", ["name", "project_name"])
searchfields = frappe.get_meta("Project").get_search_fields()
searchfields = " or ".join([field + " like %(txt)s" for field in searchfields])
fields = get_fields(doctype, ["name", "project_name"])
searchfields = frappe.get_meta(doctype).get_search_fields()
searchfields = " or ".join(["`tabProject`." + field + " like %(txt)s" for field in searchfields])
return frappe.db.sql(
"""select {fields} from `tabProject`
@@ -366,7 +374,8 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len, filters, as_dict):
fields = get_fields("Delivery Note", ["name", "customer", "posting_date"])
doctype = "Delivery Note"
fields = get_fields(doctype, ["name", "customer", "posting_date"])
return frappe.db.sql(
"""
@@ -402,6 +411,7 @@ def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len,
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
doctype = "Batch"
cond = ""
if filters.get("posting_date"):
cond = "and (batch.expiry_date is null or batch.expiry_date >= %(posting_date)s)"
@@ -420,7 +430,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
if filters.get("is_return"):
having_clause = ""
meta = frappe.get_meta("Batch", cached=True)
meta = frappe.get_meta(doctype, cached=True)
searchfields = meta.get_search_fields()
search_columns = ""
@@ -496,6 +506,7 @@ def get_batch_no(doctype, txt, searchfield, start, page_len, filters):
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_account_list(doctype, txt, searchfield, start, page_len, filters):
doctype = "Account"
filter_list = []
if isinstance(filters, dict):
@@ -514,7 +525,7 @@ def get_account_list(doctype, txt, searchfield, start, page_len, filters):
filter_list.append([doctype, searchfield, "like", "%%%s%%" % txt])
return frappe.desk.reportview.execute(
"Account",
doctype,
filters=filter_list,
fields=["name", "parent_account"],
limit_start=start,
@@ -553,6 +564,7 @@ def get_income_account(doctype, txt, searchfield, start, page_len, filters):
if not filters:
filters = {}
doctype = "Account"
condition = ""
if filters.get("company"):
condition += "and tabAccount.company = %(company)s"
@@ -628,6 +640,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
if not filters:
filters = {}
doctype = "Account"
condition = ""
if filters.get("company"):
condition += "and tabAccount.company = %(company)s"
@@ -650,6 +663,7 @@ def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
@frappe.validate_and_sanitize_search_inputs
def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
# Should be used when item code is passed in filters.
doctype = "Warehouse"
conditions, bin_conditions = [], []
filter_dict = get_doctype_wise_filters(filters)

View File

@@ -439,11 +439,17 @@ class SellingController(StockController):
# For internal transfers use incoming rate as the valuation rate
if self.is_internal_transfer():
if d.doctype == "Packed Item":
incoming_rate = flt(d.incoming_rate * d.conversion_factor, d.precision("incoming_rate"))
incoming_rate = flt(
flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor,
d.precision("incoming_rate"),
)
if d.incoming_rate != incoming_rate:
d.incoming_rate = incoming_rate
else:
rate = flt(d.incoming_rate * d.conversion_factor, d.precision("rate"))
rate = flt(
flt(d.incoming_rate, d.precision("incoming_rate")) * d.conversion_factor,
d.precision("rate"),
)
if d.rate != rate:
d.rate = rate
frappe.msgprint(
@@ -614,13 +620,13 @@ class SellingController(StockController):
stock_items = [d.item_code, d.description, d.warehouse, ""]
non_stock_items = [d.item_code, d.description]
duplicate_items_msg = _("Item {0} entered multiple times.").format(frappe.bold(d.item_code))
duplicate_items_msg += "<br><br>"
duplicate_items_msg += _("Please enable {} in {} to allow same item in multiple rows").format(
frappe.bold("Allow Item to Be Added Multiple Times in a Transaction"),
get_link_to_form("Selling Settings", "Selling Settings"),
)
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
duplicate_items_msg = _("Item {0} entered multiple times.").format(frappe.bold(d.item_code))
duplicate_items_msg += "<br><br>"
duplicate_items_msg += _("Please enable {} in {} to allow same item in multiple rows").format(
frappe.bold("Allow Item to Be Added Multiple Times in a Transaction"),
get_link_to_form("Selling Settings", "Selling Settings"),
)
if stock_items in check_list:
frappe.throw(duplicate_items_msg)
else:

View File

@@ -33,6 +33,10 @@ class QualityInspectionNotSubmittedError(frappe.ValidationError):
pass
class BatchExpiredError(frappe.ValidationError):
pass
class StockController(AccountsController):
def validate(self):
super(StockController, self).validate()
@@ -74,6 +78,10 @@ class StockController(AccountsController):
def validate_serialized_batch(self):
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
is_material_issue = False
if self.doctype == "Stock Entry" and self.purpose == "Material Issue":
is_material_issue = True
for d in self.get("items"):
if hasattr(d, "serial_no") and hasattr(d, "batch_no") and d.serial_no and d.batch_no:
serial_nos = frappe.get_all(
@@ -90,6 +98,9 @@ class StockController(AccountsController):
)
)
if is_material_issue:
continue
if flt(d.qty) > 0.0 and d.get("batch_no") and self.get("posting_date") and self.docstatus < 2:
expiry_date = frappe.get_cached_value("Batch", d.get("batch_no"), "expiry_date")
@@ -97,7 +108,8 @@ class StockController(AccountsController):
frappe.throw(
_("Row #{0}: The batch {1} has already expired.").format(
d.idx, get_link_to_form("Batch", d.get("batch_no"))
)
),
BatchExpiredError,
)
def clean_serial_nos(self):
@@ -127,13 +139,15 @@ class StockController(AccountsController):
warehouse_with_no_account = []
precision = self.get_debit_field_precision()
for item_row in voucher_details:
sle_list = sle_map.get(item_row.name)
sle_rounding_diff = 0.0
if sle_list:
for sle in sle_list:
if warehouse_account.get(sle.warehouse):
# from warehouse account
sle_rounding_diff += flt(sle.stock_value_difference)
self.check_expense_account(item_row)
# expense account/ target_warehouse / source_warehouse
@@ -176,6 +190,46 @@ class StockController(AccountsController):
elif sle.warehouse not in warehouse_with_no_account:
warehouse_with_no_account.append(sle.warehouse)
if abs(sle_rounding_diff) > (1.0 / (10**precision)) and self.is_internal_transfer():
warehouse_asset_account = ""
if self.get("is_internal_customer"):
warehouse_asset_account = warehouse_account[item_row.get("target_warehouse")]["account"]
elif self.get("is_internal_supplier"):
warehouse_asset_account = warehouse_account[item_row.get("warehouse")]["account"]
expense_account = frappe.db.get_value("Company", self.company, "default_expense_account")
gl_list.append(
self.get_gl_dict(
{
"account": expense_account,
"against": warehouse_asset_account,
"cost_center": item_row.cost_center,
"project": item_row.project or self.get("project"),
"remarks": _("Rounding gain/loss Entry for Stock Transfer"),
"debit": sle_rounding_diff,
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
},
warehouse_account[sle.warehouse]["account_currency"],
item=item_row,
)
)
gl_list.append(
self.get_gl_dict(
{
"account": warehouse_asset_account,
"against": expense_account,
"cost_center": item_row.cost_center,
"remarks": _("Rounding gain/loss Entry for Stock Transfer"),
"credit": sle_rounding_diff,
"project": item_row.get("project") or self.get("project"),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
},
item=item_row,
)
)
if warehouse_with_no_account:
for wh in warehouse_with_no_account:
if frappe.db.get_value("Warehouse", wh, "company"):

View File

@@ -355,6 +355,8 @@ class Subcontracting:
rm_obj.purchase_order = item_row.purchase_order
self.__set_batch_nos(bom_item, item_row, rm_obj, qty)
rm_obj.amount = flt(rm_obj.required_qty) * flt(rm_obj.rate)
def __set_batch_nos(self, bom_item, item_row, rm_obj, qty):
key = (rm_obj.rm_item_code, item_row.item_code, item_row.purchase_order)

View File

@@ -37,6 +37,12 @@ class calculate_taxes_and_totals(object):
self.set_discount_amount()
self.apply_discount_amount()
# Update grand total as per cash and non trade discount
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
self.doc.grand_total -= self.doc.discount_amount
self.doc.base_grand_total -= self.doc.base_discount_amount
self.set_rounded_total()
self.calculate_shipping_charges()
if self.doc.doctype in ["Sales Invoice", "Purchase Invoice"]:
@@ -598,6 +604,12 @@ class calculate_taxes_and_totals(object):
self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount")
)
if self.doc.apply_discount_on == "Grand Total" and self.doc.get(
"is_cash_or_non_trade_discount"
):
self.discount_amount_applied = True
return
total_for_discount_amount = self.get_total_for_discount_amount()
taxes = self.doc.get("taxes")
net_total = 0
@@ -758,6 +770,18 @@ class calculate_taxes_and_totals(object):
self.doc.precision("outstanding_amount"),
)
if (
self.doc.doctype == "Sales Invoice"
and self.doc.get("is_pos")
and self.doc.get("pos_profile")
and self.doc.get("is_consolidated")
):
write_off_limit = flt(
frappe.db.get_value("POS Profile", self.doc.pos_profile, "write_off_limit")
)
if write_off_limit and abs(self.doc.outstanding_amount) <= write_off_limit:
self.doc.write_off_outstanding_amount_automatically = 1
if (
self.doc.doctype == "Sales Invoice"
and self.doc.get("is_pos")

View File

@@ -48,7 +48,7 @@
"read_only": 1
},
{
"fetch_from": "website_item.image",
"fetch_from": "website_item.website_image",
"fieldname": "website_item_image",
"fieldtype": "Attach",
"label": "Website Item Image",
@@ -75,7 +75,7 @@
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-07-13 21:02:19.031652",
"modified": "2022-06-28 16:44:24.718728",
"modified_by": "Administrator",
"module": "E-commerce",
"name": "Recommended Items",
@@ -83,5 +83,6 @@
"permissions": [],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -30,10 +30,6 @@ frappe.ui.form.on('Website Item', {
}, __("View"));
},
image: () => {
refresh_field("image_view");
},
copy_from_item_group: (frm) => {
return frm.call({
doc: frm.doc,

View File

@@ -22,7 +22,6 @@
"column_break_11",
"description",
"brand",
"image",
"display_section",
"website_image",
"website_image_alt",
@@ -113,8 +112,11 @@
{
"description": "Item Image (if not slideshow)",
"fieldname": "website_image",
"fieldtype": "Attach",
"label": "Website Image"
"fieldtype": "Attach Image",
"hidden": 1,
"in_preview": 1,
"label": "Website Image",
"print_hide": 1
},
{
"description": "Image Alternative Text",
@@ -188,14 +190,6 @@
"options": "Item Group",
"read_only": 1
},
{
"fieldname": "image",
"fieldtype": "Attach Image",
"hidden": 1,
"in_preview": 1,
"label": "Image",
"print_hide": 1
},
{
"default": "1",
"fieldname": "published",
@@ -348,13 +342,14 @@
}
],
"has_web_view": 1,
"image_field": "image",
"image_field": "website_image",
"index_web_pages_for_search": 1,
"links": [],
"modified": "2021-09-02 13:08:41.942726",
"modified": "2022-06-28 17:10:30.613251",
"modified_by": "Administrator",
"module": "E-commerce",
"name": "Website Item",
"naming_rule": "Expression (old style)",
"owner": "Administrator",
"permissions": [
{
@@ -410,6 +405,7 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "web_item_name",
"track_changes": 1
}

View File

@@ -1,7 +1,11 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and contributors
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and contributors
# For license information, please see license.txt
import json
from typing import TYPE_CHECKING, List, Union
if TYPE_CHECKING:
from erpnext.stock.doctype.item.item import Item
import frappe
from frappe import _
@@ -116,11 +120,6 @@ class WebsiteItem(WebsiteGenerator):
if frappe.flags.in_import:
return
auto_set_website_image = False
if not self.website_image and self.image:
auto_set_website_image = True
self.website_image = self.image
if not self.website_image:
return
@@ -137,18 +136,16 @@ class WebsiteItem(WebsiteGenerator):
file_doc = file_doc[0]
if not file_doc:
if not auto_set_website_image:
frappe.msgprint(
_("Website Image {0} attached to Item {1} cannot be found").format(
self.website_image, self.name
)
frappe.msgprint(
_("Website Image {0} attached to Item {1} cannot be found").format(
self.website_image, self.name
)
)
self.website_image = None
elif file_doc.is_private:
if not auto_set_website_image:
frappe.msgprint(_("Website Image should be a public file or website URL"))
frappe.msgprint(_("Website Image should be a public file or website URL"))
self.website_image = None
@@ -159,9 +156,8 @@ class WebsiteItem(WebsiteGenerator):
import requests.exceptions
if not self.is_new() and self.website_image != frappe.db.get_value(
self.doctype, self.name, "website_image"
):
db_website_image = frappe.db.get_value(self.doctype, self.name, "website_image")
if not self.is_new() and self.website_image != db_website_image:
self.thumbnail = None
if self.website_image and not self.thumbnail:
@@ -437,7 +433,9 @@ def check_if_user_is_customer(user=None):
@frappe.whitelist()
def make_website_item(doc, save=True):
def make_website_item(doc: "Item", save: bool = True) -> Union["WebsiteItem", List[str]]:
"Make Website Item from Item. Used via Form UI or patch."
if not doc:
return
@@ -457,7 +455,6 @@ def make_website_item(doc, save=True):
"item_group",
"stock_uom",
"brand",
"image",
"has_variants",
"variant_of",
"description",
@@ -465,6 +462,10 @@ def make_website_item(doc, save=True):
for field in fields_to_map:
website_item.update({field: doc.get(field)})
# Needed for publishing/mapping via Form UI only
if not frappe.flags.in_migrate and (doc.get("image") and not website_item.website_image):
website_item.website_image = doc.get("image")
if not save:
return website_item

View File

@@ -1,5 +1,5 @@
frappe.listview_settings['Website Item'] = {
add_fields: ["item_name", "web_item_name", "published", "image", "has_variants", "variant_of"],
add_fields: ["item_name", "web_item_name", "published", "website_image", "has_variants", "variant_of"],
filters: [["published", "=", "1"]],
get_indicator: function(doc) {

View File

@@ -20,7 +20,15 @@ def add_to_wishlist(item_code):
web_item_data = frappe.db.get_value(
"Website Item",
{"item_code": item_code},
["image", "website_warehouse", "name", "web_item_name", "item_name", "item_group", "route"],
[
"website_image",
"website_warehouse",
"name",
"web_item_name",
"item_name",
"item_group",
"route",
],
as_dict=1,
)
@@ -30,7 +38,7 @@ def add_to_wishlist(item_code):
"item_group": web_item_data.get("item_group"),
"website_item": web_item_data.get("name"),
"web_item_name": web_item_data.get("web_item_name"),
"image": web_item_data.get("image"),
"image": web_item_data.get("website_image"),
"warehouse": web_item_data.get("website_warehouse"),
"route": web_item_data.get("route"),
}

View File

@@ -35,7 +35,6 @@ class ProductQuery:
"variant_of",
"has_variants",
"item_group",
"image",
"web_long_description",
"short_description",
"route",

View File

@@ -35,7 +35,7 @@ erpnext.ProductGrid = class {
}
get_image_html(item, title) {
let image = item.website_image || item.image;
let image = item.website_image;
if (image) {
return `

View File

@@ -35,7 +35,7 @@ erpnext.ProductList = class {
}
get_image_html(item, title, settings) {
let image = item.website_image || item.image;
let image = item.website_image;
let wishlist_enabled = !item.has_variants && settings.enable_wishlist;
let image_html = ``;

View File

@@ -199,16 +199,32 @@ def get_fee_components(fee_structure):
@frappe.whitelist()
def get_fee_schedule(program, student_category=None):
def get_fee_schedule(program, student_category=None, academic_year=None):
"""Returns Fee Schedule.
:param program: Program.
:param student_category: Student Category
:param student_category: Student Category.
:param academic_year: Academic Year.
"""
fs = frappe.get_all(
"Program Fee",
fields=["academic_term", "fee_structure", "due_date", "amount"],
filters={"parent": program, "student_category": student_category},
filters = {}
if program:
filters = {"program": program}
if student_category:
filters["student_category"] = student_category
if academic_year:
filters["academic_year"] = academic_year
fs = frappe.db.get_list(
"Fee Schedule",
filters=filters,
fields=[
"academic_term",
"fee_structure",
"student_category",
"due_date",
"total_amount as amount",
],
order_by="idx",
)
return fs

View File

@@ -11,9 +11,12 @@ frappe.ui.form.on('Course Scheduling Tool', {
},
refresh(frm) {
frm.disable_save();
frm.trigger("render_days");
frm.page.set_primary_action(__('Schedule Course'), () => {
frm.call('schedule_course')
frappe.dom.freeze(__("Scheduling..."));
frm.call('schedule_course', { days: frm.days.get_checked_options() })
.then(r => {
frappe.dom.unfreeze();
if (!r.message) {
frappe.throw(__('There were errors creating Course Schedule'));
}
@@ -40,5 +43,60 @@ frappe.ui.form.on('Course Scheduling Tool', {
}
});
});
},
render_days: function(frm) {
const days_html = $('<div class="days-editor">').appendTo(
frm.fields_dict.days_html.wrapper
);
if (!frm.days) {
frm.days = frappe.ui.form.make_control({
parent: days_html,
df: {
fieldname: "days",
fieldtype: "MultiCheck",
select_all: true,
columns: 4,
options: [
{
label: __("Monday"),
value: "Monday",
checked: 0,
},
{
label: __("Tuesday"),
value: "Tuesday",
checked: 0,
},
{
label: __("Wednesday"),
value: "Wednesday",
checked: 0,
},
{
label: __("Thursday"),
value: "Thursday",
checked: 0,
},
{
label: __("Friday"),
value: "Friday",
checked: 0,
},
{
label: __("Saturday"),
value: "Saturday",
checked: 0,
},
{
label: __("Sunday"),
value: "Sunday",
checked: 0,
},
],
},
render_input: true,
});
}
}
});

View File

@@ -1,661 +1,171 @@
{
"allow_copy": 1,
"allow_guest_to_view": 0,
"allow_import": 0,
"allow_rename": 0,
"beta": 0,
"creation": "2015-09-23 15:37:38.108475",
"custom": 0,
"docstatus": 0,
"doctype": "DocType",
"document_type": "Setup",
"editable_grid": 0,
"engine": "InnoDB",
"actions": [],
"allow_copy": 1,
"creation": "2015-09-23 15:37:38.108475",
"doctype": "DocType",
"document_type": "Setup",
"engine": "InnoDB",
"field_order": [
"student_group",
"course",
"program",
"column_break_3",
"academic_year",
"academic_term",
"section_break_6",
"instructor",
"instructor_name",
"column_break_9",
"room",
"section_break_7",
"days_html",
"section_break_14",
"from_time",
"course_start_date",
"column_break_15",
"to_time",
"course_end_date",
"reschedule"
],
"fields": [
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "student_group",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Student Group",
"length": 0,
"no_copy": 0,
"options": "Student Group",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "student_group",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Student Group",
"options": "Student Group",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "course",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Course",
"length": 0,
"no_copy": 0,
"options": "Course",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "course",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Course",
"options": "Course",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "program",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Program",
"length": 0,
"no_copy": 0,
"options": "Program",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "program",
"fieldtype": "Link",
"label": "Program",
"options": "Program",
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_3",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_3",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_year",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Year",
"length": 0,
"no_copy": 0,
"options": "Academic Year",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "academic_year",
"fieldtype": "Link",
"label": "Academic Year",
"options": "Academic Year",
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "academic_term",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Academic Term",
"length": 0,
"no_copy": 0,
"options": "Academic Term",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "academic_term",
"fieldtype": "Link",
"label": "Academic Term",
"options": "Academic Term",
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_6",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "section_break_6",
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "instructor",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Instructor",
"length": 0,
"no_copy": 0,
"options": "Instructor",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "instructor",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Instructor",
"options": "Instructor",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_from": "instructor.instructor_name",
"fieldname": "instructor_name",
"fieldtype": "Read Only",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Instructor Name",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 1,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "instructor_name",
"fieldtype": "Read Only",
"label": "Instructor Name",
"read_only": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_9",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_9",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "room",
"fieldtype": "Link",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 1,
"in_standard_filter": 0,
"label": "Room",
"length": 0,
"no_copy": 0,
"options": "Room",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "room",
"fieldtype": "Link",
"in_list_view": 1,
"label": "Room",
"options": "Room",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "section_break_7",
"fieldtype": "Section Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "section_break_7",
"fieldtype": "Section Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "from_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "From Time",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "from_time",
"fieldtype": "Time",
"label": "From Time",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "course_start_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Course Start Date",
"length": 0,
"no_copy": 0,
"options": "",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "course_start_date",
"fieldtype": "Date",
"label": "Course Start Date",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "day",
"fieldtype": "Select",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Day",
"length": 0,
"no_copy": 0,
"options": "\nMonday\nTuesday\nWednesday\nThursday\nFriday\nSaturday\nSunday",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"default": "0",
"fieldname": "reschedule",
"fieldtype": "Check",
"label": "Reschedule"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "reschedule",
"fieldtype": "Check",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Reschedule",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "column_break_15",
"fieldtype": "Column Break"
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "column_break_15",
"fieldtype": "Column Break",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 0,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "to_time",
"fieldtype": "Time",
"label": "To TIme",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "to_time",
"fieldtype": "Time",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "To TIme",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
"fieldname": "course_end_date",
"fieldtype": "Date",
"label": "Course End Date",
"reqd": 1
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"default": "",
"fieldname": "course_end_date",
"fieldtype": "Date",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
"label": "Course End Date",
"length": 0,
"no_copy": 0,
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
"set_only_once": 0,
"translatable": 0,
"unique": 0
"fieldname": "days_html",
"fieldtype": "HTML",
"label": "Days HTML"
},
{
"fieldname": "section_break_14",
"fieldtype": "Section Break"
}
],
"has_web_view": 0,
"hide_heading": 1,
"hide_toolbar": 1,
"idx": 0,
"image_view": 0,
"in_create": 0,
"is_submittable": 0,
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
"modified": "2018-05-16 22:43:29.363798",
"modified_by": "Administrator",
"module": "Education",
"name": "Course Scheduling Tool",
"name_case": "",
"owner": "Administrator",
],
"hide_toolbar": 1,
"issingle": 1,
"links": [],
"modified": "2022-10-01 17:08:07.180557",
"modified_by": "Administrator",
"module": "Education",
"name": "Course Scheduling Tool",
"owner": "Administrator",
"permissions": [
{
"amend": 0,
"cancel": 0,
"create": 1,
"delete": 0,
"email": 0,
"export": 0,
"if_owner": 0,
"import": 0,
"permlevel": 0,
"print": 0,
"read": 1,
"report": 0,
"role": "Academics User",
"set_user_permissions": 0,
"share": 0,
"submit": 0,
"create": 1,
"read": 1,
"role": "Academics User",
"write": 1
}
],
"quick_entry": 0,
"read_only": 0,
"read_only_onload": 0,
"restrict_to_domain": "Education",
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1,
"track_seen": 0
],
"restrict_to_domain": "Education",
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 1
}

View File

@@ -14,7 +14,7 @@ from erpnext.education.utils import OverlapError
class CourseSchedulingTool(Document):
@frappe.whitelist()
def schedule_course(self):
def schedule_course(self, days):
"""Creates course schedules as per specified parameters"""
course_schedules = []
@@ -22,7 +22,7 @@ class CourseSchedulingTool(Document):
rescheduled = []
reschedule_errors = []
self.validate_mandatory()
self.validate_mandatory(days)
self.validate_date()
self.instructor_name = frappe.db.get_value("Instructor", self.instructor, "instructor_name")
@@ -34,24 +34,22 @@ class CourseSchedulingTool(Document):
self.course = course
if self.reschedule:
rescheduled, reschedule_errors = self.delete_course_schedule(rescheduled, reschedule_errors)
rescheduled, reschedule_errors = self.delete_course_schedule(
rescheduled, reschedule_errors, days
)
date = self.course_start_date
while date < self.course_end_date:
if self.day == calendar.day_name[getdate(date).weekday()]:
if calendar.day_name[getdate(date).weekday()] in days:
course_schedule = self.make_course_schedule(date)
try:
print("pass")
course_schedule.save()
except OverlapError:
print("fail")
course_schedules_errors.append(date)
else:
course_schedules.append(course_schedule)
date = add_days(date, 7)
else:
date = add_days(date, 1)
date = add_days(date, 1)
return dict(
course_schedules=course_schedules,
@@ -60,8 +58,10 @@ class CourseSchedulingTool(Document):
reschedule_errors=reschedule_errors,
)
def validate_mandatory(self):
def validate_mandatory(self, days):
"""Validates all mandatory fields"""
if not days:
frappe.throw(_("Please select at least one day to schedule the course."))
fields = [
"course",
@@ -71,7 +71,6 @@ class CourseSchedulingTool(Document):
"to_time",
"course_start_date",
"course_end_date",
"day",
]
for d in fields:
if not self.get(d):
@@ -82,9 +81,8 @@ class CourseSchedulingTool(Document):
if self.course_start_date > self.course_end_date:
frappe.throw(_("Course Start Date cannot be greater than Course End Date."))
def delete_course_schedule(self, rescheduled, reschedule_errors):
def delete_course_schedule(self, rescheduled, reschedule_errors, days):
"""Delete all course schedule within the Date range and specified filters"""
schedules = frappe.get_list(
"Course Schedule",
fields=["name", "schedule_date"],
@@ -98,7 +96,7 @@ class CourseSchedulingTool(Document):
for d in schedules:
try:
if self.day == calendar.day_name[getdate(d.schedule_date).weekday()]:
if calendar.day_name[getdate(d.schedule_date).weekday()] in days:
frappe.delete_doc("Course Schedule", d.name)
rescheduled.append(d.name)
except Exception:
@@ -108,7 +106,6 @@ class CourseSchedulingTool(Document):
def make_course_schedule(self, date):
"""Makes a new Course Schedule.
:param date: Date on which Course Schedule will be created."""
course_schedule = frappe.new_doc("Course Schedule")
course_schedule.student_group = self.student_group
course_schedule.course = self.course

View File

@@ -60,12 +60,15 @@ frappe.ui.form.on('Program Enrollment', {
method: 'erpnext.education.api.get_fee_schedule',
args: {
'program': frm.doc.program,
'student_category': frm.doc.student_category
'student_category': frm.doc.student_category,
'academic_year': frm.doc.academic_year
},
callback: function(r) {
if (r.message) {
cur_frm.clear_table("fees");
frm.refresh_fields('fees');
frm.set_value('fees' ,r.message);
frm.events.get_courses(frm);
frm.refresh_fields('fees');
}
}
});
@@ -76,6 +79,10 @@ frappe.ui.form.on('Program Enrollment', {
frappe.ui.form.trigger('Program Enrollment', 'program');
},
academic_year: function() {
frappe.ui.form.trigger('Program Enrollment', 'program');
},
get_courses: function(frm) {
frm.set_value('courses',[]);
frappe.call({

View File

@@ -105,6 +105,8 @@ class ProgramEnrollment(Document):
"academic_term": d.academic_term,
"fee_structure": d.fee_structure,
"program": self.program,
"student_batch": self.student_batch_name,
"student_category": self.student_category,
"due_date": d.due_date,
"student_name": self.student_name,
"program_enrollment": self.name,

View File

@@ -37,11 +37,26 @@ def handle_end_call(**kwargs):
@frappe.whitelist(allow_guest=True)
def handle_missed_call(**kwargs):
update_call_log(kwargs, "Missed")
status = ""
call_type = kwargs.get("CallType")
dial_call_status = kwargs.get("DialCallStatus")
if call_type == "incomplete" and dial_call_status == "no-answer":
status = "No Answer"
elif call_type == "client-hangup" and dial_call_status == "canceled":
status = "Canceled"
elif call_type == "incomplete" and dial_call_status == "failed":
status = "Failed"
update_call_log(kwargs, status)
def update_call_log(call_payload, status="Ringing", call_log=None):
call_log = call_log or get_call_log(call_payload)
# for a new sid, call_log and get_call_log will be empty so create a new log
if not call_log:
call_log = create_call_log(call_payload)
if call_log:
call_log.status = status
call_log.to = call_payload.get("DialWhomNumber")
@@ -53,16 +68,9 @@ def update_call_log(call_payload, status="Ringing", call_log=None):
def get_call_log(call_payload):
call_log = frappe.get_all(
"Call Log",
{
"id": call_payload.get("CallSid"),
},
limit=1,
)
if call_log:
return frappe.get_doc("Call Log", call_log[0].name)
call_log_id = call_payload.get("CallSid")
if frappe.db.exists("Call Log", call_log_id):
return frappe.get_doc("Call Log", call_log_id)
def create_call_log(call_payload):

View File

@@ -334,8 +334,6 @@ has_website_permission = {
"Patient": "erpnext.healthcare.web_form.personal_details.personal_details.has_website_permission",
}
dump_report_map = "erpnext.startup.report_data_map.data_map"
before_tests = "erpnext.setup.utils.before_tests"
standard_queries = {
@@ -461,6 +459,14 @@ scheduler_events = {
"0/30 * * * *": [
"erpnext.utilities.doctype.video.video.update_youtube_data",
],
# Hourly but offset by 30 minutes
"30 * * * *": [
"erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
],
# Daily but offset by 45 minutes
"45 0 * * *": [
"erpnext.stock.reorder_item.reorder_item",
],
},
"all": [
"erpnext.projects.doctype.project.project.project_status_update_reminder",
@@ -470,21 +476,19 @@ scheduler_events = {
],
"hourly": [
"erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails",
"erpnext.accounts.doctype.subscription.subscription.process_all",
"erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details",
"erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.automatic_synchronization",
"erpnext.projects.doctype.project.project.hourly_reminder",
"erpnext.projects.doctype.project.project.collect_project_status",
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
"erpnext.support.doctype.issue.issue.set_service_level_agreement_variance",
"erpnext.erpnext_integrations.connectors.shopify_connection.sync_old_orders",
],
"hourly_long": [
"erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries"
"erpnext.accounts.doctype.subscription.subscription.process_all",
"erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries",
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
],
"daily": [
"erpnext.stock.reorder_item.reorder_item",
"erpnext.support.doctype.issue.issue.auto_close_tickets",
"erpnext.crm.doctype.opportunity.opportunity.auto_close_opportunity",
"erpnext.controllers.accounts_controller.update_invoice_status",
@@ -583,6 +587,7 @@ accounting_dimension_doctypes = [
"Shipping Rule",
"Landed Cost Item",
"Asset Value Adjustment",
"Asset Repair",
"Loyalty Program",
"Fee Schedule",
"Fee Structure",

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