Compare commits

..

429 Commits

Author SHA1 Message Date
Frappe PR Bot
56070c7b86 chore(release): Bumped to Version 13.32.0
# [13.32.0](https://github.com/frappe/erpnext/compare/v13.31.1...v13.32.0) (2022-05-31)

### Bug Fixes

* add list view settings for Gratuity ([e4426ad](e4426addeb))
* amount precision for Tax Exemption Proof Submission ([bb04e4b](bb04e4b6de))
* component pay calculation ([b1e119d](b1e119d97d))
* conflicts ([cdb884b](cdb884bbf2))
* conflicts ([c02a89d](c02a89db4d))
* conflicts ([6aa6114](6aa6114757))
* date filter on quality inspection report (backport [#31148](https://github.com/frappe/erpnext/issues/31148)) ([#31164](https://github.com/frappe/erpnext/issues/31164)) ([f19747c](f19747cee0))
* Exchange rate reste to 1 on making mapped doc ([91863c7](91863c7457))
* Gratuity status not updated on salary slip submission ([0a014ed](0a014edd7a))
* HRA Exemption calculation in case of multiple salary structure assignments ([de8f5f8](de8f5f87d0))
* Improve button labels in Warehouse (backport [#31101](https://github.com/frappe/erpnext/issues/31101)) ([#31150](https://github.com/frappe/erpnext/issues/31150)) ([d891394](d891394dc8))
* **india:** duplicate qrcode and hide button ([#31154](https://github.com/frappe/erpnext/issues/31154)) ([f40100d](f40100d483))
* Job Opening linked to Staffing Plan cannot be created/updated if there are existing employees ([b4a3a53](b4a3a533c8))
* **pos:** freeze screen while processing pos invoices ([#30850](https://github.com/frappe/erpnext/issues/30850)) ([a7bf236](a7bf236c28))
* skip existing batch number during autogen (backport [#31140](https://github.com/frappe/erpnext/issues/31140)) ([#31144](https://github.com/frappe/erpnext/issues/31144)) ([a380bae](a380bae298))
* Tax Declaration tests and amount precision ([1e728df](1e728df54c))
* validation message ([096ae21](096ae210e1))

### Features

* Auto accrue loan interest for backdated term loans ([89c4d51](89c4d518e1))
* live preview of naming series on naming series tool (backport [#31141](https://github.com/frappe/erpnext/issues/31141)) ([#31146](https://github.com/frappe/erpnext/issues/31146)) ([fd2f3b9](fd2f3b9061))
* provision to exclude exploded items in the BOM (backport [#29450](https://github.com/frappe/erpnext/issues/29450)) ([#31174](https://github.com/frappe/erpnext/issues/31174)) ([50d338d](50d338df30))
2022-05-31 13:22:25 +00:00
Ankush Menat
683256eccc Merge pull request #31197 from frappe/version-13-hotfix
chore: weekly release for version-13
2022-05-31 18:50:44 +05:30
Rucha Mahabal
cdb884bbf2 fix: conflicts 2022-05-31 13:11:32 +05:30
Rucha Mahabal
2c26ab599a test: HRA Exemption in Proof Submission
(cherry picked from commit ed1ba677d6)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
bb04e4b6de fix: amount precision for Tax Exemption Proof Submission
(cherry picked from commit cfe2f8cac1)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
66deee1582 test: set country to India before running regional tests
(cherry picked from commit 2e98e9e0b9)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
1e728df54c fix: Tax Declaration tests and amount precision
(cherry picked from commit 00adda7c8d)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
c1f6f11e91 test: HRA Exemption in Employee Tax Exemption Declaration
(cherry picked from commit 5e96a46c87)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
b1e119d97d fix: component pay calculation
(cherry picked from commit 2b65c9616f)
2022-05-31 13:11:32 +05:30
Rucha Mahabal
de8f5f87d0 fix: HRA Exemption calculation in case of multiple salary structure assignments
(cherry picked from commit 34925a3a8c)

# Conflicts:
#	erpnext/regional/india/utils.py
2022-05-31 13:11:32 +05:30
Deepesh Garg
99917af73f Merge pull request #31156 from frappe/mergify/bp/version-13-hotfix/pr-30850
fix(pos): freeze screen while processing pos invoices (backport #30850)
2022-05-31 10:56:32 +05:30
Deepesh Garg
698c9ed3bc Merge pull request #31186 from frappe/mergify/bp/version-13-hotfix/pr-31127
feat: Auto accrue loan interest for backdated term loans (backport #31127)
2022-05-31 10:28:38 +05:30
Deepesh Garg
3344823b7d Merge pull request #31185 from frappe/mergify/bp/version-13-hotfix/pr-31184
fix(accounts): Ignore Cancelled GL Entries (backport #31184)
2022-05-31 10:28:27 +05:30
Deepesh Garg
89c4d518e1 feat: Auto accrue loan interest for backdated term loans
(cherry picked from commit 96d8b1ef3c)
2022-05-31 04:28:29 +00:00
Mitchy25
d8531f20a0 Ignore Cancelled GL Entries
Profitability Analysis includes 'is_cancelled' GL Entries which means that the profit numbers are incorrect. This change will ensure that the profit figures ignore cancelled GL Entries.

(cherry picked from commit a0c412a0dd)
2022-05-31 04:19:35 +00:00
Rucha Mahabal
2fe54e5435 chore: add Interview doctypes to HR workspace (#31181) 2022-05-30 18:26:20 +05:30
mergify[bot]
0759a8aee3 chore: remove unused bill no & date from purchase receipt (backport #31163) (#31177)
chore: remove unused bill no & date from purchase receipt (#31163)

(cherry picked from commit 08bf0baaae)

Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
2022-05-30 15:50:04 +05:30
mergify[bot]
50d338df30 feat: provision to exclude exploded items in the BOM (backport #29450) (#31174)
* feat: provision to exclude exploded items in the BOM (#29450)

(cherry picked from commit b75b00fefc)

* fix(ux): "New Version" button BOM

"duplicate" technically creates a new version but that's not intuitive
at all.

* fix: only erase BOM when do_not_explode is set

* fix: allow non-explosive recrusive BOMs

Recursion should be allowed as long as child item is not "exploded"
further by a BOM.

Co-authored-by: rohitwaghchaure <rohitw1991@gmail.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-30 15:43:49 +05:30
Ankush Menat
eb8d30fe06 chore: remove framework tests from erpnext
Similar tests exist in FW and this is failing because someone updated
the translations
2022-05-30 15:42:34 +05:30
mergify[bot]
7767dc1ee3 chore: update translation fr for BOM (backport #31126) (#31165)
* chore: update translation fr for BOM (#31126)

* fix: update translation

* fix: fr translation for BOM

(cherry picked from commit ce8e05146e)

* chore: format

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-29 22:10:46 +05:30
mergify[bot]
f19747cee0 fix: date filter on quality inspection report (backport #31148) (#31164)
fix: date filter on quality inspection report (#31148)

* fix: date filter

fix from date to to date filter btw those days

* fix: remove unnecessary conditions

Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
(cherry picked from commit 7ff8acac51)

Co-authored-by: MOHAMMED NIYAS <76736615+niyazrazak@users.noreply.github.com>
2022-05-27 17:32:24 +05:30
Rucha Mahabal
b98f3647ec Merge pull request #31162 from frappe/mergify/bp/version-13-hotfix/pr-31160
fix: Gratuity status not updated on salary slip submission (backport #31160)
2022-05-27 15:49:08 +05:30
Rucha Mahabal
c02a89db4d fix: conflicts 2022-05-27 15:30:29 +05:30
Rucha Mahabal
6aa6114757 fix: conflicts 2022-05-27 15:11:49 +05:30
Rucha Mahabal
30cbe8feb6 test: make holiday list before running gratuity tests
(cherry picked from commit c9e070393d)
2022-05-27 09:36:21 +00:00
Rucha Mahabal
e4426addeb fix: add list view settings for Gratuity
(cherry picked from commit 79b0aede00)

# Conflicts:
#	erpnext/payroll/doctype/gratuity/gratuity.json
2022-05-27 09:36:21 +00:00
Rucha Mahabal
b5d66877d8 refactor: clean-up gratuity tests
(cherry picked from commit 6c66bbbbfe)

# Conflicts:
#	erpnext/payroll/doctype/gratuity/test_gratuity.py
2022-05-27 09:36:20 +00:00
Rucha Mahabal
00a6bc7970 test: Gratuity status for payment via salary slip
(cherry picked from commit b81d7519c1)

# Conflicts:
#	erpnext/payroll/doctype/gratuity/test_gratuity.py
2022-05-27 09:36:20 +00:00
Rucha Mahabal
0a014edd7a fix: Gratuity status not updated on salary slip submission
(cherry picked from commit 385e22a067)
2022-05-27 09:36:19 +00:00
Frappe PR Bot
1bffd06e3a chore(release): Bumped to Version 13.31.1
## [13.31.1](https://github.com/frappe/erpnext/compare/v13.31.0...v13.31.1) (2022-05-27)

### Bug Fixes

* Exchange rate reste to 1 on making mapped doc ([e5b586f](e5b586ffd5))
2022-05-27 06:50:43 +00:00
Deepesh Garg
0371c62eae Merge pull request #31158 from frappe/mergify/bp/version-13/pr-31155
fix: Exchange rate reste to 1 on making mapped doc (backport #31155)
2022-05-27 12:19:09 +05:30
Deepesh Garg
f820d8d35e Merge pull request #31157 from frappe/mergify/bp/version-13-hotfix/pr-31155
fix: Exchange rate reste to 1 on making mapped doc (backport #31155)
2022-05-27 12:18:26 +05:30
Deepesh Garg
e5b586ffd5 fix: Exchange rate reste to 1 on making mapped doc
(cherry picked from commit 2a10f09d8d)
2022-05-27 06:47:55 +00:00
Deepesh Garg
91863c7457 fix: Exchange rate reste to 1 on making mapped doc
(cherry picked from commit 2a10f09d8d)
2022-05-27 06:47:35 +00:00
mergify[bot]
f40100d483 fix(india): duplicate qrcode and hide button (#31154) 2022-05-27 12:16:47 +05:30
HarryPaulo
a7bf236c28 fix(pos): freeze screen while processing pos invoices (#30850)
(cherry picked from commit 4b04694c2c)
2022-05-27 06:46:26 +00:00
mergify[bot]
d891394dc8 fix: Improve button labels in Warehouse (backport #31101) (#31150)
* style: format warehouse js

(cherry picked from commit c704ad889d)

* fix: improve labels, simplify logic

(cherry picked from commit a6ddd86d31)

* fix: german translations

(cherry picked from commit 9356eb11de)

* fix: remove unsupported arguments

Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
(cherry picked from commit e77c379cbb)

* refactor: set queries during setup

(cherry picked from commit 1b16eb7667)

* style: format

(cherry picked from commit 1e9f9c452f)

Co-authored-by: barredterra <14891507+barredterra@users.noreply.github.com>
2022-05-27 12:11:12 +05:30
mergify[bot]
a380bae298 fix: skip existing batch number during autogen (backport #31140) (#31144)
* fix: skip existing batch number during autogen (#31140)

* test: correctly check for existing item

* test: batch no for test PR generation

Co-authored-by: Ankush Menat <me@ankush.dev>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-26 20:55:29 +05:30
mergify[bot]
fd2f3b9061 feat: live preview of naming series on naming series tool (backport #31141) (#31146)
* chore: resave naming series doctype schema

separate commit to avoid mixing actual changes

(cherry picked from commit 82cd54b40b)

* feat: preview next numbers on naming series tool

(cherry picked from commit 24d1bf5328)

* docs: update help information on naming series

(cherry picked from commit 4d0e2aa33a)

* test: add basic tests for naming series tool

(cherry picked from commit 964b4184a6)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-26 17:10:49 +05:30
Rucha Mahabal
2ce90afa25 Merge pull request #31142 from frappe/mergify/bp/version-13-hotfix/pr-31130 2022-05-26 13:42:48 +05:30
Rucha Mahabal
096ae210e1 fix: validation message
(cherry picked from commit 2bc6d46070)
2022-05-26 07:54:35 +00:00
Rucha Mahabal
ec63912253 test: Job Opening against a Staffing Plan
(cherry picked from commit ab0ef60918)
2022-05-26 07:54:35 +00:00
Rucha Mahabal
b4a3a533c8 fix: Job Opening linked to Staffing Plan cannot be created/updated if there are existing employees
(cherry picked from commit 29228575fa)
2022-05-26 07:54:34 +00:00
Frappe PR Bot
91e935fee7 chore(release): Bumped to Version 13.31.0
# [13.31.0](https://github.com/frappe/erpnext/compare/v13.30.0...v13.31.0) (2022-05-26)

### Bug Fixes

* Account currency validation for first transaction ([228f10b](228f10bf30))
* Add party account validation for journal entry ([7f853b1](7f853b1f0f))
* always update item_name for stock entry (backport [#31068](https://github.com/frappe/erpnext/issues/31068)) ([#31071](https://github.com/frappe/erpnext/issues/31071)) ([f519dc6](f519dc613c))
* change project's actual_start_date fieldtype from Data to Date (backport [#31085](https://github.com/frappe/erpnext/issues/31085)) ([#31135](https://github.com/frappe/erpnext/issues/31135)) ([8c2f203](8c2f203361))
* Chart data for monthly periodicity in Cash Flow report ([#31039](https://github.com/frappe/erpnext/issues/31039)) ([f14e9b7](f14e9b7502))
* corrective job card creation (backport [#31083](https://github.com/frappe/erpnext/issues/31083)) ([#31084](https://github.com/frappe/erpnext/issues/31084)) ([c17c260](c17c260a65))
* don't capture payments with invoice_id as donations ([168a9d4](168a9d417b))
* employee advance status update on return via additional salary ([d59c3d2](d59c3d2142))
* Handle missing HSN Codes ([ce3a21e](ce3a21eb03))
* Healthcare module accounting test cases ([09a42a1](09a42a122f))
* **India:** Async issue in company address trigger ([2ea3318](2ea331852a))
* **india:** error while parsing e-invoice ([#31061](https://github.com/frappe/erpnext/issues/31061)) ([1461d66](1461d66dda))
* **india:** eway bill cancel api is disabled ([#31060](https://github.com/frappe/erpnext/issues/31060)) ([95491e1](95491e1718))
* Job Card excess transfer behaviour (backport [#31054](https://github.com/frappe/erpnext/issues/31054)) ([#31096](https://github.com/frappe/erpnext/issues/31096)) ([3984f04](3984f04a49))
* Leave Encashment calculations (backport [#31062](https://github.com/frappe/erpnext/issues/31062)) ([#31091](https://github.com/frappe/erpnext/issues/31091)) ([ba76b64](ba76b6419e))
* Loan Doc query in Bank Reconciliation Statement ([611d1af](611d1af526))
* Loan repayment entries for payroll payable account ([ea6d754](ea6d754f73))
* multiple entries for same payment term ([90b1147](90b1147365))
* Party account validation in JV ([d10c2e5](d10c2e50be))
* payments duplicate on pos closing entry (backport [#30976](https://github.com/frappe/erpnext/issues/30976)) ([#31005](https://github.com/frappe/erpnext/issues/31005)) ([0efbabe](0efbabe7cf))
* **pos:** paid amount calculation for multicurrency invoice ([#31122](https://github.com/frappe/erpnext/issues/31122)) ([98eb7da](98eb7da06a))
* remove bad default for Membership From Date ([34928d2](34928d29f1))
* Remove validation from Journal Entry ([4ca6cdc](4ca6cdca76))
* replace document states with list settings ([78e9e66](78e9e66d63))
* timesheet fetching in sales invoice ([216c32f](216c32f4bc))
* Use directly <a> and style it as button instead of using button ([0ab9fc0](0ab9fc0040))

### Features

* **Employee Advance:** add 'Returned' and 'Partly Claimed and Returned' status ([42e7a86](42e7a86a3b))

### Reverts

* Revert "fix: Add party account validation for journal entry" ([9d43a90](9d43a90eb0))
2022-05-26 05:38:49 +00:00
Deepesh Garg
63288fcd6c Merge pull request #31137 from frappe/version-13-hotfix
chore: Weekly release for version-13
2022-05-26 11:07:11 +05:30
mergify[bot]
8c2f203361 fix: change project's actual_start_date fieldtype from Data to Date (backport #31085) (#31135)
Co-authored-by: sersaber <93864988+sersaber@users.noreply.github.com>
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-26 10:32:10 +05:30
Deepesh Garg
0b0d57f7c2 Merge pull request #31128 from frappe/mergify/bp/version-13-hotfix/pr-26916
fix: Account currency validation for first transaction (backport #26916)
2022-05-26 09:41:19 +05:30
Deepesh Garg
5748af7d53 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-26916 2022-05-26 09:23:46 +05:30
Deepesh Garg
7df829f9cc chore: Update test case 2022-05-26 09:03:18 +05:30
Deepesh Garg
3d51d125bf chore: Update test case 2022-05-25 23:52:40 +05:30
Deepesh Garg
68d1787eeb Merge pull request #31124 from nextchamp-saqib/fix-timesheet-fetch
fix: timesheet fetching in sales invoice
2022-05-25 20:15:19 +05:30
Deepesh Garg
a61d7558eb Merge pull request #31132 from frappe/mergify/bp/version-13-hotfix/pr-31039
fix: Chart data for monthly periodicity in Cash Flow report (backport #31039)
2022-05-25 20:10:08 +05:30
Deepesh Garg
14422eaf59 chore: Update test cases 2022-05-25 20:06:31 +05:30
Deepesh Garg
4aed7eda91 Merge pull request #31131 from frappe/mergify/bp/version-13-hotfix/pr-31129
fix: Loan Doc query in Bank Reconciliation Statement (backport #31129)
2022-05-25 19:41:40 +05:30
xdlumertz
f14e9b7502 fix: Chart data for monthly periodicity in Cash Flow report (#31039)
fix: Chart data for monthly periodicity in Cash Flow report
(cherry picked from commit c5e922c76b)
2022-05-25 14:10:33 +00:00
Deepesh Garg
cd00cb2fb7 chore: Linting Issues
(cherry picked from commit 9e4a36089e)
2022-05-25 13:52:10 +00:00
Deepesh Garg
74ddf261e9 chore: Linting Issues
(cherry picked from commit a1f53f8d31)
2022-05-25 13:52:09 +00:00
Deepesh Garg
611d1af526 fix: Loan Doc query in Bank Reconciliation Statement
(cherry picked from commit 147fc8fde7)
2022-05-25 13:52:08 +00:00
Deepesh Garg
3fab8a2213 chore: Remove unintended changes 2022-05-25 19:20:09 +05:30
Deepesh Garg
f724f6d1bb chore: Resolve conflicts 2022-05-25 19:04:20 +05:30
Deepesh Garg
a5bd76bbb1 Merge pull request #31076 from frappe/mergify/bp/version-13-hotfix/pr-31004
fix: duplicate entries in payment terms report output (backport #31004)
2022-05-25 17:09:15 +05:30
Deepesh Garg
761669c7ca chore: Update test case
(cherry picked from commit bc34737709)

# Conflicts:
#	erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.py
2022-05-25 11:33:46 +00:00
Deepesh Garg
0628785c64 test: Update test cases
(cherry picked from commit 65232edfd5)

# Conflicts:
#	erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
#	erpnext/accounts/doctype/pricing_rule/test_pricing_rule.py
2022-05-25 11:33:45 +00:00
Deepesh Garg
4ca6cdca76 fix: Remove validation from Journal Entry
(cherry picked from commit 5b8726405d)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
2022-05-25 11:33:44 +00:00
Deepesh Garg
d10c2e50be fix: Party account validation in JV
(cherry picked from commit 417d6abcf4)

# Conflicts:
#	erpnext/accounts/doctype/journal_entry/journal_entry.py
2022-05-25 11:33:43 +00:00
Deepesh Garg
4727482737 test: Set default currency for patient
(cherry picked from commit 30876a105c)

# Conflicts:
#	erpnext/healthcare/doctype/patient_appointment/test_patient_appointment.py
2022-05-25 11:33:43 +00:00
Deepesh Garg
e28f6b7d31 test: fix property name
(cherry picked from commit c10a22529c)

# Conflicts:
#	erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
2022-05-25 11:33:42 +00:00
Deepesh Garg
8f969fbd66 test: Update test cases for currency change validation
(cherry picked from commit 60915e874d)

# Conflicts:
#	erpnext/accounts/doctype/period_closing_voucher/test_period_closing_voucher.py
#	erpnext/healthcare/doctype/patient_appointment/patient_appointment.py
#	erpnext/healthcare/doctype/therapy_plan/therapy_plan.py
#	erpnext/non_profit/doctype/membership/membership.py
2022-05-25 11:33:42 +00:00
Deepesh Garg
9d43a90eb0 Revert "fix: Add party account validation for journal entry"
This reverts commit f00620a3ca.

(cherry picked from commit 0a618817dc)
2022-05-25 11:33:39 +00:00
Deepesh Garg
09a42a122f fix: Healthcare module accounting test cases
(cherry picked from commit bcaf475295)

# Conflicts:
#	erpnext/healthcare/doctype/lab_test/test_lab_test.py
2022-05-25 11:33:39 +00:00
Deepesh Garg
7f853b1f0f fix: Add party account validation for journal entry
(cherry picked from commit f00620a3ca)
2022-05-25 11:33:38 +00:00
Deepesh Garg
228f10bf30 fix: Account currency validation for first transaction
(cherry picked from commit 80c85dd17c)

# Conflicts:
#	erpnext/controllers/accounts_controller.py
2022-05-25 11:33:38 +00:00
Deepesh Garg
3528d6fbdb Merge pull request #31121 from frappe/mergify/bp/version-13-hotfix/pr-31077
fix: Loan repayment entries for payroll payable account (backport #31077)
2022-05-25 12:37:17 +05:30
Deepesh Garg
2ae085d258 Merge pull request #31123 from deepeshgarg007/hsn_wise_tax_rate_none_type
fix: Handle missing HSN Codes
2022-05-25 12:34:26 +05:30
Deepesh Garg
187768892d Merge pull request #31120 from frappe/mergify/bp/version-13-hotfix/pr-31080
fix(India): Async issue in company address trigger (backport #31080)
2022-05-25 12:33:37 +05:30
mergify[bot]
98eb7da06a fix(pos): paid amount calculation for multicurrency invoice (#31122) 2022-05-25 12:24:09 +05:30
Saqib Ansari
216c32f4bc fix: timesheet fetching in sales invoice 2022-05-25 12:12:35 +05:30
Deepesh Garg
ce3a21eb03 fix: Handle missing HSN Codes 2022-05-25 11:51:07 +05:30
Deepesh Garg
ea6d754f73 fix: Loan repayment entries for payroll payable account
(cherry picked from commit 3128f9603e)
2022-05-25 05:54:08 +00:00
Deepesh Garg
559fc509e7 chore: Linting issues
(cherry picked from commit 8fd0b3b9f5)
2022-05-25 05:53:45 +00:00
Deepesh Garg
2ea331852a fix(India): Async issue in company address trigger
(cherry picked from commit c41f9f046f)
2022-05-25 05:53:45 +00:00
Rucha Mahabal
22aeacb088 Merge pull request #31104 from ruchamahabal/emp-adv-status-v13
feat(Employee Advance): add 'Returned' and 'Partly Claimed and Returned'
2022-05-25 11:09:52 +05:30
Rucha Mahabal
7ac0624f68 Merge branch 'version-13-hotfix' into emp-adv-status-v13 2022-05-25 10:46:25 +05:30
Rucha Mahabal
a071095886 Merge pull request #31110 from ruchamahabal/fix-npo-membership 2022-05-24 18:38:43 +05:30
Rucha Mahabal
168a9d417b fix: don't capture payments with invoice_id as donations
- if donations and subscriptions are set up in the same dashboard, membership payments also trigger payment webhook

- in order to differentiate there is already a check for RP's auto generated description but if subscriptions are configured using subscription links, RP doesn't send descriptions

- use invoice_id to ignore such payments instead
2022-05-24 18:16:56 +05:30
Rucha Mahabal
34928d29f1 fix: remove bad default for Membership From Date 2022-05-24 18:14:06 +05:30
Ankush Menat
e9968cc6fc chore: disable feed for material request 2022-05-24 14:33:57 +05:30
Rucha Mahabal
ab9744fe97 Merge branch 'version-13-hotfix' into emp-adv-status-v13 2022-05-24 11:49:24 +05:30
Rucha Mahabal
78e9e66d63 fix: replace document states with list settings 2022-05-24 11:29:58 +05:30
Rucha Mahabal
b265ca467c test: test advance filters in expense claim and cancelled status 2022-05-24 11:19:14 +05:30
Rucha Mahabal
806752111e test: employee advance status 2022-05-24 11:13:18 +05:30
Rucha Mahabal
d59c3d2142 fix: employee advance status update on return via additional salary 2022-05-24 11:11:44 +05:30
Rucha Mahabal
cac9e245b6 patch: Employee Advance return statuses 2022-05-24 11:11:10 +05:30
Rucha Mahabal
42e7a86a3b feat(Employee Advance): add 'Returned' and 'Partly Claimed and Returned' status 2022-05-24 11:09:42 +05:30
mergify[bot]
c2a08f1285 chore: error logging for auto material requests (backport #31103) (#31105)
chore: error logging for auto material requests (#31103)

(cherry picked from commit ecb39d81e0)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-24 10:41:50 +05:30
mergify[bot]
3984f04a49 fix: Job Card excess transfer behaviour (backport #31054) (#31096)
* fix: Job Card excess transfer behaviour

- Block excess transfer of items if not allowed in settings
- Behaviour made consistent with js behaviour (button disappears if not pending and not allowed in settings)
- Test for same case

(cherry picked from commit e07ce6efe0)

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

* chore: Run `_validate_over_transfer` only if excess transfer is blocked in settings

(cherry picked from commit 9f6e10663b)

* chore: conflicts

* chore: missing conflict resolution changes

Co-authored-by: marination <maricadsouza221197@gmail.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-23 15:20:47 +05:30
mergify[bot]
f6b2f36ca8 test: search test failing because of stale data (backport #31098) (#31099)
test: search test failing because of stale data (#31098)

(cherry picked from commit a36174afdf)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-23 15:13:13 +05:30
Suraj Shetty
1c3ad13f6c Merge pull request #31094 from frappe/mergify/bp/version-13-hotfix/pr-31092 2022-05-23 12:20:53 +05:30
mergify[bot]
ddee0893e6 fix translation German "Designation" (backport #31082) (#31093)
fix translation German "Designation" (#31082)

changed "Bezeichnung" to "Position" as the is more precice in the field of employment which erpnext refers to here

(cherry picked from commit 348a674df9)

Co-authored-by: Wolfram Schmidt <wolfram.schmidt@phamos.eu>
2022-05-23 12:02:30 +05:30
Suraj Shetty
0ab9fc0040 fix: Use directly <a> and style it as button instead of using button
Since few email servers (like outlook) strips out link in the button making them unclickable.

(cherry picked from commit a29b92febc)
2022-05-23 06:27:37 +00:00
mergify[bot]
ba76b6419e fix: Leave Encashment calculations (backport #31062) (#31091)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-23 10:32:41 +05:30
mergify[bot]
c17c260a65 fix: corrective job card creation (backport #31083) (#31084)
* test: simplify job card tests

(cherry picked from commit e625394488)

* fix: creation of corrective job card fails

This used to fail because sub_operations is a child table that's not
initalized by default till v13, in develop branch we init tables with
empty list.

(cherry picked from commit 66cf9aa344)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-21 14:28:27 +05:30
ruthra kumar
90b1147365 fix: multiple entries for same payment term
(cherry picked from commit e826093150)
2022-05-20 02:24:23 +00:00
mergify[bot]
f519dc613c fix: always update item_name for stock entry (backport #31068) (#31071)
fix: always update item_name for stock entry (#31068)

If item_name is already set and for some reason becomes outdated then
it's not updated in backend.

Fix: always set item_name and stock_uom when fetching item details
(cherry picked from commit 6d6616dbcd)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-19 16:02:20 +05:30
mergify[bot]
0efbabe7cf fix: payments duplicate on pos closing entry (backport #30976) (#31005) 2022-05-19 14:27:19 +05:30
mergify[bot]
1461d66dda fix(india): error while parsing e-invoice (#31061) 2022-05-18 12:44:24 +05:30
mergify[bot]
95491e1718 fix(india): eway bill cancel api is disabled (#31060) 2022-05-18 12:44:07 +05:30
Frappe PR Bot
d9f76478da chore(release): Bumped to Version 13.30.0
# [13.30.0](https://github.com/frappe/erpnext/compare/v13.29.2...v13.30.0) (2022-05-17)

### Bug Fixes

* `set_missing_values` in SE and re-use the same on all SE mappings ([fe52c1f](fe52c1f354))
* Add validation for SEZ and Export invoices without payment of taxes ([cb8453d](cb8453dac8))
* allow to use formatting for the field to_discuss in opportunity ([e126d4e](e126d4e592))
* Block 0 Qty via Update Items to be consistent with form validation ([5647875](56478752e4))
* Calculate totals even though pricing rule is not applied on mapped doc ([678a01d](678a01d4bd))
* **charts:** Pass fieldtype for chart data in selling reports ([917e7c3](917e7c34af))
* conflicts ([87fd933](87fd93370a))
* conflicts ([fb62bbf](fb62bbf61a))
* disable pricing rules for internal transfers (backport [#31034](https://github.com/frappe/erpnext/issues/31034)) ([#31036](https://github.com/frappe/erpnext/issues/31036)) ([d5eb9fb](d5eb9fb3fd))
* discount ledger entry in case of multicurrency invoice ([#31047](https://github.com/frappe/erpnext/issues/31047)) ([c3417e4](c3417e4103))
* dont fail repost for recoverable errors (backport [#30979](https://github.com/frappe/erpnext/issues/30979)) ([#31023](https://github.com/frappe/erpnext/issues/31023)) ([a019cb6](a019cb6caa))
* **Employee Advance:** Return/Deduction from Salary button visibility (backport [#31011](https://github.com/frappe/erpnext/issues/31011)) ([#31012](https://github.com/frappe/erpnext/issues/31012)) ([5b1d85e](5b1d85e8bf))
* Failing accounting dimension patch ([b14a7b8](b14a7b8a5d))
* german translations for Employee ([b9bda04](b9bda04a83))
* gl entry validation for miniscule loan penalty ([e958ef2](e958ef26e0))
* hide template items from sales/purchase order ([8b99f43](8b99f43c61))
* IN time not captured in Attendance through Employee Checkin (backport [#31029](https://github.com/frappe/erpnext/issues/31029)) ([#31031](https://github.com/frappe/erpnext/issues/31031)) ([477bbcc](477bbcc9e5))
* Item rate reset on changing posting date ([#30990](https://github.com/frappe/erpnext/issues/30990)) ([8ef649f](8ef649f65d))
* Just add one rate in GST HSN Code ([ed76687](ed76687dac))
* Merge Conflicts ([3abf264](3abf26428c))
* Multiple fixes in GSTR-1 report ([f2cbb70](f2cbb70325))
* **patch:** avoid checking for return field if it doesnt exits (backport [#30995](https://github.com/frappe/erpnext/issues/30995)) ([#30997](https://github.com/frappe/erpnext/issues/30997)) ([a94b5c0](a94b5c0d8b))
* per_billed for return DN (backport [#30868](https://github.com/frappe/erpnext/issues/30868)) ([#30971](https://github.com/frappe/erpnext/issues/30971)) ([97ea1f5](97ea1f5123))
* precision loss when transferring  (backport [#30834](https://github.com/frappe/erpnext/issues/30834)) ([#31032](https://github.com/frappe/erpnext/issues/31032)) ([fc80a50](fc80a50640))
* precision of total penalty paid ([ad21853](ad21853b01))
* precision of total penalty paid ([5c45737](5c45737a8f))
* prevent bypassing forced valuation rate (backport [#30987](https://github.com/frappe/erpnext/issues/30987)) ([#31020](https://github.com/frappe/erpnext/issues/31020)) ([706c19d](706c19db70))
* pro rata calculation for monthly depreciation ([#30989](https://github.com/frappe/erpnext/issues/30989)) ([408d952](408d952332))
* remove item attribute limit from variant selector (backport [#31026](https://github.com/frappe/erpnext/issues/31026)) ([#31028](https://github.com/frappe/erpnext/issues/31028)) ([1f016e9](1f016e9137))
* Set actual qty and basic rate in SE on warehouse triggers (`get_warehouse_details`) ([30b0aee](30b0aee013))
* stock analytics report shows incorrect data there's no stock movement in a period (backport [#30945](https://github.com/frappe/erpnext/issues/30945)) ([#30980](https://github.com/frappe/erpnext/issues/30980)) ([295ffb3](295ffb3f1a))
* translation for status filter ([e5f8231](e5f8231632))
* **translations:** Update ru translations ([#30992](https://github.com/frappe/erpnext/issues/30992)) ([f797005](f797005384))
* TypeError in add_indicator_for_multicompany (backport [#31042](https://github.com/frappe/erpnext/issues/31042)) ([#31048](https://github.com/frappe/erpnext/issues/31048)) ([e24bb1d](e24bb1dbf1))
* unlink Attendance from Employee Checkins on cancellation (backport [#31045](https://github.com/frappe/erpnext/issues/31045)) ([#31049](https://github.com/frappe/erpnext/issues/31049)) ([e03fe97](e03fe97a6e))
* UOM in HSN-wise summary of outward supply ([cd7d5cd](cd7d5cdb22))
* user can select disabled accounts in taxes table ([047c879](047c879bec))
* validate disabled accounts before posting ledger entries ([515e49b](515e49bb90))
* validate on hold purchase invoices in payment entry ([9fbd170](9fbd170fa4))

### Features

* add Employee Status filter in leave balance reports ([716b525](716b5253a4))
* add Link to Opportunity ([#30614](https://github.com/frappe/erpnext/issues/30614)) ([bc23bc7](bc23bc738e))
* request_for_quotation ([db4e264](db4e264d92))
* request_for_quotation - refactor ([b6a3e69](b6a3e693ae))
* select multiple values for accounting dimension (backport [#31015](https://github.com/frappe/erpnext/issues/31015)) ([#31041](https://github.com/frappe/erpnext/issues/31041)) ([9c21eb5](9c21eb5b94))
2022-05-17 07:41:35 +00:00
Ankush Menat
3f8816f2ce Merge pull request #31050 from ankush/v13_release
chore: release
2022-05-17 13:09:46 +05:30
mergify[bot]
e03fe97a6e fix: unlink Attendance from Employee Checkins on cancellation (backport #31045) (#31049)
* fix: unlink Attendance from Employee Checkins on cancellation (#31045)

(cherry picked from commit 28fe4f3d54)

* fix: import missing function

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-17 12:35:27 +05:30
mergify[bot]
c3417e4103 fix: discount ledger entry in case of multicurrency invoice (#31047) 2022-05-17 12:22:08 +05:30
mergify[bot]
9c21eb5b94 feat: select multiple values for accounting dimension (backport #31015) (#31041)
fix: select multiple values for accounting dimenssion

(cherry picked from commit 69be22ba7c)

Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
2022-05-17 11:56:31 +05:30
mergify[bot]
e24bb1dbf1 fix: TypeError in add_indicator_for_multicompany (backport #31042) (#31048)
fix: TypeError in add_indicator_for_multicompany (#31042)

Minor fix in add_indicator_for_multicompany

In case of multi-company transactions add (+) buttons in connection dashboard pf customer aren't being loaded due to TypeError (TypeError: e.dashboard.stats_area.removeClass is not a function) created by "frm.dashboard.stats_area.removeClass('hidden');" during the stats section creation.

(cherry picked from commit 867f2c6282)

Co-authored-by: Deepak <36790711+dpk404@users.noreply.github.com>
2022-05-17 11:54:50 +05:30
Ganga Manoj
408d952332 fix: pro rata calculation for monthly depreciation (#30989) 2022-05-17 11:21:10 +05:30
mergify[bot]
d5eb9fb3fd fix: disable pricing rules for internal transfers (backport #31034) (#31036)
fix: disable pricing rules for internal transfers (#31034)

* fix: disable pricing rules for internal transfers

* fix: only apply validation on internal transfers

* fix: internal_party_field undefined

(cherry picked from commit 3714e36b44)

Co-authored-by: Ankush Menat <me@ankush.dev>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-05-16 18:34:39 +05:30
Marica
d7bea97095 Merge pull request #31030 from frappe/mergify/bp/version-13-hotfix/pr-30992
fix(translations): Update ru translations (backport #30992)
2022-05-16 17:35:17 +05:30
Marica
3abf26428c fix: Merge Conflicts 2022-05-16 17:13:00 +05:30
mergify[bot]
477bbcc9e5 fix: IN time not captured in Attendance through Employee Checkin (backport #31029) (#31031)
* fix: IN time not captured in Attendance through Employee Checkin (#31029)

(cherry picked from commit 1b7ce9649b)

# Conflicts:
#	erpnext/hr/doctype/employee_checkin/test_employee_checkin.py

* fix: conflicts

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-16 17:05:26 +05:30
mergify[bot]
fc80a50640 fix: precision loss when transferring (backport #30834) (#31032)
* fix: stock transfer value when precision differs

(cherry picked from commit b1c90e9949)

# Conflicts:
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py

* fix: Merge conflicts

* chore: Remove unused `flt` (sider)

Co-authored-by: Ankush Menat <ankush@frappe.io>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-05-16 17:02:47 +05:30
Vladislav
f797005384 fix(translations): Update ru translations (#30992)
* fix incorrect translation

* Update ru.csv

* Update ru.csv

* Update erpnext/translations/ru.csv

Co-authored-by: Marica <maricadsouza221197@gmail.com>

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

# Conflicts:
#	erpnext/translations/ru.csv
2022-05-16 09:49:23 +00:00
mergify[bot]
1f016e9137 fix: remove item attribute limit from variant selector (backport #31026) (#31028)
fix: remove item attribute limit from variant selector

(cherry picked from commit 6bd1cb9235)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-16 14:13:38 +05:30
Marica
a0930a5619 Merge pull request #31027 from frappe/mergify/bp/version-13-hotfix/pr-31025
fix: hide template items from sales/purchase order (backport #31025)
2022-05-16 14:11:24 +05:30
Ankush Menat
8b99f43c61 fix: hide template items from sales/purchase order
(cherry picked from commit 0e875f5049)
2022-05-16 08:31:07 +00:00
mergify[bot]
a019cb6caa fix: dont fail repost for recoverable errors (backport #30979) (#31023)
recoverable erros:
1. timeout
2. lock/deadlocks

(cherry picked from commit 80d959c579)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-16 12:08:32 +05:30
mergify[bot]
6adeaa1de6 test: check translation files (backport #31006) (#31007)
This is an automatic backport of pull request #31006 done by [Mergify](https://mergify.com).


---


<details>
<summary>Mergify commands and options</summary>

<br />

More conditions and actions can be found in the [documentation](https://docs.mergify.com/).

You can also trigger Mergify actions by commenting on this pull request:

- `@Mergifyio refresh` will re-evaluate the rules
- `@Mergifyio rebase` will rebase this PR on its base branch
- `@Mergifyio update` will merge the base branch into this PR
- `@Mergifyio backport <destination>` will backport this PR on `<destination>` branch

Additionally, on Mergify [dashboard](https://dashboard.mergify.com/) you can:

- look at your merge queues
- generate the Mergify configuration with the config editor.

Finally, you can contact us on https://mergify.com
</details>
2022-05-16 06:13:32 +00:00
Deepesh Garg
e2028a0d6d Merge pull request #31021 from frappe/mergify/bp/version-13-hotfix/pr-31010
fix: GL entry validation for minuscule loan penalty (backport #31010)
2022-05-15 23:38:07 +05:30
mergify[bot]
706c19db70 fix: prevent bypassing forced valuation rate (backport #30987) (#31020)
fix: prevent bypassing forced valuation rate

if you edit "margin_rate_or_amount" after saving DN then based on
selected margin the rate gets updated which isn't valuation rate.

(cherry picked from commit ee0a277540)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-15 21:15:24 +05:30
Abhinav Raut
ad21853b01 fix: precision of total penalty paid
(cherry picked from commit 589dd17e58)
2022-05-15 15:21:09 +00:00
Abhinav Raut
5c45737a8f fix: precision of total penalty paid
(cherry picked from commit 9a86885c0a)
2022-05-15 15:21:09 +00:00
Abhinav Raut
e958ef26e0 fix: gl entry validation for miniscule loan penalty
(cherry picked from commit aef65e7417)
2022-05-15 15:21:08 +00:00
Deepesh Garg
c7f4a1595a Merge pull request #30978 from deepeshgarg007/gstr_export_sez_tax_rates
fix: Multiple fixes in GST reporting
2022-05-15 20:33:32 +05:30
Deepesh Garg
5b02b5b3cd chore: Remove unintended changes 2022-05-15 16:42:34 +05:30
Deepesh Garg
ed76687dac fix: Just add one rate in GST HSN Code 2022-05-15 16:40:33 +05:30
Deepesh Garg
c54c01e0de Merge branch 'version-13-hotfix' of https://github.com/frappe/erpnext into gstr_export_sez_tax_rates 2022-05-14 21:33:16 +05:30
Rucha Mahabal
c4650160ce Merge pull request #31014 from frappe/mergify/bp/version-13-hotfix/pr-31013 2022-05-13 22:33:48 +05:30
Rucha Mahabal
64b58ac031 test: employee status filter in leave balance reports
(cherry picked from commit 260cfa5d1e)
2022-05-13 16:37:57 +00:00
Rucha Mahabal
e5f8231632 fix: translation for status filter
(cherry picked from commit 08fb9a4318)
2022-05-13 16:37:56 +00:00
Rucha Mahabal
716b5253a4 feat: add Employee Status filter in leave balance reports
(cherry picked from commit ed8a49737a)
2022-05-13 16:37:56 +00:00
mergify[bot]
5b1d85e8bf fix(Employee Advance): Return/Deduction from Salary button visibility (backport #31011) (#31012)
fix(Employee Advance): Return/Deduction from Salary button visibility (#31011)

(cherry picked from commit 3016ed958e)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-13 20:06:26 +05:30
Deepesh Garg
cb8453dac8 fix: Add validation for SEZ and Export invoices without payment of taxes 2022-05-13 18:12:18 +05:30
Deepesh Garg
8af30bcc16 chore: Linting Issues 2022-05-13 18:12:18 +05:30
Deepesh Garg
cd7d5cdb22 fix: UOM in HSN-wise summary of outward supply 2022-05-13 18:12:18 +05:30
Frappe PR Bot
7369db59aa chore(release): Bumped to Version 13.29.0
# [13.29.0](https://github.com/frappe/erpnext/compare/v13.28.0...v13.29.0) (2022-05-10)

### Bug Fixes

* Consider paryt and party type as well in group by consolidated view ([189fc89](189fc89e2d))
* disable form save on naming series tool ([#30909](https://github.com/frappe/erpnext/issues/30909)) ([#30910](https://github.com/frappe/erpnext/issues/30910)) ([d60a6cb](d60a6cb2f8))
* double future qty updates ([0db3013](0db3013c9b))
* HSN-wise-summary of outward supplies Updated Report ([3637525](363752510e))
* Ignore loan repayments made from salary slip ([b7e1d40](b7e1d40e43))
* **india:** invoice type for a debit note e-invoice ([#30948](https://github.com/frappe/erpnext/issues/30948)) ([c46add3](c46add3760))
* **india:** keyerror while generating e-way bill from an e-invoice ([#30879](https://github.com/frappe/erpnext/issues/30879)) ([98d799e](98d799e7cc))
* **india:** re-arrange e-way bill dialog fields ([#30941](https://github.com/frappe/erpnext/issues/30941)) ([7ce5c93](7ce5c93f44))
* Item Alternative Test ([964de1f](964de1fc69))
* patch for renaming membership settings ([#30929](https://github.com/frappe/erpnext/issues/30929)) ([9189653](9189653f2e))
* **pos:** creating pos returns resets pricing rules & discounts ([#30936](https://github.com/frappe/erpnext/issues/30936)) ([a0e39db](a0e39db200))
* remove check for already allocated earned leaves ([#30931](https://github.com/frappe/erpnext/issues/30931)) ([#30932](https://github.com/frappe/erpnext/issues/30932)) ([80f7d66](80f7d66255))
* Remove commit from stock entry test. The assertion is not important ([c449b35](c449b35cc1))
* Set available-for-use date if missing ([#30838](https://github.com/frappe/erpnext/issues/30838)) ([bf2eaec](bf2eaecb1d))
* show group warehouse in Sales Order ([#30891](https://github.com/frappe/erpnext/issues/30891)) ([#30893](https://github.com/frappe/erpnext/issues/30893)) ([c458e14](c458e14e68))
* Show linked time sheets in sales invoice dashboard ([4f4af52](4f4af523e0))
* sort before picking next stock reco ([e27fb58](e27fb58130))
* subtract change_amount from paid_amount field on POS Register ([#30937](https://github.com/frappe/erpnext/issues/30937)) ([b7e873b](b7e873b55d))
* Unlink and delete batch created from stock reco on cancel ([fc35323](fc35323106))
* Wrap SLE actual_qty in `flt` to avoid NoneType operation ([d53228b](d53228b153))

### Features

* **HR:** Leave Type configuration to allow over allocation (backport [#30940](https://github.com/frappe/erpnext/issues/30940)) ([#30944](https://github.com/frappe/erpnext/issues/30944)) ([64440fc](64440fc4fb))
* **india:** cancel e-way bill is enabled with e-invoicing APIs. ([#30924](https://github.com/frappe/erpnext/issues/30924)) ([4ef2ffd](4ef2ffd14c))
* **india:** generate qrcode button for e-invoice ([#30946](https://github.com/frappe/erpnext/issues/30946)) ([7bd5b2b](7bd5b2ba29))
* **india:** store e-way bill auto calculated distance in sales invoice ([#30923](https://github.com/frappe/erpnext/issues/30923)) ([b96f156](b96f1565c5))
2022-05-13 18:12:18 +05:30
Frappe PR Bot
8cc2ea0ddb chore(release): Bumped to Version 13.28.0
# [13.28.0](https://github.com/frappe/erpnext/compare/v13.27.1...v13.28.0) (2022-05-03)

### Bug Fixes

* Consistent accounting dimensions across Sales and Purchase docs ([5df5058](5df50588cf))
* convert default_item_manufacturer to link field ([#30835](https://github.com/frappe/erpnext/issues/30835)) ([#30866](https://github.com/frappe/erpnext/issues/30866)) ([37fad7e](37fad7e04c))
* Cost center filter on payment reconciliation ([22e7f03](22e7f03a03))
* filters not working in Shift Assignment Calendar view ([#30822](https://github.com/frappe/erpnext/issues/30822)) ([3cdbb65](3cdbb65b5a))
* Ignore custom field validation while setup ([ee54bf7](ee54bf7fe2))
* **india:** e-invoice generation for registered composition gst category type ([#30814](https://github.com/frappe/erpnext/issues/30814)) ([#30877](https://github.com/frappe/erpnext/issues/30877)) ([246869d](246869dd28))
* Multi currency opening invoices ([2e62d51](2e62d518e8))
* payment days calculation for employees joining/leaving mid-month ([#30863](https://github.com/frappe/erpnext/issues/30863)) ([#30883](https://github.com/frappe/erpnext/issues/30883)) ([a1b0813](a1b0813966))
* Period Closing Voucher is considering GL entries with is_cancelled=1 ([#30865](https://github.com/frappe/erpnext/issues/30865)) ([5a5b49b](5a5b49b61a))
* **pos:** number pad translations ([b01f855](b01f8555e5))
* **pos:** search field doesn't reset on checkout ([edbf551](edbf5513da))
* Supply type for overseas invoices with payment of tax ([fdcc591](fdcc591a5e))
* supply type for sez invoices with payment of tax ([cf08710](cf087103cb))
* Use `account_type == 'Stock'` to filter stock accounts ([93482f3](93482f3302))
* **UX:** misleading stock entry lables ([#30870](https://github.com/frappe/erpnext/issues/30870)) ([#30871](https://github.com/frappe/erpnext/issues/30871)) ([57b03f0](57b03f0bf2))
* **UX:** record reason for skipping attendance or marking absent for auto attendance ([#30846](https://github.com/frappe/erpnext/issues/30846)) ([f7bf4a3](f7bf4a3e62))
* Vat Audit report fixes ([d5319a4](d5319a4826))

### Features

* Copy task color from project template (backport [#30857](https://github.com/frappe/erpnext/issues/30857)) ([#30859](https://github.com/frappe/erpnext/issues/30859)) ([7ee18e8](7ee18e86a2))
* support product bundles in picklist (backport [#30762](https://github.com/frappe/erpnext/issues/30762)) ([#30826](https://github.com/frappe/erpnext/issues/30826)) ([645ee2d](645ee2d822))
2022-05-13 18:12:18 +05:30
Frappe PR Bot
096dcf0e54 chore(release): Bumped to Version 13.27.1
## [13.27.1](https://github.com/frappe/erpnext/compare/v13.27.0...v13.27.1) (2022-04-26)

### Bug Fixes

* Add accounting dimensions for round off GL Entry ([dedb90e](dedb90ea72))
* batch_no filtering not working when batch no is also a number in scientific notation ([#30770](https://github.com/frappe/erpnext/issues/30770)) ([#30771](https://github.com/frappe/erpnext/issues/30771)) ([c339305](c339305e9c))
* Check if accounting dimension exists ([1834671](1834671d59))
* dependent gle reposting (backport [#30726](https://github.com/frappe/erpnext/issues/30726)) ([#30772](https://github.com/frappe/erpnext/issues/30772)) ([a6d0938](a6d0938591))
* Do not validate while creating accounting dimension ([153b41a](153b41a269))
* e_commerce_settings.js ([3a5f5d5](3a5f5d5cd0))
* e_commerce_settings.py ([86c5f4d](86c5f4db85))
* First preference to parent cost center rather than round off cost center ([a2d95fc](a2d95fc62b))
* Handle Multiselect field mapping separately ([dc2f694](dc2f694547))
* **india:** 401 & 403 client error while generating IRN ([198bdcf](198bdcfdc6))
* **india:** cess value not considered while validating e-invoice totals ([#30800](https://github.com/frappe/erpnext/issues/30800)) ([f70fca1](f70fca1c9e))
* **india:** transporter name is null while generating e-way bill ([#30736](https://github.com/frappe/erpnext/issues/30736)) ([6291b28](6291b28c37))
* linter ([6dddbb9](6dddbb9f27))
* Loan doctypes in bank reconciliation ([e69c715](e69c71576d))
* Mistyped variable name in patch ([e76220e](e76220e819))
* monthly attendance sheet ([#30748](https://github.com/frappe/erpnext/issues/30748)) ([0b4e3f1](0b4e3f1467))
* Must not be able to start Job Card if it is related to Work Order that is not started yet ([#29072](https://github.com/frappe/erpnext/issues/29072)) ([#30755](https://github.com/frappe/erpnext/issues/30755)) ([b656ffa](b656ffa45e))
* Query filter fields from Website Item instead of Item master ([bed9e09](bed9e09153))
* select doctype as payment_document ([44f0b69](44f0b69152))
* **Selling,E-Commerce:** Shopping cart quotation without website item. ([#29085](https://github.com/frappe/erpnext/issues/29085)) ([ea0fe5e](ea0fe5e10c))
* SO analysis rpt will fetch SO's without Delivery note as well ([f9d89c7](f9d89c7ce6))
* translation ([#30781](https://github.com/frappe/erpnext/issues/30781)) ([#30783](https://github.com/frappe/erpnext/issues/30783)) ([8335ca6](8335ca6331))
* Update token to allow updates on protected branch ([baab379](baab3797ca))
* update translation ([#30725](https://github.com/frappe/erpnext/issues/30725)) ([#30776](https://github.com/frappe/erpnext/issues/30776)) ([b585262](b585262842))
* Use parent cost center for Sales and Purchase Invoice ([fe9f329](fe9f32946c))
* Use right precision for asset value after full schedule ([#30745](https://github.com/frappe/erpnext/issues/30745)) ([269e192](269e1923c9))
* Validate field filter wrt to Website Item & re-use validation in Item Group ([34437a8](34437a83df))
2022-05-13 18:12:18 +05:30
Deepesh Garg
f2cbb70325 fix: Multiple fixes in GSTR-1 report 2022-05-13 18:12:18 +05:30
Deepesh Garg
7d8e3344e9 Merge pull request #31002 from frappe/mergify/bp/version-13-hotfix/pr-30990
fix: Item rate reset on changing posting date (backport #30990)
2022-05-13 14:44:04 +05:30
Marica
f7eb3ca1c0 Merge pull request #31000 from frappe/mergify/bp/version-13-hotfix/pr-30894
chore: added RFQ Link to Opportunity Dashboard (backport #30894)
2022-05-13 13:17:12 +05:30
Ankush Menat
0ec5adeed8 chore:conflicts 2022-05-13 13:14:08 +05:30
Marica
44d892fb70 Merge pull request #30999 from frappe/mergify/bp/version-13-hotfix/pr-30614
feat: add Link to Opportunity (backport #30614)
2022-05-13 13:12:50 +05:30
Frappe PR Bot
9ea017248d chore(release): Bumped to Version 13.29.2
## [13.29.2](https://github.com/frappe/erpnext/compare/v13.29.1...v13.29.2) (2022-05-13)

### Bug Fixes

* **patch:** avoid checking for return field if it doesnt exits (backport [#30995](https://github.com/frappe/erpnext/issues/30995)) ([#30997](https://github.com/frappe/erpnext/issues/30997)) ([752bda5](752bda5d84))
2022-05-13 07:41:38 +00:00
Ankush Menat
e392f6ce31 Merge branch 'version-13-pre-release' into version-13 2022-05-13 13:09:44 +05:30
mergify[bot]
752bda5d84 fix(patch): avoid checking for return field if it doesnt exits (backport #30995) (#30997)
(cherry picked from commit b08180092e)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-13 13:09:22 +05:30
Deepesh Garg
8ef649f65d fix: Item rate reset on changing posting date (#30990)
* fix: Item rate reset on changing posting date

* chore: Remove debugger

(cherry picked from commit 54d6cf18fc)

# Conflicts:
#	erpnext/public/js/controllers/transaction.js
2022-05-13 07:37:57 +00:00
mergify[bot]
a94b5c0d8b fix(patch): avoid checking for return field if it doesnt exits (backport #30995) (#30997)
(cherry picked from commit b08180092e)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-13 13:07:51 +05:30
Marica
a829072353 Merge pull request #31001 from frappe/mergify/bp/version-13-hotfix/pr-30911
fix: German translations for Employee doctype (backport #30911)
2022-05-13 12:55:11 +05:30
Marica
eb1245e9f8 Merge pull request #30998 from frappe/mergify/bp/version-13-hotfix/pr-30818
feat: request_for_quotation - show supplier name (backport #30818)
2022-05-13 12:24:02 +05:30
barredterra
b9bda04a83 fix: german translations for Employee
(cherry picked from commit 02b38a439f)
2022-05-13 06:54:02 +00:00
Wolfram Schmidt
24851a8577 chore: added RFQ Link to Opportunity Dashboard (#30894)
added Link to Dashboard

added backlink to Request for Quotation in the Quotation dashboard for transparency and ease of navigation.

(cherry picked from commit c4a2778359)
2022-05-13 06:48:34 +00:00
Wolfram Schmidt
bc23bc738e feat: add Link to Opportunity (#30614)
Adding Link to Opportunity

Following the process of Opportunity to Quotation I added a section and link field to Opportunity for a backlink when using "create"-> Request for Quotation from Opportunity.

(cherry picked from commit 0bbed414f8)
2022-05-13 06:48:08 +00:00
Ahmad
b6a3e693ae feat: request_for_quotation - refactor
- Set supplier as link in while selecting supplier to create quotation

(cherry picked from commit 04c96b547e)
2022-05-13 06:47:19 +00:00
Ahmad
db4e264d92 feat: request_for_quotation
- Show supplier name if supplier ID is not equal to supplier name

(cherry picked from commit b226e7d2ac)
2022-05-13 06:47:18 +00:00
Saqib Ansari
1ecbf33960 Merge pull request #30991 from frappe/mergify/bp/version-13-hotfix/pr-30968
fix(accounts): minor fixes & validations (backport #30968)
2022-05-13 12:03:52 +05:30
Saqib Ansari
013ac26231 test: sales_invoice_with_disabled_account
(cherry picked from commit 6c16422beb)
2022-05-12 16:37:27 +00:00
Saqib Ansari
7c750571cd test: payment_entry_against_onhold_purchase_invoice
(cherry picked from commit 92613777b9)
2022-05-12 16:37:26 +00:00
Saqib Ansari
515e49bb90 fix: validate disabled accounts before posting ledger entries
(cherry picked from commit 95b059a98c)
2022-05-12 16:37:26 +00:00
Saqib Ansari
047c879bec fix: user can select disabled accounts in taxes table
(cherry picked from commit a1e3ae8869)
2022-05-12 16:37:25 +00:00
Saqib Ansari
9fbd170fa4 fix: validate on hold purchase invoices in payment entry
(cherry picked from commit b0f302e579)
2022-05-12 16:37:24 +00:00
Frappe PR Bot
a89612e448 chore(release): Bumped to Version 13.29.1
## [13.29.1](https://github.com/frappe/erpnext/compare/v13.29.0...v13.29.1) (2022-05-12)

### Bug Fixes

* Failing accounting dimension patch ([b9a5575](b9a557599e))
2022-05-12 10:01:53 +00:00
Deepesh Garg
1def38dba0 Merge pull request #30985 from frappe/version-13-pre-release
chore: version-13 patch release
2022-05-12 15:29:21 +05:30
Deepesh Garg
bed1a218a2 Merge pull request #30984 from frappe/mergify/bp/version-13-pre-release/pr-30982
fix: Failing accounting dimension patch (backport #30982)
2022-05-12 15:28:05 +05:30
Deepesh Garg
b9a557599e fix: Failing accounting dimension patch
(cherry picked from commit b14a7b8a5d)
2022-05-12 09:48:53 +00:00
Deepesh Garg
43ebe946f1 Merge pull request #30982 from deepeshgarg007/failing_patch_for_dimensisons
fix: Failing accounting dimension patch
2022-05-12 14:57:01 +05:30
Deepesh Garg
b14a7b8a5d fix: Failing accounting dimension patch 2022-05-12 13:54:47 +05:30
mergify[bot]
295ffb3f1a fix: stock analytics report shows incorrect data there's no stock movement in a period (backport #30945) (#30980)
* test: basic test for stock analytics report

(cherry picked from commit d81422fb58)

* fix: consider previous balance is missing

Also remove `total`, total of total is a meaningless value.

(cherry picked from commit 6ab0046e9c)

* fix: batch_no doesn't maintain qty_after_transaction

(cherry picked from commit 287b255ad6)

* fix: only carry-forward balances till today's period

Showing data in future doesn't make sense. Only carry-forward till last
bucket that contains today's day.

(cherry picked from commit 198b91f8d4)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-05-12 13:06:52 +05:30
Marica
d697515125 Merge pull request #30975 from frappe/mergify/bp/version-13-hotfix/pr-30950
fix: Set actual qty and basic rate in SE on warehouse triggers (`get_warehouse_details`) (backport #30950)
2022-05-12 12:54:12 +05:30
marination
6ef1261afd test: Test for mapped SE and fix for failing tests
- Remove `set_missing_values` from mapper util function since a lot of item data is set after this function is run
- `split_batch` can skip `set_missing_values` since no warehouses are set on mapping and relies on user input

(cherry picked from commit 4fa15b50ca)
2022-05-11 14:44:42 +00:00
marination
fe52c1f354 fix: set_missing_values in SE and re-use the same on all SE mappings
- `set_missing_values` in SE will set actual qty, transfer qty and calculate rate/amount
- Re-use `set_missing_values` wherever SE is doc is being mapped

(cherry picked from commit 90a8e924f5)
2022-05-11 14:44:42 +00:00
marination
678a01d4bd fix: Calculate totals even though pricing rule is not applied on mapped doc
- `apply_pricing_rule` is triggered due to change in some data which most likely contributes to Total.

(cherry picked from commit 494ddd1eb4)
2022-05-11 14:44:38 +00:00
marination
30b0aee013 fix: Set actual qty and basic rate in SE on warehouse triggers (get_warehouse_details)
- set `actual_qty` on source and target warehouse change

(cherry picked from commit 1ce45f623e)
2022-05-11 14:44:37 +00:00
mergify[bot]
97ea1f5123 fix: per_billed for return DN (backport #30868) (#30971)
This is a semi-automatic backport of pull request #30868 done by [Mergify](https://mergify.com).
2022-05-11 14:33:58 +00:00
rohitwaghchaure
60964a48c4 Merge pull request #30947 from frappe/mergify/bp/version-13-hotfix/pr-30938
fix: allow to use formatting for the field to_discuss in opportunity (backport #30938)
2022-05-11 17:48:23 +05:30
rohitwaghchaure
87fd93370a fix: conflicts 2022-05-11 16:07:24 +05:30
rohitwaghchaure
fb62bbf61a fix: conflicts 2022-05-11 16:05:19 +05:30
Ankush Menat
b008efbfdb Merge pull request #30970 from frappe/mergify/bp/version-13-hotfix/pr-30969
chore: fifo queue vs qty after transaction comparison report (backport #30969)
2022-05-11 15:55:17 +05:30
Ankush Menat
78f694ca4e chore: incompatible changes 2022-05-11 15:22:33 +05:30
Ankush Menat
8c2bfe1d5c chore: fifo queue vs qty after transaction comparison report
(cherry picked from commit f6d6463a33)
2022-05-11 09:43:15 +00:00
Marica
c873950f41 Merge pull request #30967 from frappe/mergify/bp/version-13-hotfix/pr-30962
fix: Block 0 Qty via Update Items to be consistent with form validation (backport #30962)
2022-05-11 13:04:10 +05:30
marination
56478752e4 fix: Block 0 Qty via Update Items to be consistent with form validation
(cherry picked from commit 0c9154389b)
2022-05-11 07:12:29 +00:00
gavin
a761c5c62c Merge pull request #30961 from frappe/mergify/bp/version-13-hotfix/pr-30958
fix(charts): Pass fieldtype for chart data in selling reports (backport #30958)
2022-05-10 17:55:19 +05:30
Gavin D'souza
917e7c34af fix(charts): Pass fieldtype for chart data in selling reports
(cherry picked from commit 7bf0e4f8e5)
2022-05-10 12:10:48 +00:00
Frappe PR Bot
974f2a85ea chore(release): Bumped to Version 13.29.0
# [13.29.0](https://github.com/frappe/erpnext/compare/v13.28.0...v13.29.0) (2022-05-10)

### Bug Fixes

* Consider paryt and party type as well in group by consolidated view ([189fc89](189fc89e2d))
* disable form save on naming series tool ([#30909](https://github.com/frappe/erpnext/issues/30909)) ([#30910](https://github.com/frappe/erpnext/issues/30910)) ([d60a6cb](d60a6cb2f8))
* double future qty updates ([0db3013](0db3013c9b))
* HSN-wise-summary of outward supplies Updated Report ([3637525](363752510e))
* Ignore loan repayments made from salary slip ([b7e1d40](b7e1d40e43))
* **india:** invoice type for a debit note e-invoice ([#30948](https://github.com/frappe/erpnext/issues/30948)) ([c46add3](c46add3760))
* **india:** keyerror while generating e-way bill from an e-invoice ([#30879](https://github.com/frappe/erpnext/issues/30879)) ([98d799e](98d799e7cc))
* **india:** re-arrange e-way bill dialog fields ([#30941](https://github.com/frappe/erpnext/issues/30941)) ([7ce5c93](7ce5c93f44))
* Item Alternative Test ([964de1f](964de1fc69))
* patch for renaming membership settings ([#30929](https://github.com/frappe/erpnext/issues/30929)) ([9189653](9189653f2e))
* **pos:** creating pos returns resets pricing rules & discounts ([#30936](https://github.com/frappe/erpnext/issues/30936)) ([a0e39db](a0e39db200))
* remove check for already allocated earned leaves ([#30931](https://github.com/frappe/erpnext/issues/30931)) ([#30932](https://github.com/frappe/erpnext/issues/30932)) ([80f7d66](80f7d66255))
* Remove commit from stock entry test. The assertion is not important ([c449b35](c449b35cc1))
* Set available-for-use date if missing ([#30838](https://github.com/frappe/erpnext/issues/30838)) ([bf2eaec](bf2eaecb1d))
* show group warehouse in Sales Order ([#30891](https://github.com/frappe/erpnext/issues/30891)) ([#30893](https://github.com/frappe/erpnext/issues/30893)) ([c458e14](c458e14e68))
* Show linked time sheets in sales invoice dashboard ([4f4af52](4f4af523e0))
* sort before picking next stock reco ([e27fb58](e27fb58130))
* subtract change_amount from paid_amount field on POS Register ([#30937](https://github.com/frappe/erpnext/issues/30937)) ([b7e873b](b7e873b55d))
* Unlink and delete batch created from stock reco on cancel ([fc35323](fc35323106))
* Wrap SLE actual_qty in `flt` to avoid NoneType operation ([d53228b](d53228b153))

### Features

* **HR:** Leave Type configuration to allow over allocation (backport [#30940](https://github.com/frappe/erpnext/issues/30940)) ([#30944](https://github.com/frappe/erpnext/issues/30944)) ([64440fc](64440fc4fb))
* **india:** cancel e-way bill is enabled with e-invoicing APIs. ([#30924](https://github.com/frappe/erpnext/issues/30924)) ([4ef2ffd](4ef2ffd14c))
* **india:** generate qrcode button for e-invoice ([#30946](https://github.com/frappe/erpnext/issues/30946)) ([7bd5b2b](7bd5b2ba29))
* **india:** store e-way bill auto calculated distance in sales invoice ([#30923](https://github.com/frappe/erpnext/issues/30923)) ([b96f156](b96f1565c5))
2022-05-10 10:27:19 +00:00
Deepesh Garg
705a21a0f0 Merge pull request #30952 from frappe/version-13-pre-release
chore: Release for version-13
2022-05-10 15:55:39 +05:30
Ankush Menat
6863a59472 Merge branch 'version-13-hotfix' into version-13-pre-release 2022-05-10 15:20:35 +05:30
Ankush Menat
f64ba80913 Merge pull request #30953 from frappe/mergify/bp/version-13-hotfix/pr-30913
fix: double future qty updates (backport #30913)
2022-05-10 15:16:37 +05:30
mergify[bot]
b7e873b55d fix: subtract change_amount from paid_amount field on POS Register (#30937)
Co-authored-by: HarryPaulo <paulo_fabris@hotmail.com>
Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
2022-05-10 14:54:19 +05:30
Ankush Menat
4d682face2 chore: remove datettime formatting from debug report
This hides some information that would otherwise help during debugging

(cherry picked from commit ae842d8145)
2022-05-10 14:51:02 +05:30
Ankush Menat
6312938fed chore: conflicts 2022-05-10 14:50:35 +05:30
Ankush Menat
e27fb58130 fix: sort before picking next stock reco
(cherry picked from commit 7e2fbc050a)
2022-05-10 14:50:35 +05:30
Ankush Menat
0db3013c9b fix: double future qty updates
update_qty_in_future_sle is reprocessing rows which are already
processed by process_sle_against_current_voucher

(cherry picked from commit 7c839c4503)

# Conflicts:
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
2022-05-10 09:17:34 +00:00
Deepesh Garg
a85fe517df Merge pull request #30951 from frappe/version-13-hotfix
chore: Pre release for version-13
2022-05-10 14:42:16 +05:30
Deepesh Garg
3373ce5c47 Merge pull request #30949 from frappe/mergify/bp/version-13-hotfix/pr-30948
fix(india): invoice type for a debit note e-invoice (backport #30948)
2022-05-10 14:13:48 +05:30
Saqib Ansari
c46add3760 fix(india): invoice type for a debit note e-invoice (#30948)
(cherry picked from commit 8dd046cc51)
2022-05-10 08:10:34 +00:00
mergify[bot]
7bd5b2ba29 feat(india): generate qrcode button for e-invoice (#30946) 2022-05-10 12:29:52 +05:30
Rohit Waghchaure
e126d4e592 fix: allow to use formatting for the field to_discuss in opportunity
(cherry picked from commit 3f41cb762d)

# Conflicts:
#	erpnext/crm/doctype/opportunity/opportunity.py
#	erpnext/crm/doctype/opportunity/test_opportunity.py
2022-05-10 06:41:34 +00:00
mergify[bot]
64440fc4fb feat(HR): Leave Type configuration to allow over allocation (backport #30940) (#30944)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-10 09:25:32 +05:30
mergify[bot]
7ce5c93f44 fix(india): re-arrange e-way bill dialog fields (#30941) 2022-05-09 21:36:57 +05:30
Ankush Menat
c1f6586e39 Merge pull request #30869 from marination/batch-source-reference-v13
fix: Unlink and delete batch created from stock reco on cancel
2022-05-09 19:01:59 +05:30
mergify[bot]
a0e39db200 fix(pos): creating pos returns resets pricing rules & discounts (#30936) 2022-05-09 17:43:36 +05:30
mergify[bot]
80f7d66255 fix: remove check for already allocated earned leaves (#30931) (#30932)
* fix: remove check for already allocated earned leaves

* fix: do not set New Leaves Allocated field as read-only for earned leaves

- removing this until there's a better way to update existing allocations

(cherry picked from commit f92bc4dd33)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-09 12:34:21 +05:30
Rucha Mahabal
9189653f2e fix: patch for renaming membership settings (#30929) 2022-05-09 10:11:52 +05:30
Deepesh Garg
4e53dd71db Merge pull request #30065 from govindsmenokee/patch-9
fix: HSN-wise-summary of outward supplies Updated Report
2022-05-08 19:36:11 +05:30
mergify[bot]
4ef2ffd14c feat(india): cancel e-way bill is enabled with e-invoicing APIs. (#30924) 2022-05-08 19:11:04 +05:30
mergify[bot]
b96f1565c5 feat(india): store e-way bill auto calculated distance in sales invoice (#30923) 2022-05-08 19:10:22 +05:30
Saqib Ansari
713a84bb73 Merge branch 'version-13-hotfix' into patch-9 2022-05-08 12:49:28 +05:30
Saqib Ansari
2972ef8f2c chore: fix linter (#30925) 2022-05-08 12:48:57 +05:30
Deepesh Garg
a8fbd2451b chore: Remove print statement 2022-05-07 22:53:59 +05:30
Deepesh Garg
b0e929b8ae chore: Remove extra columns 2022-05-07 22:44:53 +05:30
Deepesh Garg
ac362c75db Merge branch 'version-13-hotfix' of https://github.com/frappe/erpnext into patch-9 2022-05-07 19:04:14 +05:30
Ganga Manoj
bf2eaecb1d fix: Set available-for-use date if missing (#30838) 2022-05-06 18:06:21 +05:30
Deepesh Garg
e9e2dcc1bf Merge pull request #30915 from frappe/mergify/bp/version-13-hotfix/pr-30897
fix: Consider party and party type as well in group by consolidated view (backport #30897)
2022-05-06 13:37:54 +05:30
Deepesh Garg
189fc89e2d fix: Consider paryt and party type as well in group by consolidated view
(cherry picked from commit c2d52a1ac0)
2022-05-06 07:40:39 +00:00
Deepesh Garg
4c2fdfe2c1 Merge pull request #30914 from deepeshgarg007/payment_reco_linting_issue
chore: Linting issues
2022-05-06 13:08:57 +05:30
Deepesh Garg
b7698aa210 chore: Linting issues 2022-05-06 13:08:09 +05:30
Deepesh Garg
96db9ee17b Merge pull request #30912 from frappe/mergify/bp/version-13-hotfix/pr-30879
fix(india): keyerror while generating e-way bill from an e-invoice (backport #30879)
2022-05-06 13:05:21 +05:30
maharshivpatel
98d799e7cc fix(india): keyerror while generating e-way bill from an e-invoice (#30879)
(cherry picked from commit ee7a7eb782)
2022-05-06 05:53:50 +00:00
mergify[bot]
d60a6cb2f8 fix: disable form save on naming series tool (#30909) (#30910)
(cherry picked from commit f31122cbc3)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-05 17:38:11 +05:30
marination
a2fff8741e style: Spaces to Tabs 2022-05-05 13:00:00 +05:30
mergify[bot]
c458e14e68 fix: show group warehouse in Sales Order (#30891) (#30893)
(cherry picked from commit 91cd5f5d4a)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-05 11:07:11 +05:30
Deepesh Garg
59686093b4 Merge pull request #30902 from frappe/mergify/bp/version-13-hotfix/pr-30899
fix: Show linked time sheets in sales invoice dashboard (backport #30899)
2022-05-04 21:01:08 +05:30
Deepesh Garg
4f4af523e0 fix: Show linked time sheets in sales invoice dashboard
(cherry picked from commit 3e38dc7ea8)
2022-05-04 14:24:57 +00:00
marination
c449b35cc1 fix: Remove commit from stock entry test. The assertion is not important 2022-05-04 13:00:00 +05:30
Deepesh Garg
57409b6ffd Merge pull request #30884 from deepeshgarg007/loan_repayment_clearance_v3
fix: Ignore loan repayments made from salary slip
2022-05-04 09:44:22 +05:30
Frappe PR Bot
53024be347 chore(release): Bumped to Version 13.28.0
# [13.28.0](https://github.com/frappe/erpnext/compare/v13.27.1...v13.28.0) (2022-05-03)

### Bug Fixes

* Consistent accounting dimensions across Sales and Purchase docs ([5df5058](5df50588cf))
* convert default_item_manufacturer to link field ([#30835](https://github.com/frappe/erpnext/issues/30835)) ([#30866](https://github.com/frappe/erpnext/issues/30866)) ([37fad7e](37fad7e04c))
* Cost center filter on payment reconciliation ([22e7f03](22e7f03a03))
* filters not working in Shift Assignment Calendar view ([#30822](https://github.com/frappe/erpnext/issues/30822)) ([3cdbb65](3cdbb65b5a))
* Ignore custom field validation while setup ([ee54bf7](ee54bf7fe2))
* **india:** e-invoice generation for registered composition gst category type ([#30814](https://github.com/frappe/erpnext/issues/30814)) ([#30877](https://github.com/frappe/erpnext/issues/30877)) ([246869d](246869dd28))
* Multi currency opening invoices ([2e62d51](2e62d518e8))
* payment days calculation for employees joining/leaving mid-month ([#30863](https://github.com/frappe/erpnext/issues/30863)) ([#30883](https://github.com/frappe/erpnext/issues/30883)) ([a1b0813](a1b0813966))
* Period Closing Voucher is considering GL entries with is_cancelled=1 ([#30865](https://github.com/frappe/erpnext/issues/30865)) ([5a5b49b](5a5b49b61a))
* **pos:** number pad translations ([b01f855](b01f8555e5))
* **pos:** search field doesn't reset on checkout ([edbf551](edbf5513da))
* Supply type for overseas invoices with payment of tax ([fdcc591](fdcc591a5e))
* supply type for sez invoices with payment of tax ([cf08710](cf087103cb))
* Use `account_type == 'Stock'` to filter stock accounts ([93482f3](93482f3302))
* **UX:** misleading stock entry lables ([#30870](https://github.com/frappe/erpnext/issues/30870)) ([#30871](https://github.com/frappe/erpnext/issues/30871)) ([57b03f0](57b03f0bf2))
* **UX:** record reason for skipping attendance or marking absent for auto attendance ([#30846](https://github.com/frappe/erpnext/issues/30846)) ([f7bf4a3](f7bf4a3e62))
* Vat Audit report fixes ([d5319a4](d5319a4826))

### Features

* Copy task color from project template (backport [#30857](https://github.com/frappe/erpnext/issues/30857)) ([#30859](https://github.com/frappe/erpnext/issues/30859)) ([7ee18e8](7ee18e86a2))
* support product bundles in picklist (backport [#30762](https://github.com/frappe/erpnext/issues/30762)) ([#30826](https://github.com/frappe/erpnext/issues/30826)) ([645ee2d](645ee2d822))
2022-05-03 08:51:32 +00:00
Deepesh Garg
a1f31013e2 Merge pull request #30886 from frappe/version-13-pre-release
chore: weekly release for version-13
2022-05-03 14:19:46 +05:30
Deepesh Garg
64d96f436b Merge pull request #30885 from frappe/version-13-hotfix
chore: pre release for version-13
2022-05-03 13:41:33 +05:30
Deepesh Garg
fda250606a Merge branch 'version-13-pre-release' into version-13-hotfix 2022-05-03 13:21:10 +05:30
Deepesh Garg
2126dee8ca Merge pull request #30874 from frappe/mergify/bp/version-13-hotfix/pr-30848
fix: Cost center filter in payment reconciliation (backport #30848)
2022-05-03 13:18:31 +05:30
marination
d53228b153 fix: Wrap SLE actual_qty in flt to avoid NoneType operation
- Since Batch cancellation SLEs do not set qtys (will fix separately), `merge_similar_entries` gets `actual_qty` as None
- This causes NoneType operation error on tests that cancel batch-serial reco
- Modified tests to avoid using commit and rollback explicitly
2022-05-03 13:00:00 +05:30
Deepesh Garg
b7e1d40e43 fix: Ignore loan repayments made from salary slip 2022-05-03 12:55:04 +05:30
Deepesh Garg
937d358fbf Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30848 2022-05-03 12:46:10 +05:30
Deepesh Garg
366cd6171c chore: resolve conflicts 2022-05-03 12:21:06 +05:30
mergify[bot]
a1b0813966 fix: payment days calculation for employees joining/leaving mid-month (#30863) (#30883)
(cherry picked from commit 924cf7763e)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-05-03 11:46:46 +05:30
Saqib Ansari
4db588e72e Merge pull request #30876 from frappe/mergify/bp/version-13-hotfix/pr-30875
fix(India): Supply type for overseas invoices with payment of tax (backport #30875)
2022-05-02 22:17:56 +05:30
mergify[bot]
246869dd28 fix(india): e-invoice generation for registered composition gst category type (#30814) (#30877) 2022-05-02 22:16:43 +05:30
Saqib Ansari
cf087103cb fix: supply type for sez invoices with payment of tax
(cherry picked from commit c8aa77285e)
2022-05-02 16:20:44 +00:00
Deepesh Garg
fdcc591a5e fix: Supply type for overseas invoices with payment of tax
(cherry picked from commit d7cb269e0c)
2022-05-02 16:20:44 +00:00
Deepesh Garg
0df96e1084 test: Add test for payment reconciliation
(cherry picked from commit b440dabe12)
2022-05-02 12:29:25 +00:00
Deepesh Garg
22e7f03a03 fix: Cost center filter on payment reconciliation
(cherry picked from commit ab94b73e93)

# Conflicts:
#	erpnext/accounts/doctype/payment_reconciliation/payment_reconciliation.js
2022-05-02 12:29:24 +00:00
Deepesh Garg
6aab9ca427 Merge pull request #30852 from deepeshgarg007/vat_ksa
fix: Vat Audit report fixes
2022-05-02 16:14:03 +05:30
mergify[bot]
57b03f0bf2 fix(UX): misleading stock entry lables (#30870) (#30871)
* fix(UX): misleading stock entry lables

* chore: field labels

[skip ci]

Co-authored-by: Marica <maricadsouza221197@gmail.com>

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

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-02 15:17:13 +05:30
Sherin KR
5a5b49b61a fix: Period Closing Voucher is considering GL entries with is_cancelled=1 (#30865)
* fix: Period Closing Voucher - Period Closing Voucher is considering GL entry with is_cancelled=1 as well

* fix: condition

Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
2022-05-02 15:03:30 +05:30
mergify[bot]
37fad7e04c fix: convert default_item_manufacturer to link field (#30835) (#30866)
(cherry picked from commit dcda55641b)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-05-02 14:58:05 +05:30
marination
964de1fc69 fix: Item Alternative Test 2022-05-02 14:44:26 +05:30
marination
5bc5af1066 chore: Tests for Stock Reconciliation 2022-05-02 14:41:08 +05:30
marination
a144548db9 chore: Tests for Stock Entry 2022-05-02 14:18:54 +05:30
marination
fc35323106 fix: Unlink and delete batch created from stock reco on cancel 2022-05-02 14:18:27 +05:30
Deepesh Garg
7c0069c0d3 chore: Education domain deprecation warning (#30861)
* chore: Education domain deprecation warning

* chore: Education domain deprecation warning

* chore: Rename file and patch
2022-05-02 13:29:25 +05:30
Deepesh Garg
0b9a59c605 Merge pull request #30856 from frappe/mergify/bp/version-13-hotfix/pr-30806
fix: Consistent accounting dimensions across Sales and Purchase docs (backport #30806)
2022-05-02 11:44:52 +05:30
Deepesh Garg
b9c326e3f6 chore: resolve conflicts 2022-05-02 11:16:48 +05:30
Deepesh Garg
d9756d54ad chore: resolve conflicts 2022-05-02 11:15:58 +05:30
mergify[bot]
7ee18e86a2 feat: Copy task color from project template (backport #30857) (#30859)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
Co-authored-by: sersaber <93864988+sersaber@users.noreply.github.com>
2022-05-02 10:59:58 +05:30
Deepesh Garg
5df50588cf fix: Consistent accounting dimensions across Sales and Purchase docs
(cherry picked from commit 82a0635c66)

# Conflicts:
#	erpnext/patches.txt
#	erpnext/selling/doctype/sales_order/sales_order.json
2022-05-01 16:33:16 +00:00
Deepesh Garg
87383680f0 Merge pull request #30853 from frappe/mergify/bp/version-13-hotfix/pr-30815
fix: Ignore custom field validation while setup (backport #30815)
2022-05-01 15:22:57 +05:30
Deepesh Garg
ee54bf7fe2 fix: Ignore custom field validation while setup
(cherry picked from commit 67bb29026f)
2022-04-30 16:33:44 +00:00
Deepesh Garg
d5319a4826 fix: Vat Audit report fixes 2022-04-30 22:01:05 +05:30
Deepesh Garg
a98263cd31 Merge pull request #30845 from frappe/mergify/bp/version-13-hotfix/pr-30843
fix: Multi currency opening invoices (backport #30843)
2022-04-29 23:04:03 +05:30
Deepesh Garg
a3de0320aa Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30843 2022-04-29 22:16:52 +05:30
Rucha Mahabal
f7bf4a3e62 fix(UX): record reason for skipping attendance or marking absent for auto attendance (#30846) 2022-04-29 16:37:26 +05:30
Deepesh Garg
2e62d518e8 fix: Multi currency opening invoices
(cherry picked from commit a8452c2ba2)
2022-04-29 09:46:34 +00:00
mergify[bot]
731107d0a3 test: create new item instead of using with _Test Item (backport #30827) (#30829)
This is an automatic backport of pull request #30827 done by [Mergify](https://mergify.com).


---


<details>
<summary>Mergify commands and options</summary>

<br />

More conditions and actions can be found in the [documentation](https://docs.mergify.com/).

You can also trigger Mergify actions by commenting on this pull request:

- `@Mergifyio refresh` will re-evaluate the rules
- `@Mergifyio rebase` will rebase this PR on its base branch
- `@Mergifyio update` will merge the base branch into this PR
- `@Mergifyio backport <destination>` will backport this PR on `<destination>` branch

Additionally, on Mergify [dashboard](https://dashboard.mergify.com/) you can:

- look at your merge queues
- generate the Mergify configuration with the config editor.

Finally, you can contact us on https://mergify.com
</details>
2022-04-28 10:58:24 +00:00
mergify[bot]
645ee2d822 feat: support product bundles in picklist (backport #30762) (#30826)
* refactor: misc pick list refactors

- make tracking fields read only and no-copy 🤦
- collapse print settings section, most users configure it once and
  forget about it, not need to show this.
- call pick list grouping function directly
- use get_descendants_of instead of obscure db function

(cherry picked from commit 5c3f9019cc)

* test: bundles in picklist

(cherry picked from commit 7d5682020a)

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

* feat: Pick list from SO with Product Bundle

(cherry picked from commit 36c5e8a14f)

* refactor: sales order status update

- rename badly named variables
- support updated packed items

(cherry picked from commit e64cc66df7)

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

* perf: single update per Sales Order.

For each SO item the sales order picking status was being updated, this
isn't required and wasteful.

(cherry picked from commit c3fc0a4f55)

* feat: back-update min picked qty for a bundle

(cherry picked from commit 60bc26fdbe)

* refactor: simplify needlessly complicated code

(cherry picked from commit 3ddad6891a)

* refactor: groupby using keys instead of int index

(cherry picked from commit 277b51b404)

* refactor: simpler check for non-SO items

(cherry picked from commit f574121741)

* feat: create DN from pick list with bundle items

(cherry picked from commit 23cb0d684d)

* refactor: remove unnecssary vars

also remove misleading docstring

(cherry picked from commit 25485edfd9)

* fix: round off bundle qty

This is to accomodate bundles that might allow floating point qty.

(cherry picked from commit 41aa4b3524)

* feat: transfer picklist stock info to packing list

(cherry picked from commit 1ac275ce61)

* test: product bundle fixture

(cherry picked from commit ee54ece8fd)

* test: test bundle - picklist behaviour

(cherry picked from commit 9e60acdf56)

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

* fix: compare against stock qty while validating

Other changes:

- only allow whole number of bundles to get picked

(cherry picked from commit 8207697e43)

* fix: dont map picked qty and consider pick qty for new PL

Co-Authored-By: marination <maricadsouza221197@gmail.com>
(cherry picked from commit 47e1a0104c)

* fix(UX): only show pick list when picking is pending

[skip ci]

(cherry picked from commit 9a8e3ef235)

* chore: make picked qty read only

(cherry picked from commit ebd5f0b1bb)

* chore: conflicts and py3.7 compatibilty

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-27 17:08:37 +05:30
mergify[bot]
b45db347cc ci: failfast when merge conflict exists (#30823) (#30824)
[skip ci]

(cherry picked from commit 3ae9fa98c4)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-27 14:45:21 +05:30
Rucha Mahabal
3cdbb65b5a fix: filters not working in Shift Assignment Calendar view (#30822) 2022-04-27 14:44:25 +05:30
Saqib Ansari
f693d43cda Merge pull request #30809 from frappe/mergify/bp/version-13-hotfix/pr-30808
fix(pos): search field doesn't reset on checkout (backport #30808)
2022-04-27 14:15:07 +05:30
Ankush Menat
b33317e987 chore: format 2022-04-26 18:44:03 +05:30
Ankush Menat
980a87417b Merge pull request #30812 from frappe/mergify/bp/version-13-hotfix/pr-30811
chore: Warn users about multiple warehouse accounts (backport #30811)
2022-04-26 18:42:10 +05:30
marination
93482f3302 fix: Use account_type == 'Stock' to filter stock accounts
(cherry picked from commit e2a163d4e9)
2022-04-26 12:49:00 +00:00
marination
38fbd94ac9 chore: Warn users about multiple warehouse accounts
- Get distinct accounts that warehouse value has been booked against
- If same account as the one being set, ignore
- If not same account or multiple accounts: warn user that it makes it harder to track mismatches

(cherry picked from commit 44331f4f1f)
2022-04-26 12:49:00 +00:00
Saqib Ansari
b01f8555e5 fix(pos): number pad translations
(cherry picked from commit b1ac5ff9d2)
2022-04-26 09:18:11 +00:00
Saqib Ansari
edbf5513da fix(pos): search field doesn't reset on checkout
(cherry picked from commit 03a6103fe5)
2022-04-26 09:18:11 +00:00
Frappe PR Bot
b77b3780d6 chore(release): Bumped to Version 13.27.1
## [13.27.1](https://github.com/frappe/erpnext/compare/v13.27.0...v13.27.1) (2022-04-26)

### Bug Fixes

* Add accounting dimensions for round off GL Entry ([dedb90e](dedb90ea72))
* batch_no filtering not working when batch no is also a number in scientific notation ([#30770](https://github.com/frappe/erpnext/issues/30770)) ([#30771](https://github.com/frappe/erpnext/issues/30771)) ([c339305](c339305e9c))
* Check if accounting dimension exists ([1834671](1834671d59))
* dependent gle reposting (backport [#30726](https://github.com/frappe/erpnext/issues/30726)) ([#30772](https://github.com/frappe/erpnext/issues/30772)) ([a6d0938](a6d0938591))
* Do not validate while creating accounting dimension ([153b41a](153b41a269))
* e_commerce_settings.js ([3a5f5d5](3a5f5d5cd0))
* e_commerce_settings.py ([86c5f4d](86c5f4db85))
* First preference to parent cost center rather than round off cost center ([a2d95fc](a2d95fc62b))
* Handle Multiselect field mapping separately ([dc2f694](dc2f694547))
* **india:** 401 & 403 client error while generating IRN ([198bdcf](198bdcfdc6))
* **india:** cess value not considered while validating e-invoice totals ([#30800](https://github.com/frappe/erpnext/issues/30800)) ([f70fca1](f70fca1c9e))
* **india:** transporter name is null while generating e-way bill ([#30736](https://github.com/frappe/erpnext/issues/30736)) ([6291b28](6291b28c37))
* linter ([6dddbb9](6dddbb9f27))
* Loan doctypes in bank reconciliation ([e69c715](e69c71576d))
* Mistyped variable name in patch ([e76220e](e76220e819))
* monthly attendance sheet ([#30748](https://github.com/frappe/erpnext/issues/30748)) ([0b4e3f1](0b4e3f1467))
* Must not be able to start Job Card if it is related to Work Order that is not started yet ([#29072](https://github.com/frappe/erpnext/issues/29072)) ([#30755](https://github.com/frappe/erpnext/issues/30755)) ([b656ffa](b656ffa45e))
* Query filter fields from Website Item instead of Item master ([bed9e09](bed9e09153))
* select doctype as payment_document ([44f0b69](44f0b69152))
* **Selling,E-Commerce:** Shopping cart quotation without website item. ([#29085](https://github.com/frappe/erpnext/issues/29085)) ([ea0fe5e](ea0fe5e10c))
* SO analysis rpt will fetch SO's without Delivery note as well ([f9d89c7](f9d89c7ce6))
* translation ([#30781](https://github.com/frappe/erpnext/issues/30781)) ([#30783](https://github.com/frappe/erpnext/issues/30783)) ([8335ca6](8335ca6331))
* Update token to allow updates on protected branch ([baab379](baab3797ca))
* update translation ([#30725](https://github.com/frappe/erpnext/issues/30725)) ([#30776](https://github.com/frappe/erpnext/issues/30776)) ([b585262](b585262842))
* Use parent cost center for Sales and Purchase Invoice ([fe9f329](fe9f32946c))
* Use right precision for asset value after full schedule ([#30745](https://github.com/frappe/erpnext/issues/30745)) ([269e192](269e1923c9))
* Validate field filter wrt to Website Item & re-use validation in Item Group ([34437a8](34437a83df))
2022-04-26 07:52:13 +00:00
Deepesh Garg
016839e573 Merge pull request #30805 from frappe/version-13-pre-release
chore: version 13 release
2022-04-26 13:17:29 +05:30
Deepesh Garg
25bc10e0a9 Merge branch 'version-13' into version-13-pre-release 2022-04-26 12:32:06 +05:30
Deepesh Garg
87ec9cd0cc Merge pull request #30804 from frappe/version-13-hotfix
chore: version 13 pre release
2022-04-26 12:25:25 +05:30
Deepesh Garg
2f42cb6362 Merge branch 'version-13-pre-release' into version-13-hotfix 2022-04-26 11:47:34 +05:30
Deepesh Garg
30d1cecf60 Merge pull request #30801 from frappe/mergify/bp/version-13-hotfix/pr-30754
fix: First preference to parent cost center rather than round off cost center (backport #30754)
2022-04-25 17:28:55 +05:30
Deepesh Garg
4522826335 test: Unit test for round off entry dimensions
(cherry picked from commit 3fa1c63479)
2022-04-25 11:37:13 +00:00
Deepesh Garg
1834671d59 fix: Check if accounting dimension exists
(cherry picked from commit c312cd3725)
2022-04-25 11:37:13 +00:00
Deepesh Garg
dedb90ea72 fix: Add accounting dimensions for round off GL Entry
(cherry picked from commit 015812b0b8)
2022-04-25 11:37:12 +00:00
Deepesh Garg
fe9f32946c fix: Use parent cost center for Sales and Purchase Invoice
(cherry picked from commit c42547d40f)
2022-04-25 11:37:12 +00:00
Deepesh Garg
a2d95fc62b fix: First preference to parent cost center rather than round off cost center
(cherry picked from commit 0ac11a5b30)
2022-04-25 11:37:11 +00:00
mergify[bot]
f70fca1c9e fix(india): cess value not considered while validating e-invoice totals (#30800)
(cherry picked from commit 8e6c7a6bf7)

Co-authored-by: Saqib Ansari <nextchamp.saqib@gmail.com>
2022-04-25 15:08:09 +05:30
Deepesh Garg
30bf48e1db Merge pull request #30798 from frappe/mergify/bp/version-13-hotfix/pr-30778
fix: Do not validate while creating accounting dimension (backport #30778)
2022-04-25 14:08:13 +05:30
Deepesh Garg
153b41a269 fix: Do not validate while creating accounting dimension
(cherry picked from commit 9bb132fdd3)
2022-04-25 07:01:28 +00:00
Deepesh Garg
d99cc8b05a Merge pull request #30794 from frappe/mergify/bp/version-13-hotfix/pr-30763
fix: Add loan doctypes in bank clearance (backport #30763)
2022-04-25 08:51:50 +05:30
Deepesh Garg
12f5d65271 test: Remove teardown method
(cherry picked from commit c515abc392)
2022-04-24 15:26:13 +00:00
Deepesh Garg
57485b30b8 test: Fixes in test case
(cherry picked from commit d4d83f4bb6)
2022-04-24 15:26:12 +00:00
Deepesh Garg
1a74c6ee56 test: Fixes in test case
(cherry picked from commit 0eacc99ab7)
2022-04-24 15:26:12 +00:00
Deepesh Garg
728ac1f54e test: Add test coverage for bank clearance
(cherry picked from commit 8a8476bb5c)
2022-04-24 15:26:12 +00:00
Deepesh Garg
44f0b69152 fix: select doctype as payment_document
(cherry picked from commit 3d0e68acaa)
2022-04-24 15:26:11 +00:00
Deepesh Garg
e69c71576d fix: Loan doctypes in bank reconciliation
(cherry picked from commit c3e27b5556)
2022-04-24 15:26:11 +00:00
Deepesh Garg
664a2989a6 Merge pull request #30773 from frappe/mergify/bp/version-13-hotfix/pr-30757
fix(india): 401 & 403 client error while generating IRN (backport #30757)
2022-04-22 19:47:19 +05:30
mergify[bot]
8335ca6331 fix: translation (#30781) (#30783)
fixed the short word for March in german language

(cherry picked from commit 43c1d63ab2)

Co-authored-by: Wolfram Schmidt <wolfram.schmidt@phamos.eu>
2022-04-22 17:39:15 +05:30
Devin Slauenwhite
ea0fe5e10c fix(Selling,E-Commerce): Shopping cart quotation without website item. (#29085)
* test: assert error if quotation contains non website item

* fix(test): validate exception without website item

* fix: shopping cart quotation without website item

* fix: sider issues

* fix: linter trilaing whitespace

* fix: linter format string after translation

* fix: Skip unpublished Variants with published templates in shopping cart quote validation

* style: Re-run pre-commit

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-04-22 17:19:29 +05:30
Saqib Ansari
6dddbb9f27 fix: linter 2022-04-22 14:15:21 +05:30
Deepesh Garg
a074d12afd Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30757 2022-04-22 13:20:09 +05:30
Deepesh Garg
712443a91c chore: Resolve conflicts 2022-04-22 11:48:07 +05:30
mergify[bot]
b585262842 fix: update translation (#30725) (#30776)
* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

(cherry picked from commit e088e65871)

Co-authored-by: Vladislav <integration.into.society@gmail.com>
2022-04-22 11:18:29 +05:30
mergify[bot]
a6d0938591 fix: dependent gle reposting (backport #30726) (#30772)
* refactor: repost error handling

(cherry picked from commit afc5a55a23)

* test: dependent GL entry reposting

(cherry picked from commit a2af2daca7)

# Conflicts:
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py

* fix: dependent GLE reposting

(cherry picked from commit ecdb49314f)

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

* test: repost queue progress

(cherry picked from commit 8f519545b0)

* test: use disposable item codes in tests

dependency causes flake

(cherry picked from commit d2882ea436)

* fix: correct sorting while updating bin

(cherry picked from commit b24920c0e9)

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

* fix: sort stock vouchers before reposting GLE

(cherry picked from commit 700e864d90)

* test: discard local future SLE cache between tests

(cherry picked from commit 9734329094)

* chore: conflicts

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-21 19:27:23 +05:30
Saqib Ansari
198bdcfdc6 fix(india): 401 & 403 client error while generating IRN
(cherry picked from commit ee8047aba3)

# Conflicts:
#	erpnext/regional/india/e_invoice/utils.py
2022-04-21 13:26:05 +00:00
Deepesh Garg
32cff94bde chore: Remove conflicts from Sales Order Analysis report (#30761)
* fix: Remove conflicts from Sales Order Analysis report

* fix: change field to duration and fetch elapsed seconds

* chore: Ignore linting check for sql query
2022-04-21 18:31:35 +05:30
mergify[bot]
c339305e9c fix: batch_no filtering not working when batch no is also a number in scientific notation (#30770) (#30771)
[skip ci]

(cherry picked from commit ee3036651a)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-21 16:39:24 +05:30
Marica
ac433dce2a Merge pull request #30179 from MostafaFekry/patch-4
fix: Filter fields in E Commerce Settings (use Website Item)
2022-04-21 14:36:20 +05:30
Marica
d8944b0499 Merge branch 'version-13-hotfix' into patch-4 2022-04-21 12:32:17 +05:30
marination
f58d3b4d3d test: setup e commerce settings before running invalid filtrs test 2022-04-21 12:31:16 +05:30
Ganga Manoj
269e1923c9 fix: Use right precision for asset value after full schedule (#30745) 2022-04-20 19:44:09 +05:30
marination
ba635145da test: Field filter validation and Custom field as field filter
- Test to block Item fields (which aren’t in Website Item) in E Commerce Settings as filters
- Removed unnecessary function and setup in E Commerce Settings test
- Removed commented useless test
- Test to check custom field as filter
2022-04-20 18:54:30 +05:30
marination
dc2f694547 fix: Handle Multiselect field mapping separately
- Map Multiselect child table to Website Item (copy rows)
2022-04-20 17:47:14 +05:30
mergify[bot]
b656ffa45e fix: Must not be able to start Job Card if it is related to Work Order that is not started yet (#29072) (#30755)
* fix: Cannot start Job strat if related to Work Order not started yet

* fix: Cannot start Job strat if related to Work Order not started yet

* test

* test

* fix siders

* PR review

* chore: Code cleanup

- Better short circuit for if condition (make it such that both conditions dont always have to be computed)
- Remove `r.message` extraction by avoiding `then()`

* chore: Remove unnecessary json change

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

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2022-04-20 15:11:11 +05:30
Raffael Meyer
0b4e3f1467 fix: monthly attendance sheet (#30748) 2022-04-20 12:29:45 +05:30
marination
e76220e819 fix: Mistyped variable name in patch 2022-04-20 12:27:04 +05:30
mergify[bot]
77e8c542dd chore: Update creds to allow updates on protected branch (#30749) (#30750)
(cherry picked from commit e4265ce814)

Co-authored-by: Deepesh Garg <42651287+deepeshgarg007@users.noreply.github.com>
2022-04-19 17:33:15 +05:30
FinByz Tech Pvt. Ltd
6291b28c37 fix(india): transporter name is null while generating e-way bill (#30736) 2022-04-19 16:26:56 +05:30
semantic-release-bot
4389100fa1 chore(release): Bumped to Version 13.27.0
# [13.27.0](https://github.com/frappe/erpnext/compare/v13.26.0...v13.27.0) (2022-04-19)

### Bug Fixes

* Depreciation Amount calculation for first row when Monthly Depreciation is allowed ([#30692](https://github.com/frappe/erpnext/issues/30692)) ([9cf790d](9cf790db9d))
* Do not show disabled dimensions in reports ([46d773d](46d773df5d))
* Exchange gain and loss on advance jv allocation ([9c5f841](9c5f8415bf))
* Map correct company to PO made via Prod Plan (subcontract) ([44be67e](44be67e6dd))
* Map Production Plan company in subassembly WO created from it ([f604101](f604101fea))
* **patch:** check if column is present while fixing reverse linking (backport [#30737](https://github.com/frappe/erpnext/issues/30737)) ([#30739](https://github.com/frappe/erpnext/issues/30739)) ([38002e3](38002e3fe2))
* Payment reco query with max invocie and payment amount limit ([4008c95](4008c95ac6))
* Price changing on creating Sales retrun from Delivery Note ([93fe840](93fe840844))
* process statement to_date override ([378d15d](378d15d388))
* Remove "Values Out of Sync" validation (backport [#30707](https://github.com/frappe/erpnext/issues/30707)) ([#30718](https://github.com/frappe/erpnext/issues/30718)) ([fb9d640](fb9d640d8b))
* Update token to allow updates on protected branch ([2a29aef](2a29aefb19))
* update translation ([#30716](https://github.com/frappe/erpnext/issues/30716)) ([fb127da](fb127da489))

### Features

* Item-wise provisional accounting for service items ([5776881](5776881f34))
2022-04-19 10:46:00 +00:00
Ankush Menat
f266d765fd chore: add GH token 2022-04-19 15:58:49 +05:30
Deepesh Garg
5915a73939 Merge pull request #30741 from frappe/version-13-pre-release
chore: release for v13.27.0
2022-04-19 15:42:46 +05:30
Deepesh Garg
f6898344ef Merge pull request #30744 from frappe/mergify/bp/version-13-pre-release/pr-30742
fix: Update token to allow updates on protected branch (backport #30742)
2022-04-19 15:33:21 +05:30
Deepesh Garg
2a29aefb19 fix: Update token to allow updates on protected branch
(cherry picked from commit 6f332f3669)
2022-04-19 10:02:33 +00:00
Deepesh Garg
377c37a99f Merge pull request #30743 from frappe/mergify/bp/version-13-hotfix/pr-30742
fix: Update token to allow updates on protected branch (backport #30742)
2022-04-19 15:32:10 +05:30
Deepesh Garg
baab3797ca fix: Update token to allow updates on protected branch
(cherry picked from commit 6f332f3669)
2022-04-19 10:01:58 +00:00
Deepesh Garg
8c291f7b7a Merge pull request #30734 from frappe/mergify/bp/version-13-hotfix/pr-30721
fix: SO's without delivery note will also be fetched (backport #30721)
2022-04-19 14:12:03 +05:30
Deepesh Garg
381e9d2236 Merge pull request #30740 from frappe/version-13-hotfix
chore: Pre-release for v13.27.0
2022-04-19 14:10:58 +05:30
mergify[bot]
38002e3fe2 fix(patch): check if column is present while fixing reverse linking (backport #30737) (#30739)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-04-19 12:39:28 +05:30
marination
9506dbe433 chore: Patch to copy custom fields (field filters) from Item to Website Item 2022-04-18 21:38:22 +05:30
ruthra kumar
61ff1c22b3 test: Sales order analysis report
(cherry picked from commit 13487e2408)
2022-04-18 14:29:06 +00:00
ruthra kumar
f9d89c7ce6 fix: SO analysis rpt will fetch SO's without Delivery note as well
(cherry picked from commit e28e6726f1)

# Conflicts:
#	erpnext/selling/report/sales_order_analysis/sales_order_analysis.py
2022-04-18 14:29:06 +00:00
marination
34437a83df fix: Validate field filter wrt to Website Item & re-use validation in Item Group 2022-04-18 19:24:08 +05:30
marination
bed9e09153 fix: Query filter fields from Website Item instead of Item master
- tweak `filters.py` to correctly query filter field values from Website Item
- Use Website Item for filter field options in Settings and Item Group Field Filter table
2022-04-18 19:23:17 +05:30
Marica
952e267e92 Merge branch 'version-13-hotfix' into patch-4 2022-04-18 18:10:02 +05:30
mergify[bot]
8e30af84cd chore: Add semantic releases (backport #30729) (#30732)
* chore: Add sematic releases

(cherry picked from commit 41249c57c4)

* chore: Update branch name

(cherry picked from commit cc1bdd426b)

* chore: block major releases

(cherry picked from commit c12a36aed9)

* ci: use latest ubuntu container

(cherry picked from commit 6fc11cb4c5)

* chore: do not publish any assets

(cherry picked from commit e0a9a69d76)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
2022-04-18 17:18:53 +05:30
Deepesh Garg
d6126b6695 Merge pull request #30731 from frappe/mergify/bp/version-13-hotfix/pr-30728
fix: Price changing on creating Sales return from Delivery Note (backport #30728)
2022-04-18 16:33:14 +05:30
Deepesh Garg
93fe840844 fix: Price changing on creating Sales retrun from Delivery Note
(cherry picked from commit 9c081947ec)
2022-04-18 09:04:50 +00:00
Deepesh Garg
183ff53ccb Merge pull request #30720 from frappe/mergify/bp/version-13-hotfix/pr-30716
fix: update translation (backport #30716)
2022-04-15 14:01:19 +05:30
HENRY Florian
fb127da489 fix: update translation (#30716)
* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

(cherry picked from commit e6aa28ea14)
2022-04-14 16:07:40 +00:00
Deepesh Garg
933bd7413a Merge pull request #30408 from bhavesh95863/patch-3
fix: process statement to_date override
2022-04-14 18:43:28 +05:30
mergify[bot]
fb9d640d8b fix: Remove "Values Out of Sync" validation (backport #30707) (#30718)
This is an automatic backport of pull request #30707 done by [Mergify](https://mergify.com).
Cherry-pick of 89fab78027 has failed:
```
On branch mergify/bp/version-13-hotfix/pr-30707
Your branch is up to date with 'origin/version-13-hotfix'.

You are currently cherry-picking commit 89fab78027.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   erpnext/accounts/doctype/journal_entry/journal_entry.py

no changes added to commit (use "git add" and/or "git commit -a")
```


To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/github/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally

---


<details>
<summary>Mergify commands and options</summary>

<br />

More conditions and actions can be found in the [documentation](https://docs.mergify.com/).

You can also trigger Mergify actions by commenting on this pull request:

- `@Mergifyio refresh` will re-evaluate the rules
- `@Mergifyio rebase` will rebase this PR on its base branch
- `@Mergifyio update` will merge the base branch into this PR
- `@Mergifyio backport <destination>` will backport this PR on `<destination>` branch

Additionally, on Mergify [dashboard](https://dashboard.mergify.com/) you can:

- look at your merge queues
- generate the Mergify configuration with the config editor.

Finally, you can contact us on https://mergify.com
</details>
2022-04-14 12:29:35 +00:00
Deepesh Garg
62bad90c90 Merge pull request #30717 from frappe/mergify/bp/version-13-hotfix/pr-30710
fix: Exchange gain and loss on advance Journal Entry allocation (backport #30710)
2022-04-14 15:29:55 +05:30
Deepesh Garg
a167f9e17f test: Update customer in Sales Invoice
(cherry picked from commit c38be53ce8)
2022-04-14 09:40:53 +00:00
Deepesh Garg
e135c452af test: Update customer
(cherry picked from commit 972d9ec5b4)
2022-04-14 09:40:53 +00:00
Deepesh Garg
9c5f8415bf fix: Exchange gain and loss on advance jv allocation
(cherry picked from commit 31883b699d)
2022-04-14 09:40:53 +00:00
Deepesh Garg
46a00d1da6 Merge pull request #30714 from frappe/mergify/bp/version-13-hotfix/pr-30675
feat: Item-wise provisional accounting for service items (backport #30675)
2022-04-14 13:14:48 +05:30
Ankush Menat
3a7ac29907 chore: check in missing __init__.py (#30713) 2022-04-14 13:03:34 +05:30
Deepesh Garg
3dcef9352e test: Update test case
(cherry picked from commit ad171c6225)
2022-04-14 07:01:23 +00:00
Deepesh Garg
5776881f34 feat: Item-wise provisional accounting for service items
(cherry picked from commit 3ce64170db)
2022-04-14 07:01:23 +00:00
Deepesh Garg
0b62784f6f Merge pull request #30700 from deepeshgarg007/pay_reco_query_v13
fix: Payment reco query with max invoice and payment amount limit
2022-04-14 11:11:30 +05:30
Ankush Menat
ef4eb4705e chore: warning for DATEV deprecation (#30703) 2022-04-13 15:07:48 +05:30
Ganga Manoj
9cf790db9d fix: Depreciation Amount calculation for first row when Monthly Depreciation is allowed (#30692) 2022-04-13 14:15:10 +05:30
mergify[bot]
2778123106 Merge pull request #30699 from frappe/mergify/bp/version-13-hotfix/pr-30688
fix: Map Production Plan company in subassembly WO created from it (backport #30688)
2022-04-13 07:30:31 +00:00
marination
44be67e6dd fix: Map correct company to PO made via Prod Plan (subcontract)
(cherry picked from commit 6315acc450)
2022-04-13 07:14:16 +00:00
marination
f604101fea fix: Map Production Plan company in subassembly WO created from it
(cherry picked from commit 2777c5c67c)
2022-04-13 07:14:15 +00:00
Deepesh Garg
4008c95ac6 fix: Payment reco query with max invocie and payment amount limit 2022-04-13 12:21:33 +05:30
Deepesh Garg
512b480f6a chore: version bump 2022-04-12 23:31:47 +05:30
Deepesh Garg
d5d6b34380 Merge pull request #30695 from deepeshgarg007/v13_26_0
chore: change log and version bump
2022-04-12 23:29:44 +05:30
Deepesh Garg
2c2d5ccb8f Merge pull request #30694 from frappe/version-13-pre-release
chore: Release for v13.26.0
2022-04-12 23:28:24 +05:30
Deepesh Garg
147499bc9c chore: change log and version bump 2022-04-12 23:01:09 +05:30
Deepesh Garg
dc669b540d Merge pull request #30691 from frappe/mergify/bp/version-13-hotfix/pr-30689
fix: Do not show disabled dimensions in reports (backport #30689)
2022-04-12 22:28:46 +05:30
Deepesh Garg
08e2b9110c Merge pull request #30693 from frappe/version-13-hotfix
chore: Pre release for v13.26.0
2022-04-12 16:56:52 +05:30
Deepesh Garg
46d773df5d fix: Do not show disabled dimensions in reports
(cherry picked from commit 9a1c560c82)
2022-04-12 10:41:25 +00:00
Deepesh Garg
4a48a6aae3 Merge pull request #30690 from frappe/mergify/bp/version-13-hotfix/pr-30686
feat: Ignore permlevel for specific fields (backport #30686)
2022-04-12 16:10:51 +05:30
Nabin Hait
e650d99cdd feat: Ignore permlevel for specific fields
(cherry picked from commit 993c6c0de9)
2022-04-12 10:26:17 +00:00
Deepesh Garg
23ccadbcae Merge pull request #30683 from frappe/mergify/bp/version-13-hotfix/pr-30651
fix: Download JSON for GSTR-1 report (backport #30651)
2022-04-12 14:00:55 +05:30
Deepesh Garg
bfd8ab6d72 Merge pull request #30687 from frappe/mergify/bp/version-13-hotfix/pr-30626
feat(india): e-invoicing for intra-state union territory transactions (backport #30626)
2022-04-12 14:00:38 +05:30
Saqib Ansari
2ab431ad36 feat(india): e-invoicing for intra-state union territory transactions
(cherry picked from commit 45fca6bed7)
2022-04-12 08:03:23 +00:00
mergify[bot]
21066a48b6 fix: ignore item-less maintenance visit for sr no (#30684) (#30685)
(cherry picked from commit 60fb71bd2a)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-12 11:16:59 +05:30
Deepesh Garg
9efc0d1043 fix: Download JSON for GSTR-1 report
(cherry picked from commit b532ade383)
2022-04-11 18:37:17 +00:00
Deepesh Garg
54ea9319a1 Merge pull request #30680 from frappe/mergify/bp/version-13-hotfix/pr-30602
fix: Deferred Revenue/Expense Account validation (backport #30602)
2022-04-11 20:54:52 +05:30
Marica
f54f9771e4 Merge pull request #30681 from frappe/mergify/bp/version-13-hotfix/pr-30674
fix: Handle multiple item transfer in separate SEs against WO (backport #30674)
2022-04-11 17:46:12 +05:30
marination
e322e7654a test: Multiple RM transfer in separate Stock Entries
- Added test and acceptance of 0 as For Quantity in test helper

(cherry picked from commit 5aa60bb651)
2022-04-11 11:54:48 +00:00
marination
c674180f1a style: Missing Semicolon
(cherry picked from commit be2e5ce966)
2022-04-11 11:54:48 +00:00
marination
d079d8771b fix: Handle multiple item transfer in separate SEs against WO
- Check for pending qty in child items to show/hide "Start" button
- If no qty needed to transfer (FG qty is fulfilled), but RM qty pending: map pending in SE with For Quantity = 0

(cherry picked from commit dfff4beaf4)
2022-04-11 11:54:48 +00:00
Deepesh Garg
4296fc36cc test: Add test
(cherry picked from commit 553178bfe7)
2022-04-11 11:33:33 +00:00
Deepesh Garg
f6c9f052d2 fix: Deferred Revenue/Expense Account validation
(cherry picked from commit 9bf5f76ac8)
2022-04-11 11:33:33 +00:00
Ankush Menat
c9af4e8ce5 chore: broken link 2022-04-11 16:55:22 +05:30
mergify[bot]
e91dea62b8 fix: update translation (#30654) (#30676)
(cherry picked from commit 03c631d723)

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
2022-04-11 14:48:17 +05:30
Deepesh Garg
cc3c9c7042 Merge pull request #30662 from deepeshgarg007/implicit_ignore_prcing_rule_check_on_returns
fix: Implicit ignore pricing rule check on returns
2022-04-09 20:15:57 +05:30
Deepesh Garg
8e742d6612 Merge pull request #30663 from frappe/mergify/bp/version-13-hotfix/pr-30542
fix: Ignore disabled tax categories (backport #30542)
2022-04-09 20:15:30 +05:30
Deepesh Garg
37dc11e59a fix: Ignore disabled tax categories
(cherry picked from commit 9a6a181f14)
2022-04-09 14:22:53 +00:00
Deepesh Garg
1b25a7fe76 fix: Implicit ignore pricing rule check on returns 2022-04-09 19:20:51 +05:30
mergify[bot]
e69849d333 fix(pos): cannot change paid amount in pos payments (#30661) 2022-04-09 16:28:25 +05:30
Saqib Ansari
e4bb81d830 fix(pos): cannot change paid amount in pos payments (#30657) 2022-04-09 16:13:29 +05:30
Jannat Patel
d66979ff52 Merge pull request #30650 from frappe/mergify/bp/version-13-hotfix/pr-30596 2022-04-08 16:50:38 +05:30
Jannat Patel
2ccf58d6ad fix: removed unused courses template
(cherry picked from commit bce1c2a028)
2022-04-08 10:58:18 +00:00
Ankush Menat
9b6c5f2e54 test: prevent cancelling RIV of cancelled voucher
(cherry picked from commit d74181630a)
2022-04-08 16:14:01 +05:30
Ankush Menat
8cac70a63c fix: prevent deleting repost queue for cancelled transactions
(cherry picked from commit a281998bcb)
2022-04-08 16:14:01 +05:30
Deepesh Garg
8d4d12c3b0 Merge pull request #30633 from frappe/mergify/bp/version-13-hotfix/pr-30606
fix: Exchange gain and loss button in Payment Entry (backport #30606)
2022-04-08 13:05:23 +05:30
mergify[bot]
341e8dffd3 fix: remove bad defaults from BOM operation (#30644) (#30645)
[skip ci]

(cherry picked from commit 49560d20bc)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-08 11:27:17 +05:30
Deepesh Garg
13f9207b41 Merge pull request #30620 from nabinhait/party-account-in-ar-ap-report-v13
feat: Receivable/Payable Account column and filter in AR/AP report
2022-04-07 21:24:56 +05:30
Deepesh Garg
a4ea9fa801 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30606 2022-04-07 21:24:24 +05:30
mergify[bot]
c0cf18d2d6 Merge pull request #30624 from frappe/mergify/bp/version-13-hotfix/pr-30499
feat: 'customer' column and more filter to Payment terms status report (backport #30499)
2022-04-07 13:47:58 +00:00
Ankush Menat
d62928ed65 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30499 2022-04-07 19:02:47 +05:30
mergify[bot]
4a7ae5c4a7 fix: dont reassign mutable (list) to a different field (backport #30634) (#30635)
This is an automatic backport of pull request #30634 done by [Mergify](https://mergify.com).
Conflicts fixed.
2022-04-07 13:30:24 +00:00
Deepesh Garg
be438c08db fix: Exchange gain and loss button in Payment Entry
(cherry picked from commit 8feb4f08c5)
2022-04-07 11:19:25 +00:00
Nabin Hait
709fcd5051 feat: Receivable/Payable Account column and filter in AR/AP report 2022-04-07 15:56:42 +05:30
mergify[bot]
560c55935f fix: warehouse naming when suffix is present (#30621) (#30629)
(cherry picked from commit be04eaf723)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-07 15:37:33 +05:30
Chillar Anand
30a86951c3 test: Fix failing tests for healthcare service unit (#30625) 2022-04-07 14:58:38 +05:30
mergify[bot]
4b77a4de28 fix: update translation (backport #30474) (#30593)
* fix: update translation (#30474)

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

* fix: update translation

(cherry picked from commit 4895761d89)

* chore: fix translation csv file

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-07 13:24:48 +05:30
Rucha Mahabal
8932d7040f fix: conflicts 2022-04-07 13:21:06 +05:30
Rucha Mahabal
07ff2cb1d3 fix: conflicts 2022-04-07 13:21:06 +05:30
Rucha Mahabal
8393d113d4 fix: show allocation history for earned leaves allocated via scheduler
(cherry picked from commit ec65af5f38)
2022-04-07 13:21:06 +05:30
Rucha Mahabal
c68a38eb5b fix: make New Leaves Allocated read-only if policy assignment is linked to the allocation and leave type is earned leave
(cherry picked from commit 6203ffc8fa)
2022-04-07 13:21:06 +05:30
Rucha Mahabal
0c163eef23 fix: enable Track Changes in Leave Allocation
(cherry picked from commit f8f1c3d8b5)

# Conflicts:
#	erpnext/hr/doctype/leave_allocation/leave_allocation.json
2022-04-07 13:21:06 +05:30
mergify[bot]
af039be03e fix: fallback to item_name if description is not found (backport #30619) (#30622)
* fix: strip html tags before checking for empty description (#30619)

(cherry picked from commit e4c6d6a1a6)

# Conflicts:
#	erpnext/stock/doctype/item/test_item.py

* fix: resolve conflicts

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-07 13:20:36 +05:30
ruthra kumar
39f8ee2ea6 test: added test cases for group filters
(cherry picked from commit 16bfb930f8)
2022-04-07 07:32:04 +00:00
ruthra kumar
a9d5000eab refactor: use group fields from Sales Order and Sales Order Items
(cherry picked from commit b2ed9fd3fe)
2022-04-07 07:32:03 +00:00
ruthra kumar
00acb000dc refactor: item filters are linked with group filters
(cherry picked from commit e324d668d3)
2022-04-07 07:32:02 +00:00
ruthra kumar
9336a3413f refactor: adding new filters and column to test cases
(cherry picked from commit 7558f1b078)
2022-04-07 07:32:02 +00:00
ruthra kumar
c6f946e3e8 feat: additional filters in payment terms status report
(cherry picked from commit eaeadbc422)
2022-04-07 07:32:01 +00:00
Saqib Ansari
d720d15e3d fix(pos): reload doc before set value (#30610) 2022-04-06 22:32:23 +05:30
Saqib Ansari
2e29cf38bb Merge pull request #30611 from nextchamp-saqib/fix-pos-patch-v13
fix(pos): reload doc before set value
2022-04-06 22:28:49 +05:30
Saqib Ansari
f94afc1fff fix(pos): reload doc before set value 2022-04-06 22:14:37 +05:30
Ankush Menat
f89c1b2c0c fix: dont trigger closed WO check on new Job card 2022-04-06 18:28:54 +05:30
mergify[bot]
52aa3561e3 fix: hide pending qty only if original item is assigned (#30599) (#30600)
(cherry picked from commit 8b090a9f7d)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-06 16:38:25 +05:30
mergify[bot]
14f46a3e26 fix: check null values in is_cancelled patch (#30594) (#30595)
(cherry picked from commit bb875fe217)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-04-06 15:14:37 +05:30
Mostafa Fekry
86c5f4db85 fix: e_commerce_settings.py
Update get meta from Item to Website Item doctype to check validate_field_filters
2022-03-28 18:15:46 +05:30
Ankush Menat
fc5fd34621 Merge branch 'version-13-hotfix' into patch-4 2022-03-28 18:06:50 +05:30
Bhavesh Maheshwari
378d15d388 fix: process statement to_date override 2022-03-25 11:27:19 +05:30
Mostafa Fekry
3a5f5d5cd0 fix: e_commerce_settings.js
Update get meta from Item to Website Item
To allow Website Item Fields to display meta fields
2022-03-10 16:05:08 +02:00
Govind S Menokee
363752510e fix: HSN-wise-summary of outward supplies Updated Report
Report changes done in order to meet the specification as per govt guideline - [GUIDELINE](https://taxguru.in/goods-and-service-tax/12-points-note-filing-gstr-1-01st-2021-onwards.html)
2022-03-02 22:29:19 +05:30
272 changed files with 152144 additions and 3100 deletions

View File

@@ -2,6 +2,13 @@
set -e
# Check for merge conflicts before proceeding
python -m compileall -f "${GITHUB_WORKSPACE}"
if grep -lr --exclude-dir=node_modules "^<<<<<<< " "${GITHUB_WORKSPACE}"
then echo "Found merge conflicts"
exit 1
fi
cd ~ || exit
sudo apt-get install redis-server libcups2-dev

31
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,31 @@
name: Generate Semantic Release
on:
push:
branches:
- version-13
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Entire Repository
uses: actions/checkout@v2
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js v14
uses: actions/setup-node@v2
with:
node-version: 14
- name: Setup dependencies
run: |
npm install @semantic-release/git @semantic-release/exec --no-save
- name: Create Release
env:
GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
GIT_AUTHOR_NAME: "Frappe PR Bot"
GIT_AUTHOR_EMAIL: "developers@frappe.io"
GIT_COMMITTER_NAME: "Frappe PR Bot"
GIT_COMMITTER_EMAIL: "developers@frappe.io"
run: npx semantic-release

24
.releaserc Normal file
View File

@@ -0,0 +1,24 @@
{
"branches": ["version-13"],
"plugins": [
"@semantic-release/commit-analyzer", {
"preset": "angular",
"releaseRules": [
{"breaking": true, "release": false}
]
},
"@semantic-release/release-notes-generator",
[
"@semantic-release/exec", {
"prepareCmd": 'sed -ir "s/[0-9]*\.[0-9]*\.[0-9]*/${nextRelease.version}/" erpnext/__init__.py'
}
],
[
"@semantic-release/git", {
"assets": ["erpnext/__init__.py"],
"message": "chore(release): Bumped to Version ${nextRelease.version}\n\n${nextRelease.notes}"
}
],
"@semantic-release/github"
]
}

View File

@@ -4,7 +4,8 @@ import frappe
from erpnext.hooks import regional_overrides
__version__ = '13.25.2'
__version__ = "13.32.0"
def get_default_company(user=None):
"""Get default company for user"""

View File

@@ -386,7 +386,6 @@ def book_deferred_income_or_expense(doc, deferred_process, posting_date=None):
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
end_date,
@@ -570,7 +569,6 @@ def book_revenue_via_journal_entry(
doc,
credit_account,
debit_account,
against,
amount,
base_amount,
posting_date,
@@ -591,6 +589,7 @@ def book_revenue_via_journal_entry(
journal_entry.voucher_type = (
"Deferred Revenue" if doc.doctype == "Sales Invoice" else "Deferred Expense"
)
journal_entry.process_deferred_accounting = deferred_process
debit_entry = {
"account": credit_account,

View File

@@ -99,7 +99,7 @@ def make_dimension_in_accounting_doctypes(doc, doclist=None):
if doctype == "Budget":
add_dimension_to_budget_doctype(df.copy(), doc)
else:
create_custom_field(doctype, df)
create_custom_field(doctype, df, ignore_validate=True)
count += 1
@@ -115,7 +115,7 @@ def add_dimension_to_budget_doctype(df, doc):
}
)
create_custom_field("Budget", df)
create_custom_field("Budget", df, ignore_validate=True)
property_setter = frappe.db.exists("Property Setter", "Budget-budget_against-options")
@@ -205,10 +205,16 @@ def get_doctypes_with_dimensions():
return frappe.get_hooks("accounting_dimension_doctypes")
def get_accounting_dimensions(as_list=True):
def get_accounting_dimensions(as_list=True, filters=None):
if not filters:
filters = {"disabled": 0}
if frappe.flags.accounting_dimensions is None:
frappe.flags.accounting_dimensions = frappe.get_all(
"Accounting Dimension", fields=["label", "fieldname", "disabled", "document_type"]
"Accounting Dimension",
fields=["label", "fieldname", "disabled", "document_type"],
filters=filters,
)
if as_list:
@@ -228,17 +234,19 @@ def get_checks_for_pl_and_bs_accounts():
return dimensions
def get_dimension_with_children(doctype, dimension):
def get_dimension_with_children(doctype, dimensions):
if isinstance(dimension, list):
dimension = dimension[0]
if isinstance(dimensions, str):
dimensions = [dimensions]
all_dimensions = []
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
children = frappe.get_all(
doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft"
)
all_dimensions += [c.name for c in children]
for dimension in dimensions:
lft, rgt = frappe.db.get_value(doctype, dimension, ["lft", "rgt"])
children = frappe.get_all(
doctype, filters={"lft": [">=", lft], "rgt": ["<=", rgt]}, order_by="lft"
)
all_dimensions += [c.name for c in children]
return all_dimensions

View File

@@ -5,7 +5,10 @@
import frappe
from frappe import _, msgprint
from frappe.model.document import Document
from frappe.utils import flt, fmt_money, getdate, nowdate
from frappe.query_builder.custom import ConstantColumn
from frappe.utils import flt, fmt_money, getdate
import erpnext
form_grid_templates = {"journal_entries": "templates/form_grid/bank_reconciliation_grid.html"}
@@ -76,6 +79,53 @@ class BankClearance(Document):
as_dict=1,
)
loan_disbursement = frappe.qb.DocType("Loan Disbursement")
loan_disbursements = (
frappe.qb.from_(loan_disbursement)
.select(
ConstantColumn("Loan Disbursement").as_("payment_document"),
loan_disbursement.name.as_("payment_entry"),
loan_disbursement.disbursed_amount.as_("credit"),
ConstantColumn(0).as_("debit"),
loan_disbursement.reference_number.as_("cheque_number"),
loan_disbursement.reference_date.as_("cheque_date"),
loan_disbursement.disbursement_date.as_("posting_date"),
loan_disbursement.applicant.as_("against_account"),
)
.where(loan_disbursement.docstatus == 1)
.where(loan_disbursement.disbursement_date >= self.from_date)
.where(loan_disbursement.disbursement_date <= self.to_date)
.where(loan_disbursement.clearance_date.isnull())
.where(loan_disbursement.disbursement_account.isin([self.bank_account, self.account]))
.orderby(loan_disbursement.disbursement_date)
.orderby(loan_disbursement.name, frappe.qb.desc)
).run(as_dict=1)
loan_repayment = frappe.qb.DocType("Loan Repayment")
loan_repayments = (
frappe.qb.from_(loan_repayment)
.select(
ConstantColumn("Loan Repayment").as_("payment_document"),
loan_repayment.name.as_("payment_entry"),
loan_repayment.amount_paid.as_("debit"),
ConstantColumn(0).as_("credit"),
loan_repayment.reference_number.as_("cheque_number"),
loan_repayment.reference_date.as_("cheque_date"),
loan_repayment.applicant.as_("against_account"),
loan_repayment.posting_date,
)
.where(loan_repayment.docstatus == 1)
.where(loan_repayment.clearance_date.isnull())
.where(loan_repayment.repay_from_salary == 0)
.where(loan_repayment.posting_date >= self.from_date)
.where(loan_repayment.posting_date <= self.to_date)
.where(loan_repayment.payment_account.isin([self.bank_account, self.account]))
.orderby(loan_repayment.posting_date)
.orderby(loan_repayment.name, frappe.qb.desc)
).run(as_dict=1)
pos_sales_invoices, pos_purchase_invoices = [], []
if self.include_pos_transactions:
pos_sales_invoices = frappe.db.sql(
@@ -114,20 +164,29 @@ class BankClearance(Document):
entries = sorted(
list(payment_entries)
+ list(journal_entries + list(pos_sales_invoices) + list(pos_purchase_invoices)),
key=lambda k: k["posting_date"] or getdate(nowdate()),
+ list(journal_entries)
+ list(pos_sales_invoices)
+ list(pos_purchase_invoices)
+ list(loan_disbursements)
+ list(loan_repayments),
key=lambda k: getdate(k["posting_date"]),
)
self.set("payment_entries", [])
self.total_amount = 0.0
default_currency = erpnext.get_default_currency()
for d in entries:
row = self.append("payment_entries", {})
amount = flt(d.get("debit", 0)) - flt(d.get("credit", 0))
if not d.get("account_currency"):
d.account_currency = default_currency
formatted_amount = fmt_money(abs(amount), 2, d.account_currency)
d.amount = formatted_amount + " " + (_("Dr") if amount > 0 else _("Cr"))
d.posting_date = getdate(d.posting_date)
d.pop("credit")
d.pop("debit")

View File

@@ -1,9 +1,96 @@
# Copyright (c) 2020, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
import frappe
from frappe.utils import add_months, getdate
from erpnext.accounts.doctype.payment_entry.test_payment_entry import get_payment_entry
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
from erpnext.loan_management.doctype.loan.test_loan import (
create_loan,
create_loan_accounts,
create_loan_type,
create_repayment_entry,
make_loan_disbursement_entry,
)
class TestBankClearance(unittest.TestCase):
pass
@classmethod
def setUpClass(cls):
make_bank_account()
create_loan_accounts()
create_loan_masters()
add_transactions()
# Basic test case to test if bank clearance tool doesn't break
# Detailed test can be added later
def test_bank_clearance(self):
bank_clearance = frappe.get_doc("Bank Clearance")
bank_clearance.account = "_Test Bank Clearance - _TC"
bank_clearance.from_date = add_months(getdate(), -1)
bank_clearance.to_date = getdate()
bank_clearance.get_payment_entries()
self.assertEqual(len(bank_clearance.payment_entries), 3)
def make_bank_account():
if not frappe.db.get_value("Account", "_Test Bank Clearance - _TC"):
frappe.get_doc(
{
"doctype": "Account",
"account_type": "Bank",
"account_name": "_Test Bank Clearance",
"company": "_Test Company",
"parent_account": "Bank Accounts - _TC",
}
).insert()
def create_loan_masters():
create_loan_type(
"Clearance Loan",
2000000,
13.5,
25,
0,
5,
"Cash",
"_Test Bank Clearance - _TC",
"_Test Bank Clearance - _TC",
"Loan Account - _TC",
"Interest Income Account - _TC",
"Penalty Income Account - _TC",
)
def add_transactions():
make_payment_entry()
make_loan()
def make_loan():
loan = create_loan(
"_Test Customer",
"Clearance Loan",
280000,
"Repay Over Number of Periods",
20,
applicant_type="Customer",
)
loan.submit()
make_loan_disbursement_entry(loan.name, loan.loan_amount, disbursement_date=getdate())
repayment_entry = create_repayment_entry(loan.name, "_Test Customer", getdate(), loan.loan_amount)
repayment_entry.save()
repayment_entry.submit()
def make_payment_entry():
pi = make_purchase_invoice(supplier="_Test Supplier", qty=1, rate=690)
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank Clearance - _TC")
pe.reference_no = "Conrad Oct 18"
pe.reference_date = "2018-10-24"
pe.insert()
pe.submit()

View File

@@ -467,6 +467,7 @@ def get_lr_matching_query(bank_account, amount_condition, filters):
loan_repayment.posting_date,
)
.where(loan_repayment.docstatus == 1)
.where(loan_repayment.repay_from_salary == 0)
.where(loan_repayment.clearance_date.isnull())
.where(loan_repayment.payment_account == bank_account)
)

View File

@@ -10,6 +10,7 @@
"sgst_account",
"igst_account",
"cess_account",
"utgst_account",
"is_reverse_charge_account"
],
"fields": [
@@ -64,12 +65,18 @@
"fieldtype": "Check",
"in_list_view": 1,
"label": "Is Reverse Charge Account"
},
{
"fieldname": "utgst_account",
"fieldtype": "Link",
"label": "UTGST Account",
"options": "Account"
}
],
"index_web_pages_for_search": 1,
"istable": 1,
"links": [],
"modified": "2021-04-09 12:30:25.889993",
"modified": "2022-04-07 12:59:14.039768",
"modified_by": "Administrator",
"module": "Accounts",
"name": "GST Account",
@@ -78,5 +85,6 @@
"quick_entry": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -3,7 +3,7 @@
"allow_auto_repeat": 1,
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2013-03-25 10:53:52",
"creation": "2022-01-25 10:29:58.717206",
"doctype": "DocType",
"document_type": "Document",
"engine": "InnoDB",
@@ -13,6 +13,7 @@
"voucher_type",
"naming_series",
"finance_book",
"process_deferred_accounting",
"reversal_of",
"tax_withholding_category",
"column_break1",
@@ -524,13 +525,20 @@
"label": "Reversal Of",
"options": "Journal Entry",
"read_only": 1
},
{
"fieldname": "process_deferred_accounting",
"fieldtype": "Link",
"label": "Process Deferred Accounting",
"options": "Process Deferred Accounting",
"read_only": 1
}
],
"icon": "fa fa-file-text",
"idx": 176,
"is_submittable": 1,
"links": [],
"modified": "2022-01-04 13:39:36.485954",
"modified": "2022-04-06 17:18:46.865259",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",
@@ -578,6 +586,7 @@
"search_fields": "voucher_type,posting_date, due_date, cheque_no",
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"title_field": "title",
"track_changes": 1
}

View File

@@ -19,7 +19,6 @@ from erpnext.accounts.doctype.tax_withholding_category.tax_withholding_category
)
from erpnext.accounts.party import get_party_account
from erpnext.accounts.utils import (
check_if_stock_and_account_balance_synced,
get_account_currency,
get_balance_on,
get_stock_accounts,
@@ -88,9 +87,6 @@ class JournalEntry(AccountsController):
self.update_expense_claim()
self.update_inter_company_jv()
self.update_invoice_discounting()
check_if_stock_and_account_balance_synced(
self.posting_date, self.company, self.doctype, self.name
)
def on_cancel(self):
from erpnext.accounts.utils import unlink_ref_doc_from_payment_entries

View File

@@ -114,10 +114,13 @@ class OpeningInvoiceCreationTool(Document):
)
or {}
)
default_currency = frappe.db.get_value(row.party_type, row.party, "default_currency")
if company_details:
invoice.update(
{
"currency": company_details.get("default_currency"),
"currency": default_currency or company_details.get("default_currency"),
"letter_head": company_details.get("default_letter_head"),
}
)

View File

@@ -226,10 +226,7 @@ frappe.ui.form.on('Payment Entry', {
(frm.doc.total_allocated_amount > party_amount)));
frm.toggle_display("set_exchange_gain_loss",
(frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount &&
((frm.doc.paid_from_account_currency != company_currency ||
frm.doc.paid_to_account_currency != company_currency) &&
frm.doc.paid_from_account_currency != frm.doc.paid_to_account_currency)));
frm.doc.paid_amount && frm.doc.received_amount && frm.doc.difference_amount);
frm.refresh_fields();
},

View File

@@ -357,6 +357,12 @@ class PaymentEntry(AccountsController):
)
)
if ref_doc.doctype == "Purchase Invoice" and ref_doc.get("on_hold"):
frappe.throw(
_("{0} {1} is on hold").format(d.reference_doctype, d.reference_name),
title=_("Invalid Invoice"),
)
if ref_doc.docstatus != 1:
frappe.throw(_("{0} {1} must be submitted").format(d.reference_doctype, d.reference_name))

View File

@@ -743,6 +743,21 @@ class TestPaymentEntry(unittest.TestCase):
flt(payment_entry.total_taxes_and_charges, 2), flt(10 / payment_entry.target_exchange_rate, 2)
)
def test_payment_entry_against_onhold_purchase_invoice(self):
pi = make_purchase_invoice()
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
pe.reference_no = "1"
pe.reference_date = "2016-01-01"
# block invoice after creating payment entry
# since `get_payment_entry` will not attach blocked invoice to payment
pi.block_invoice()
with self.assertRaises(frappe.ValidationError) as err:
pe.save()
self.assertTrue("is on hold" in str(err.exception).lower())
def create_payment_entry(**args):
payment_entry = frappe.new_doc("Payment Entry")

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
// Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
// For license information, please see license.txt
frappe.provide("erpnext.accounts");
@@ -38,6 +38,15 @@ erpnext.accounts.PaymentReconciliationController = frappe.ui.form.Controller.ext
]
};
});
this.frm.set_query("cost_center", () => {
return {
"filters": {
"company": this.frm.doc.company,
"is_group": 0
}
}
});
},
refresh: function() {

View File

@@ -24,6 +24,7 @@
"invoice_limit",
"payment_limit",
"bank_cash_account",
"cost_center",
"sec_break1",
"invoices",
"column_break_15",
@@ -178,13 +179,19 @@
{
"fieldname": "column_break_11",
"fieldtype": "Column Break"
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
}
],
"hide_toolbar": 1,
"icon": "icon-resize-horizontal",
"issingle": 1,
"links": [],
"modified": "2021-10-04 20:27:11.114194",
"modified": "2022-04-29 15:37:10.246831",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Payment Reconciliation",
@@ -209,5 +216,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -332,6 +332,9 @@ 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):
condition = " and cost_center = '{0}' ".format(self.cost_center)
if get_invoices:
condition += (
" and posting_date >= {0}".format(frappe.db.escape(self.from_invoice_date))
@@ -350,9 +353,13 @@ class PaymentReconciliation(Document):
)
if self.minimum_invoice_amount:
condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_invoice_amount))
condition += " and {dr_or_cr} >= {amount}".format(
dr_or_cr=dr_or_cr, amount=flt(self.minimum_invoice_amount)
)
if self.maximum_invoice_amount:
condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_invoice_amount))
condition += " and {dr_or_cr} <= {amount}".format(
dr_or_cr=dr_or_cr, amount=flt(self.maximum_invoice_amount)
)
elif get_return_invoices:
condition = " and doc.company = '{0}' ".format(self.company)
@@ -367,15 +374,19 @@ class PaymentReconciliation(Document):
else ""
)
dr_or_cr = (
"gl.debit_in_account_currency"
"debit_in_account_currency"
if erpnext.get_party_account_type(self.party_type) == "Receivable"
else "gl.credit_in_account_currency"
else "credit_in_account_currency"
)
if self.minimum_invoice_amount:
condition += " and `{0}` >= {1}".format(dr_or_cr, flt(self.minimum_payment_amount))
condition += " and gl.{dr_or_cr} >= {amount}".format(
dr_or_cr=dr_or_cr, amount=flt(self.minimum_payment_amount)
)
if self.maximum_invoice_amount:
condition += " and `{0}` <= {1}".format(dr_or_cr, flt(self.maximum_payment_amount))
condition += " and gl.{dr_or_cr} <= {amount}".format(
dr_or_cr=dr_or_cr, amount=flt(self.maximum_payment_amount)
)
else:
condition += (

View File

@@ -1,9 +1,96 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
# import frappe
import unittest
import frappe
from frappe.utils import add_days, getdate
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
class TestPaymentReconciliation(unittest.TestCase):
pass
@classmethod
def setUpClass(cls):
make_customer()
make_invoice_and_payment()
def test_payment_reconciliation(self):
payment_reco = frappe.get_doc("Payment Reconciliation")
payment_reco.company = "_Test Company"
payment_reco.party_type = "Customer"
payment_reco.party = "_Test Payment Reco Customer"
payment_reco.receivable_payable_account = "Debtors - _TC"
payment_reco.from_invoice_date = add_days(getdate(), -1)
payment_reco.to_invoice_date = getdate()
payment_reco.from_payment_date = add_days(getdate(), -1)
payment_reco.to_payment_date = getdate()
payment_reco.maximum_invoice_amount = 1000
payment_reco.maximum_payment_amount = 1000
payment_reco.invoice_limit = 10
payment_reco.payment_limit = 10
payment_reco.bank_cash_account = "_Test Bank - _TC"
payment_reco.cost_center = "_Test Cost Center - _TC"
payment_reco.get_unreconciled_entries()
self.assertEqual(len(payment_reco.get("invoices")), 1)
self.assertEqual(len(payment_reco.get("payments")), 1)
payment_entry = payment_reco.get("payments")[0].reference_name
invoice = payment_reco.get("invoices")[0].invoice_number
payment_reco.allocate_entries(
{
"payments": [payment_reco.get("payments")[0].as_dict()],
"invoices": [payment_reco.get("invoices")[0].as_dict()],
}
)
payment_reco.reconcile()
payment_entry_doc = frappe.get_doc("Payment Entry", payment_entry)
self.assertEqual(payment_entry_doc.get("references")[0].reference_name, invoice)
def make_customer():
if not frappe.db.get_value("Customer", "_Test Payment Reco Customer"):
frappe.get_doc(
{
"doctype": "Customer",
"customer_name": "_Test Payment Reco Customer",
"customer_type": "Individual",
"customer_group": "_Test Customer Group",
"territory": "_Test Territory",
}
).insert()
def make_invoice_and_payment():
si = create_sales_invoice(
customer="_Test Payment Reco Customer", qty=1, rate=690, do_not_save=True
)
si.cost_center = "_Test Cost Center - _TC"
si.save()
si.submit()
pe = frappe.get_doc(
{
"doctype": "Payment Entry",
"payment_type": "Receive",
"party_type": "Customer",
"party": "_Test Payment Reco Customer",
"company": "_Test Company",
"paid_from_account_currency": "INR",
"paid_to_account_currency": "INR",
"source_exchange_rate": 1,
"target_exchange_rate": 1,
"reference_no": "1",
"reference_date": getdate(),
"received_amount": 690,
"paid_amount": 690,
"paid_from": "Debtors - _TC",
"paid_to": "_Test Bank - _TC",
"cost_center": "_Test Cost Center - _TC",
}
)
pe.insert()
pe.submit()

View File

@@ -166,7 +166,7 @@ class PeriodClosingVoucher(AccountsController):
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.account = t2.name and t2.report_type = 'Profit and Loss'
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}

View File

@@ -78,7 +78,10 @@ class TestPeriodClosingVoucher(unittest.TestCase):
expense_account="Cost of Goods Sold - TPC",
rate=400,
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
)
create_sales_invoice(
company=company,
cost_center=cost_center2,
@@ -86,6 +89,8 @@ class TestPeriodClosingVoucher(unittest.TestCase):
expense_account="Cost of Goods Sold - TPC",
rate=200,
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
)
pcv = self.make_period_closing_voucher(submit=False)
@@ -119,14 +124,17 @@ class TestPeriodClosingVoucher(unittest.TestCase):
surplus_account = create_account()
cost_center = create_cost_center("Test Cost Center 1")
create_sales_invoice(
si = create_sales_invoice(
company=company,
income_account="Sales - TPC",
expense_account="Cost of Goods Sold - TPC",
cost_center=cost_center,
rate=400,
debit_to="Debtors - TPC",
currency="USD",
customer="_Test Customer USD",
)
jv = make_journal_entry(
account1="Cash - TPC",
account2="Sales - TPC",

View File

@@ -64,13 +64,15 @@ frappe.ui.form.on('POS Closing Entry', {
pos_opening_entry(frm) {
if (frm.doc.pos_opening_entry && frm.doc.period_start_date && frm.doc.period_end_date && frm.doc.user) {
reset_values(frm);
frm.trigger("set_opening_amounts");
frm.trigger("get_pos_invoices");
frappe.run_serially([
() => frm.trigger("set_opening_amounts"),
() => frm.trigger("get_pos_invoices")
]);
}
},
set_opening_amounts(frm) {
frappe.db.get_doc("POS Opening Entry", frm.doc.pos_opening_entry)
return frappe.db.get_doc("POS Opening Entry", frm.doc.pos_opening_entry)
.then(({ balance_details }) => {
balance_details.forEach(detail => {
frm.add_child("payment_reconciliation", {
@@ -83,7 +85,7 @@ frappe.ui.form.on('POS Closing Entry', {
},
get_pos_invoices(frm) {
frappe.call({
return frappe.call({
method: 'erpnext.accounts.doctype.pos_closing_entry.pos_closing_entry.get_pos_invoices',
args: {
start: frappe.datetime.get_datetime_as_string(frm.doc.period_start_date),
@@ -100,7 +102,9 @@ frappe.ui.form.on('POS Closing Entry', {
});
},
before_save: function(frm) {
before_save: async function(frm) {
frappe.dom.freeze(__('Processing Sales! Please Wait...'));
frm.set_value("grand_total", 0);
frm.set_value("net_total", 0);
frm.set_value("total_quantity", 0);
@@ -110,17 +114,23 @@ frappe.ui.form.on('POS Closing Entry', {
row.expected_amount = row.opening_amount;
}
for (let row of frm.doc.pos_transactions) {
frappe.db.get_doc("POS Invoice", row.pos_invoice).then(doc => {
frm.doc.grand_total += flt(doc.grand_total);
frm.doc.net_total += flt(doc.net_total);
frm.doc.total_quantity += flt(doc.total_qty);
refresh_payments(doc, frm);
refresh_taxes(doc, frm);
refresh_fields(frm);
set_html_data(frm);
});
const pos_inv_promises = frm.doc.pos_transactions.map(
row => frappe.db.get_doc("POS Invoice", row.pos_invoice)
);
const pos_invoices = await Promise.all(pos_inv_promises);
for (let doc of pos_invoices) {
frm.doc.grand_total += flt(doc.grand_total);
frm.doc.net_total += flt(doc.net_total);
frm.doc.total_quantity += flt(doc.total_qty);
refresh_payments(doc, frm);
refresh_taxes(doc, frm);
refresh_fields(frm);
set_html_data(frm);
}
frappe.dom.unfreeze();
}
});

View File

@@ -712,7 +712,7 @@ class TestPricingRule(unittest.TestCase):
title="_Test Pricing Rule with Min Qty - 2",
)
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", qty=1, currency="USD")
si = create_sales_invoice(do_not_submit=True, customer="_Test Customer 1", qty=1)
item = si.items[0]
item.stock_qty = 1
si.save()

View File

@@ -11,7 +11,7 @@ from erpnext.accounts.deferred_revenue import (
convert_deferred_expense_to_expense,
convert_deferred_revenue_to_income,
)
from erpnext.accounts.general_ledger import make_reverse_gl_entries
from erpnext.accounts.general_ledger import make_gl_entries
class ProcessDeferredAccounting(Document):
@@ -34,4 +34,4 @@ class ProcessDeferredAccounting(Document):
filters={"against_voucher_type": self.doctype, "against_voucher": self.name},
)
make_reverse_gl_entries(gl_entries=gl_entries)
make_gl_entries(gl_entries=gl_entries, cancel=1)

View File

@@ -34,8 +34,9 @@ class ProcessStatementOfAccounts(Document):
frappe.throw(_("Customers not selected."))
if self.enable_auto_email:
self.to_date = self.start_date
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
if self.start_date and getdate(self.start_date) >= getdate(today()):
self.to_date = self.start_date
self.from_date = add_months(self.to_date, -1 * self.filter_duration)
def get_report_pdf(doc, consolidated=True):

View File

@@ -30,6 +30,9 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
onload: function() {
this._super();
// Ignore linked advances
this.frm.ignore_doctypes_on_cancel_all = ['Journal Entry', 'Payment Entry'];
if(!this.frm.doc.__islocal) {
// show credit_to in print format
if(!this.frm.doc.supplier && this.frm.doc.credit_to) {

View File

@@ -801,7 +801,9 @@ class PurchaseInvoice(BuyingController):
if provisional_accounting_for_non_stock_items:
if item.purchase_receipt:
provisional_account = self.get_company_default("default_provisional_account")
provisional_account = frappe.db.get_value(
"Purchase Receipt Item", item.pr_detail, "provisional_expense_account"
) or self.get_company_default("default_provisional_account")
purchase_receipt_doc = purchase_receipt_doc_map.get(item.purchase_receipt)
if not purchase_receipt_doc:
@@ -824,7 +826,7 @@ class PurchaseInvoice(BuyingController):
if expense_booked_in_pr:
# Intentionally passing purchase invoice item to handle partial billing
purchase_receipt_doc.add_provisional_gl_entry(
item, gl_entries, self.posting_date, reverse=1
item, gl_entries, self.posting_date, provisional_account, reverse=1
)
if not self.is_internal_transfer():
@@ -1315,7 +1317,9 @@ class PurchaseInvoice(BuyingController):
if (
not self.is_internal_transfer() and self.rounding_adjustment and self.base_rounding_adjustment
):
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(self.company)
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(
self.company, "Purchase Invoice", self.name
)
gl_entries.append(
self.get_gl_dict(

View File

@@ -1449,7 +1449,8 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertEqual(payment_entry.taxes[0].allocated_amount, 0)
def test_provisional_accounting_entry(self):
item = create_item("_Test Non Stock Item", is_stock_item=0)
create_item("_Test Non Stock Item", is_stock_item=0)
provisional_account = create_account(
account_name="Provision Account",
parent_account="Current Liabilities - _TC",
@@ -1472,6 +1473,8 @@ class TestPurchaseInvoice(unittest.TestCase):
pi.save()
pi.submit()
self.assertEquals(pr.items[0].provisional_expense_account, "Provision Account - _TC")
# Check GLE for Purchase Invoice
expected_gle = [
["Cost of Goods Sold - _TC", 250, 0, add_days(pr.posting_date, -1)],

View File

@@ -34,7 +34,9 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
var me = this;
this._super();
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log', 'POS Closing Entry'];
this.frm.ignore_doctypes_on_cancel_all = ['POS Invoice', 'Timesheet', 'POS Invoice Merge Log',
'POS Closing Entry', 'Journal Entry', 'Payment Entry'];
if(!this.frm.doc.__islocal && !this.frm.doc.customer && this.frm.doc.debit_to) {
// show debit_to in print format
this.frm.set_df_property("debit_to", "print_hide", 0);
@@ -473,7 +475,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
let row = frappe.get_doc(d.doctype, d.name)
set_timesheet_detail_rate(row.doctype, row.name, me.frm.doc.currency, row.timesheet_detail)
});
frm.trigger("calculate_timesheet_totals");
this.frm.trigger("calculate_timesheet_totals");
}
}
});
@@ -883,27 +885,44 @@ frappe.ui.form.on('Sales Invoice', {
set_timesheet_data: function(frm, timesheets) {
frm.clear_table("timesheets")
timesheets.forEach(timesheet => {
timesheets.forEach(async (timesheet) => {
if (frm.doc.currency != timesheet.currency) {
frappe.call({
method: "erpnext.setup.utils.get_exchange_rate",
args: {
from_currency: timesheet.currency,
to_currency: frm.doc.currency
},
callback: function(r) {
if (r.message) {
exchange_rate = r.message;
frm.events.append_time_log(frm, timesheet, exchange_rate);
}
}
});
const exchange_rate = await frm.events.get_exchange_rate(
frm, timesheet.currency, frm.doc.currency
)
frm.events.append_time_log(frm, timesheet, exchange_rate)
} else {
frm.events.append_time_log(frm, timesheet, 1.0);
}
});
},
async get_exchange_rate(frm, from_currency, to_currency) {
if (
frm.exchange_rates
&& frm.exchange_rates[from_currency]
&& frm.exchange_rates[from_currency][to_currency]
) {
return frm.exchange_rates[from_currency][to_currency];
}
return frappe.call({
method: "erpnext.setup.utils.get_exchange_rate",
args: {
from_currency,
to_currency
},
callback: function(r) {
if (r.message) {
// cache exchange rates
frm.exchange_rates = frm.exchange_rates || {};
frm.exchange_rates[from_currency] = frm.exchange_rates[from_currency] || {};
frm.exchange_rates[from_currency][to_currency] = r.message;
}
}
});
},
append_time_log: function(frm, time_log, exchange_rate) {
const row = frm.add_child("timesheets");
row.activity_type = time_log.activity_type;
@@ -914,7 +933,7 @@ frappe.ui.form.on('Sales Invoice', {
row.billing_hours = time_log.billing_hours;
row.billing_amount = flt(time_log.billing_amount) * flt(exchange_rate);
row.timesheet_detail = time_log.name;
row.project_name = time_log.project_name;
row.project_name = time_log.project_name;
frm.refresh_field("timesheets");
frm.trigger("calculate_timesheet_totals");

View File

@@ -1473,7 +1473,9 @@ class SalesInvoice(SellingController):
and self.base_rounding_adjustment
and not self.is_internal_transfer()
):
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(self.company)
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(
self.company, "Sales Invoice", self.name
)
gl_entries.append(
self.get_gl_dict(

View File

@@ -12,7 +12,10 @@ def get_data():
"Sales Invoice": "return_against",
"Auto Repeat": "reference_document",
},
"internal_links": {"Sales Order": ["items", "sales_order"]},
"internal_links": {
"Sales Order": ["items", "sales_order"],
"Timesheet": ["timesheets", "time_sheet"],
},
"transactions": [
{
"label": _("Payment"),

View File

@@ -2007,6 +2007,13 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEqual(expected_values[gle.account][2], gle.credit)
def test_rounding_adjustment_3(self):
from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
create_dimension,
disable_dimension,
)
create_dimension()
si = create_sales_invoice(do_not_save=True)
si.items = []
for d in [(1122, 2), (1122.01, 1), (1122.01, 1)]:
@@ -2034,6 +2041,10 @@ class TestSalesInvoice(unittest.TestCase):
"included_in_print_rate": 1,
},
)
si.cost_center = "_Test Cost Center 2 - _TC"
si.location = "Block 1"
si.save()
si.submit()
self.assertEqual(si.net_total, 4007.16)
@@ -2069,6 +2080,18 @@ class TestSalesInvoice(unittest.TestCase):
self.assertEqual(debit_credit_diff, 0)
round_off_gle = frappe.db.get_value(
"GL Entry",
{"voucher_type": "Sales Invoice", "voucher_no": si.name, "account": "Round Off - _TC"},
["cost_center", "location"],
as_dict=1,
)
self.assertEqual(round_off_gle.cost_center, "_Test Cost Center 2 - _TC")
self.assertEqual(round_off_gle.location, "Block 1")
disable_dimension()
def test_sales_invoice_with_shipping_rule(self):
from erpnext.accounts.doctype.shipping_rule.test_shipping_rule import create_shipping_rule
@@ -2270,6 +2293,14 @@ class TestSalesInvoice(unittest.TestCase):
check_gl_entries(self, si.name, expected_gle, "2019-01-30")
def test_deferred_revenue_missing_account(self):
si = create_sales_invoice(posting_date="2019-01-10", do_not_submit=True)
si.items[0].enable_deferred_revenue = 1
si.items[0].service_start_date = "2019-01-10"
si.items[0].service_end_date = "2019-03-15"
self.assertRaises(frappe.ValidationError, si.save)
def test_fixed_deferred_revenue(self):
deferred_account = create_account(
account_name="Deferred Revenue",
@@ -2554,6 +2585,7 @@ class TestSalesInvoice(unittest.TestCase):
# reset
einvoice_settings = frappe.get_doc("E Invoice Settings")
einvoice_settings.enable = 0
einvoice_settings.save()
frappe.flags.country = country
def test_einvoice_json(self):
@@ -3042,7 +3074,7 @@ class TestSalesInvoice(unittest.TestCase):
acc_settings = frappe.get_single("Accounts Settings")
acc_settings.book_deferred_entries_via_journal_entry = 0
acc_settings.submit_journal_entriessubmit_journal_entries = 0
acc_settings.submit_journal_entries = 0
acc_settings.save()
frappe.db.set_value("Accounts Settings", None, "acc_frozen_upto", None)
@@ -3054,6 +3086,95 @@ class TestSalesInvoice(unittest.TestCase):
si.reload()
self.assertTrue(si.items[0].serial_no)
def test_sales_invoice_with_disabled_account(self):
try:
account = frappe.get_doc("Account", "VAT 5% - _TC")
account.disabled = 1
account.save()
si = create_sales_invoice(do_not_save=True)
si.posting_date = add_days(getdate(), 1)
si.taxes = []
si.append(
"taxes",
{
"charge_type": "On Net Total",
"account_head": "VAT 5% - _TC",
"cost_center": "Main - _TC",
"description": "VAT @ 5.0",
"rate": 9,
},
)
si.save()
with self.assertRaises(frappe.ValidationError) as err:
si.submit()
self.assertTrue(
"Cannot create accounting entries against disabled accounts" in str(err.exception)
)
finally:
account.disabled = 0
account.save()
def test_gain_loss_with_advance_entry(self):
from erpnext.accounts.doctype.journal_entry.test_journal_entry import make_journal_entry
unlink_enabled = frappe.db.get_value(
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice"
)
frappe.db.set_value(
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", 1
)
jv = make_journal_entry("_Test Receivable USD - _TC", "_Test Bank - _TC", -7000, save=False)
jv.accounts[0].exchange_rate = 70
jv.accounts[0].credit_in_account_currency = 100
jv.accounts[0].party_type = "Customer"
jv.accounts[0].party = "_Test Customer USD"
jv.save()
jv.submit()
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=75,
do_not_save=1,
rate=100,
)
si.append(
"advances",
{
"reference_type": "Journal Entry",
"reference_name": jv.name,
"reference_row": jv.accounts[0].name,
"advance_amount": 100,
"allocated_amount": 100,
"ref_exchange_rate": 70,
},
)
si.save()
si.submit()
expected_gle = [
["_Test Receivable USD - _TC", 7500.0, 500],
["Exchange Gain/Loss - _TC", 500.0, 0.0],
["Sales - _TC", 0.0, 7500.0],
]
check_gl_entries(self, si.name, expected_gle, nowdate())
frappe.db.set_value(
"Accounts Settings", "Accounts Settings", "unlink_payment_on_cancel_of_invoice", unlink_enabled
)
def get_sales_invoice_for_e_invoice():
si = make_sales_invoice_for_ewaybill()

View File

@@ -29,6 +29,7 @@ def make_gl_entries(
if gl_map:
if not cancel:
validate_accounting_period(gl_map)
validate_disabled_accounts(gl_map)
gl_map = process_gl_map(gl_map, merge_entries)
if gl_map and len(gl_map) > 1:
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
@@ -43,6 +44,26 @@ def make_gl_entries(
make_reverse_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
def validate_disabled_accounts(gl_map):
accounts = [d.account for d in gl_map if d.account]
Account = frappe.qb.DocType("Account")
disabled_accounts = (
frappe.qb.from_(Account)
.where(Account.name.isin(accounts) & Account.disabled == 1)
.select(Account.name, Account.disabled)
).run(as_dict=True)
if disabled_accounts:
account_list = "<br>"
account_list += ", ".join([frappe.bold(d.name) for d in disabled_accounts])
frappe.throw(
_("Cannot create accounting entries against disabled accounts: {0}").format(account_list),
title=_("Disabled Account Selected"),
)
def validate_accounting_period(gl_map):
accounting_periods = frappe.db.sql(
""" SELECT
@@ -273,7 +294,7 @@ def round_off_debit_credit(gl_map):
def make_round_off_gle(gl_map, debit_credit_diff, precision):
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(
gl_map[0].company
gl_map[0].company, gl_map[0].voucher_type, gl_map[0].voucher_no
)
round_off_account_exists = False
round_off_gle = frappe._dict()
@@ -310,14 +331,43 @@ def make_round_off_gle(gl_map, debit_credit_diff, precision):
}
)
update_accounting_dimensions(round_off_gle)
if not round_off_account_exists:
gl_map.append(round_off_gle)
def get_round_off_account_and_cost_center(company):
def update_accounting_dimensions(round_off_gle):
dimensions = get_accounting_dimensions()
meta = frappe.get_meta(round_off_gle["voucher_type"])
has_all_dimensions = True
for dimension in dimensions:
if not meta.has_field(dimension):
has_all_dimensions = False
if dimensions and has_all_dimensions:
dimension_values = frappe.db.get_value(
round_off_gle["voucher_type"], round_off_gle["voucher_no"], dimensions, as_dict=1
)
for dimension in dimensions:
round_off_gle[dimension] = dimension_values.get(dimension)
def get_round_off_account_and_cost_center(company, voucher_type, voucher_no):
round_off_account, round_off_cost_center = frappe.get_cached_value(
"Company", company, ["round_off_account", "round_off_cost_center"]
) or [None, None]
meta = frappe.get_meta(voucher_type)
# Give first preference to parent cost center for round off GLE
if meta.has_field("cost_center"):
parent_cost_center = frappe.db.get_value(voucher_type, voucher_no, "cost_center")
if parent_cost_center:
round_off_cost_center = parent_cost_center
if not round_off_account:
frappe.throw(_("Please mention Round Off Account in Company"))

View File

@@ -898,3 +898,18 @@ def get_default_contact(doctype, name):
return None
else:
return None
def add_party_account(party_type, party, company, account):
doc = frappe.get_doc(party_type, party)
account_exists = False
for d in doc.get("accounts"):
if d.account == account:
account_exists = True
if not account_exists:
accounts = {"company": company, "account": account}
doc.append("accounts", accounts)
doc.save()

View File

@@ -53,6 +53,22 @@ frappe.query_reports["Accounts Payable"] = {
}
}
},
{
"fieldname": "party_account",
"label": __("Payable Account"),
"fieldtype": "Link",
"options": "Account",
get_query: () => {
var company = frappe.query_report.get_filter_value('company');
return {
filters: {
'company': company,
'account_type': 'Payable',
'is_group': 0
}
};
}
},
{
"fieldname": "ageing_based_on",
"label": __("Ageing Based On"),

View File

@@ -66,6 +66,22 @@ frappe.query_reports["Accounts Receivable"] = {
}
}
},
{
"fieldname": "party_account",
"label": __("Receivable Account"),
"fieldtype": "Link",
"options": "Account",
get_query: () => {
var company = frappe.query_report.get_filter_value('company');
return {
filters: {
'company': company,
'account_type': 'Receivable',
'is_group': 0
}
};
}
},
{
"fieldname": "ageing_based_on",
"label": __("Ageing Based On"),

View File

@@ -111,6 +111,7 @@ class ReceivablePayableReport(object):
voucher_type=gle.voucher_type,
voucher_no=gle.voucher_no,
party=gle.party,
party_account=gle.account,
posting_date=gle.posting_date,
account_currency=gle.account_currency,
remarks=gle.remarks if self.filters.get("show_remarks") else None,
@@ -777,18 +778,21 @@ class ReceivablePayableReport(object):
conditions.append("party=%s")
values.append(self.filters.get(party_type_field))
# get GL with "receivable" or "payable" account_type
account_type = "Receivable" if self.party_type == "Customer" else "Payable"
accounts = [
d.name
for d in frappe.get_all(
"Account", filters={"account_type": account_type, "company": self.filters.company}
)
]
if accounts:
conditions.append("account in (%s)" % ",".join(["%s"] * len(accounts)))
values += accounts
if self.filters.party_account:
conditions.append("account =%s")
values.append(self.filters.party_account)
else:
# get GL with "receivable" or "payable" account_type
account_type = "Receivable" if self.party_type == "Customer" else "Payable"
accounts = [
d.name
for d in frappe.get_all(
"Account", filters={"account_type": account_type, "company": self.filters.company}
)
]
if accounts:
conditions.append("account in (%s)" % ",".join(["%s"] * len(accounts)))
values += accounts
def add_customer_filters(self, conditions, values):
if self.filters.get("customer_group"):
@@ -889,6 +893,14 @@ class ReceivablePayableReport(object):
width=180,
)
self.add_column(
label="Receivable Account" if self.party_type == "Customer" else "Payable Account",
fieldname="party_account",
fieldtype="Link",
options="Account",
width=180,
)
if self.party_naming_by == "Naming Series":
self.add_column(
_("{0} Name").format(self.party_type),

View File

@@ -50,12 +50,19 @@ class TestAccountsReceivable(unittest.TestCase):
make_credit_note(name)
report = execute(filters)
expected_data_after_credit_note = [100, 0, 0, 40, -40]
expected_data_after_credit_note = [100, 0, 0, 40, -40, "Debtors - _TC2"]
row = report[1][0]
self.assertEqual(
expected_data_after_credit_note,
[row.invoice_grand_total, row.invoiced, row.paid, row.credit_note, row.outstanding],
[
row.invoice_grand_total,
row.invoiced,
row.paid,
row.credit_note,
row.outstanding,
row.party_account,
],
)

View File

@@ -198,12 +198,14 @@ def get_loan_entries(filters):
amount_field = (loan_doc.disbursed_amount).as_("credit")
posting_date = (loan_doc.disbursement_date).as_("posting_date")
account = loan_doc.disbursement_account
salary_condition = loan_doc.docstatus == 1
else:
amount_field = (loan_doc.amount_paid).as_("debit")
posting_date = (loan_doc.posting_date).as_("posting_date")
account = loan_doc.payment_account
salary_condition = loan_doc.repay_from_salary == 0
entries = (
query = (
frappe.qb.from_(loan_doc)
.select(
ConstantColumn(doctype).as_("payment_document"),
@@ -214,12 +216,13 @@ def get_loan_entries(filters):
posting_date,
)
.where(loan_doc.docstatus == 1)
.where(salary_condition)
.where(account == filters.get("account"))
.where(posting_date <= getdate(filters.get("report_date")))
.where(ifnull(loan_doc.clearance_date, "4000-01-01") > getdate(filters.get("report_date")))
.run(as_dict=1)
)
entries = query.run(as_dict=1)
loan_docs.extend(entries)
return loan_docs
@@ -264,15 +267,17 @@ def get_loan_amount(filters):
amount_field = Sum(loan_doc.disbursed_amount)
posting_date = (loan_doc.disbursement_date).as_("posting_date")
account = loan_doc.disbursement_account
salary_condition = loan_doc.docstatus == 1
else:
amount_field = Sum(loan_doc.amount_paid)
posting_date = (loan_doc.posting_date).as_("posting_date")
account = loan_doc.payment_account
salary_condition = loan_doc.repay_from_salary == 0
amount = (
frappe.qb.from_(loan_doc)
.select(amount_field)
.where(loan_doc.docstatus == 1)
.where(salary_condition)
.where(account == filters.get("account"))
.where(posting_date > getdate(filters.get("report_date")))
.where(ifnull(loan_doc.clearance_date, "4000-01-01") <= getdate(filters.get("report_date")))

View File

@@ -263,7 +263,10 @@ def get_report_summary(summary_data, currency):
def get_chart_data(columns, data):
labels = [d.get("label") for d in columns[2:]]
datasets = [
{"name": account.get("account").replace("'", ""), "values": [account.get("total")]}
{
"name": account.get("account").replace("'", ""),
"values": [account.get(d.get("fieldname")) for d in columns[2:]],
}
for account in data
if account.get("parent_account") == None and account.get("currency")
]

View File

@@ -539,7 +539,7 @@ def get_additional_conditions(from_date, ignore_closing_entries, filters):
)
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
else:
additional_conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
additional_conditions.append("{0} in %({0})s".format(dimension.fieldname))
return " and {}".format(" and ".join(additional_conditions)) if additional_conditions else ""

View File

@@ -318,7 +318,7 @@ def get_conditions(filters):
)
conditions.append("{0} in %({0})s".format(dimension.fieldname))
else:
conditions.append("{0} in (%({0})s)".format(dimension.fieldname))
conditions.append("{0} in %({0})s".format(dimension.fieldname))
return "and {}".format(" and ".join(conditions)) if conditions else ""
@@ -478,7 +478,13 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
gle_map[group_by_value].entries.append(gle)
elif group_by_voucher_consolidated:
keylist = [gle.get("voucher_type"), gle.get("voucher_no"), gle.get("account")]
keylist = [
gle.get("voucher_type"),
gle.get("voucher_no"),
gle.get("account"),
gle.get("party_type"),
gle.get("party"),
]
if filters.get("include_dimensions"):
for dim in accounting_dimensions:
keylist.append(gle.get(dim))

View File

@@ -62,7 +62,7 @@ def get_pos_entries(filters, group_by_field):
"""
SELECT
p.posting_date, p.name as pos_invoice, p.pos_profile,
p.owner, p.base_grand_total as grand_total, p.base_paid_amount as paid_amount,
p.owner, p.base_grand_total as grand_total, p.base_paid_amount - p.change_amount as paid_amount,
p.customer, p.is_return {select_mop_field}
FROM
`tabPOS Invoice` p {from_sales_invoice_payment}

View File

@@ -228,6 +228,7 @@ def set_gl_entries_by_account(
{additional_conditions}
and posting_date <= %(to_date)s
and {based_on} is not null
and is_cancelled = 0
order by {based_on}, posting_date""".format(
additional_conditions="\n".join(additional_conditions), based_on=based_on
),

View File

@@ -124,11 +124,10 @@ def get_columns(invoice_list, additional_table_columns):
_("Purchase Receipt") + ":Link/Purchase Receipt:100",
{"fieldname": "currency", "label": _("Currency"), "fieldtype": "Data", "width": 80},
]
expense_accounts = (
tax_accounts
) = (
expense_columns
) = tax_columns = unrealized_profit_loss_accounts = unrealized_profit_loss_account_columns = []
expense_accounts = []
tax_accounts = []
unrealized_profit_loss_accounts = []
if invoice_list:
expense_accounts = frappe.db.sql_list(
@@ -163,10 +162,11 @@ def get_columns(invoice_list, additional_table_columns):
unrealized_profit_loss_account_columns = [
(account + ":Currency/currency:120") for account in unrealized_profit_loss_accounts
]
for account in tax_accounts:
if account not in expense_accounts:
tax_columns.append(account + ":Currency/currency:120")
tax_columns = [
(account + ":Currency/currency:120")
for account in tax_accounts
if account not in expense_accounts
]
columns = (
columns
@@ -237,7 +237,7 @@ def get_conditions(filters):
else:
conditions += (
common_condition
+ "and ifnull(`tabPurchase Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
+ "and ifnull(`tabPurchase Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
return conditions

View File

@@ -405,7 +405,7 @@ def get_conditions(filters):
else:
conditions += (
common_condition
+ "and ifnull(`tabSales Invoice Item`.{0}, '') in (%({0})s))".format(dimension.fieldname)
+ "and ifnull(`tabSales Invoice Item`.{0}, '') in %({0})s)".format(dimension.fieldname)
)
return conditions

View File

@@ -188,9 +188,9 @@ def get_rootwise_opening_balances(filters, report_type):
filters[dimension.fieldname] = get_dimension_with_children(
dimension.document_type, filters.get(dimension.fieldname)
)
additional_conditions += "and {0} in %({0})s".format(dimension.fieldname)
additional_conditions += " and {0} in %({0})s".format(dimension.fieldname)
else:
additional_conditions += "and {0} in (%({0})s)".format(dimension.fieldname)
additional_conditions += " and {0} in %({0})s".format(dimension.fieldname)
query_filters.update({dimension.fieldname: filters.get(dimension.fieldname)})

View File

@@ -1,10 +1,17 @@
import unittest
import frappe
from frappe.test_runner import make_test_objects
from erpnext.accounts.party import get_party_shipping_address
from erpnext.accounts.utils import get_future_stock_vouchers, get_voucherwise_gl_entries
from erpnext.accounts.utils import (
get_future_stock_vouchers,
get_voucherwise_gl_entries,
sort_stock_vouchers_by_posting_date,
)
from erpnext.stock.doctype.item.test_item import make_item
from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import make_purchase_receipt
from erpnext.stock.doctype.stock_entry.stock_entry_utils import make_stock_entry
class TestUtils(unittest.TestCase):
@@ -47,6 +54,25 @@ class TestUtils(unittest.TestCase):
msg="get_voucherwise_gl_entries not returning expected GLes",
)
def test_stock_voucher_sorting(self):
vouchers = []
item = make_item().name
stock_entry = {"item": item, "to_warehouse": "_Test Warehouse - _TC", "qty": 1, "rate": 10}
se1 = make_stock_entry(posting_date="2022-01-01", **stock_entry)
se2 = make_stock_entry(posting_date="2022-02-01", **stock_entry)
se3 = make_stock_entry(posting_date="2022-03-01", **stock_entry)
for doc in (se1, se2, se3):
vouchers.append((doc.doctype, doc.name))
vouchers.append(("Stock Entry", "Wat"))
sorted_vouchers = sort_stock_vouchers_by_posting_date(list(reversed(vouchers)))
self.assertEqual(sorted_vouchers, vouchers)
ADDRESS_RECORDS = [
{

View File

@@ -3,6 +3,7 @@
from json import loads
from typing import List, Tuple
import frappe
import frappe.defaults
@@ -19,10 +20,6 @@ from erpnext.stock import get_warehouse_account_map
from erpnext.stock.utils import get_stock_value_on
class StockValueAndAccountBalanceOutOfSync(frappe.ValidationError):
pass
class FiscalYearError(frappe.ValidationError):
pass
@@ -1127,6 +1124,9 @@ def update_gl_entries_after(
def repost_gle_for_stock_vouchers(
stock_vouchers, posting_date, company=None, warehouse_account=None
):
if not stock_vouchers:
return
def _delete_gl_entries(voucher_type, voucher_no):
frappe.db.sql(
"""delete from `tabGL Entry`
@@ -1134,6 +1134,8 @@ def repost_gle_for_stock_vouchers(
(voucher_type, voucher_no),
)
stock_vouchers = sort_stock_vouchers_by_posting_date(stock_vouchers)
if not warehouse_account:
warehouse_account = get_warehouse_account_map(company)
@@ -1154,6 +1156,27 @@ def repost_gle_for_stock_vouchers(
_delete_gl_entries(voucher_type, voucher_no)
def sort_stock_vouchers_by_posting_date(
stock_vouchers: List[Tuple[str, str]]
) -> List[Tuple[str, str]]:
sle = frappe.qb.DocType("Stock Ledger Entry")
voucher_nos = [v[1] for v in stock_vouchers]
sles = (
frappe.qb.from_(sle)
.select(sle.voucher_type, sle.voucher_no, sle.posting_date, sle.posting_time, sle.creation)
.where((sle.is_cancelled == 0) & (sle.voucher_no.isin(voucher_nos)))
.groupby(sle.voucher_type, sle.voucher_no)
).run(as_dict=True)
sorted_vouchers = [(sle.voucher_type, sle.voucher_no) for sle in sles]
unknown_vouchers = set(stock_vouchers) - set(sorted_vouchers)
if unknown_vouchers:
sorted_vouchers.extend(unknown_vouchers)
return sorted_vouchers
def get_future_stock_vouchers(
posting_date, posting_time, for_warehouses=None, for_items=None, company=None
):
@@ -1247,47 +1270,6 @@ def compare_existing_and_expected_gle(existing_gle, expected_gle, precision):
return matched
def check_if_stock_and_account_balance_synced(
posting_date, company, voucher_type=None, voucher_no=None
):
if not cint(erpnext.is_perpetual_inventory_enabled(company)):
return
accounts = get_stock_accounts(company, voucher_type, voucher_no)
stock_adjustment_account = frappe.db.get_value("Company", company, "stock_adjustment_account")
for account in accounts:
account_bal, stock_bal, warehouse_list = get_stock_and_account_balance(
account, posting_date, company
)
if abs(account_bal - stock_bal) > 0.1:
precision = get_field_precision(
frappe.get_meta("GL Entry").get_field("debit"),
currency=frappe.get_cached_value("Company", company, "default_currency"),
)
diff = flt(stock_bal - account_bal, precision)
error_reason = _(
"Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses as on {3}."
).format(stock_bal, account_bal, frappe.bold(account), posting_date)
error_resolution = _("Please create an adjustment Journal Entry for amount {0} on {1}").format(
frappe.bold(diff), frappe.bold(posting_date)
)
frappe.msgprint(
msg="""{0}<br></br>{1}<br></br>""".format(error_reason, error_resolution),
raise_exception=StockValueAndAccountBalanceOutOfSync,
title=_("Values Out Of Sync"),
primary_action={
"label": _("Make Journal Entry"),
"client_action": "erpnext.route_to_adjustment_jv",
"args": get_journal_entry(account, stock_adjustment_account, diff),
},
)
def get_stock_accounts(company, voucher_type=None, voucher_no=None):
stock_accounts = [
d.name

View File

@@ -353,18 +353,18 @@ class Asset(AccountsController):
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
month_range = (
months
if (has_pro_rata and n == 0)
or (has_pro_rata and n == cint(number_of_pending_depreciations) - 1)
else finance_book.frequency_of_depreciation
)
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:
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)
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
@@ -628,7 +628,7 @@ class Asset(AccountsController):
asset_value_after_full_schedule = flt(
flt(self.gross_purchase_amount) - flt(accumulated_depreciation_after_full_schedule),
self.precision("gross_purchase_amount"),
row.precision("expected_value_after_useful_life"),
)
if (

View File

@@ -41,40 +41,46 @@ class AssetRepair(AccountsController):
if self.get("stock_consumption") or self.get("capitalize_repair_cost"):
self.increase_asset_value()
if self.get("stock_consumption"):
self.check_for_stock_items_and_warehouse()
self.decrease_stock_quantity()
if self.get("capitalize_repair_cost"):
self.make_gl_entries()
if (
frappe.db.get_value("Asset", self.asset, "calculate_depreciation")
and self.increase_in_asset_life
):
self.modify_depreciation_schedule()
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.asset_doc.prepare_depreciation_data()
self.asset_doc.save()
if self.get("stock_consumption"):
self.check_for_stock_items_and_warehouse()
self.decrease_stock_quantity()
if self.get("capitalize_repair_cost"):
self.make_gl_entries()
if (
frappe.db.get_value("Asset", self.asset, "calculate_depreciation")
and self.increase_in_asset_life
):
self.modify_depreciation_schedule()
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.asset_doc.prepare_depreciation_data()
self.asset_doc.save()
def before_cancel(self):
self.asset_doc = frappe.get_doc("Asset", self.asset)
if self.get("stock_consumption") or self.get("capitalize_repair_cost"):
self.decrease_asset_value()
if self.get("stock_consumption"):
self.increase_stock_quantity()
if self.get("capitalize_repair_cost"):
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
self.make_gl_entries(cancel=True)
if (
frappe.db.get_value("Asset", self.asset, "calculate_depreciation")
and self.increase_in_asset_life
):
self.revert_depreciation_schedule_on_cancellation()
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.asset_doc.prepare_depreciation_data()
self.asset_doc.save()
if self.get("stock_consumption"):
self.increase_stock_quantity()
if self.get("capitalize_repair_cost"):
self.ignore_linked_doctypes = ("GL Entry", "Stock Ledger Entry")
self.make_gl_entries(cancel=True)
if (
frappe.db.get_value("Asset", self.asset, "calculate_depreciation")
and self.increase_in_asset_life
):
self.revert_depreciation_schedule_on_cancellation()
self.asset_doc.flags.ignore_validate_update_after_submit = True
self.asset_doc.prepare_depreciation_data()
self.asset_doc.save()
def check_repair_status(self):
if self.repair_status == "Pending":

View File

@@ -23,6 +23,10 @@
"order_confirmation_no",
"order_confirmation_date",
"amended_from",
"accounting_dimensions_section",
"cost_center",
"dimension_col_break",
"project",
"drop_ship",
"customer",
"customer_name",
@@ -1138,16 +1142,39 @@
"fieldtype": "Link",
"label": "Tax Withholding Category",
"options": "Tax Withholding Category"
},
{
"collapsible": 1,
"fieldname": "accounting_dimensions_section",
"fieldtype": "Section Break",
"label": "Accounting Dimensions "
},
{
"fieldname": "cost_center",
"fieldtype": "Link",
"label": "Cost Center",
"options": "Cost Center"
},
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "project",
"fieldtype": "Link",
"label": "Project",
"options": "Project"
}
],
"icon": "fa fa-file-text",
"idx": 105,
"is_submittable": 1,
"links": [],
"modified": "2021-09-28 13:10:47.955401",
"modified": "2022-04-26 12:16:38.694276",
"modified_by": "Administrator",
"module": "Buying",
"name": "Purchase Order",
"naming_rule": "By \"Naming Series\" field",
"owner": "Administrator",
"permissions": [
{
@@ -1194,6 +1221,7 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"timeline_field": "supplier",
"title_field": "supplier_name",
"track_changes": 1

View File

@@ -637,6 +637,8 @@ def make_rm_stock_entry(purchase_order, rm_items):
}
}
stock_entry.add_to_stock_entry_detail(items_dict)
stock_entry.set_missing_values()
return stock_entry.as_dict()
else:
frappe.throw(_("No Items selected for transfer"))
@@ -724,7 +726,7 @@ def make_return_stock_entry_for_subcontract(available_materials, po_doc, po_deta
add_items_in_ste(ste_doc, value, value.qty, po_details)
ste_doc.set_stock_entry_type()
ste_doc.calculate_rate_and_amount()
ste_doc.set_missing_values()
return ste_doc

View File

@@ -31,7 +31,7 @@ frappe.ui.form.on("Request for Quotation",{
if (frm.doc.docstatus === 1) {
frm.add_custom_button(__('Supplier Quotation'),
function(){ frm.trigger("make_suppplier_quotation") }, __("Create"));
function(){ frm.trigger("make_supplier_quotation") }, __("Create"));
frm.add_custom_button(__("Send Emails to Suppliers"), function() {
@@ -87,16 +87,24 @@ frappe.ui.form.on("Request for Quotation",{
},
make_suppplier_quotation: function(frm) {
make_supplier_quotation: function(frm) {
var doc = frm.doc;
var dialog = new frappe.ui.Dialog({
title: __("Create Supplier Quotation"),
fields: [
{ "fieldtype": "Select", "label": __("Supplier"),
{ "fieldtype": "Link",
"label": __("Supplier"),
"fieldname": "supplier",
"options": doc.suppliers.map(d => d.supplier),
"options": 'Supplier',
"reqd": 1,
"default": doc.suppliers.length === 1 ? doc.suppliers[0].supplier_name : "" },
get_query: () => {
return {
filters: [
["Supplier", "name", "in", frm.doc.suppliers.map((row) => {return row.supplier;})]
]
}
}
}
],
primary_action_label: __("Create"),
primary_action: (args) => {

View File

@@ -32,7 +32,9 @@
"terms",
"printing_settings",
"select_print_heading",
"letter_head"
"letter_head",
"more_info",
"opportunity"
],
"fields": [
{
@@ -193,6 +195,23 @@
"options": "Letter Head",
"print_hide": 1
},
{
"collapsible": 1,
"fieldname": "more_info",
"fieldtype": "Section Break",
"label": "More Information",
"oldfieldtype": "Section Break",
"options": "fa fa-file-text",
"print_hide": 1
},
{
"fieldname": "opportunity",
"fieldtype": "Link",
"label": "Opportunity",
"options": "Opportunity",
"print_hide": 1,
"read_only": 1
},
{
"fieldname": "status",
"fieldtype": "Select",
@@ -258,7 +277,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-11-24 17:47:49.909000",
"modified": "2022-04-06 17:47:49.909000",
"modified_by": "Administrator",
"module": "Buying",
"name": "Request for Quotation",
@@ -327,4 +346,4 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC"
}
}

View File

@@ -0,0 +1,31 @@
## Version 13.26.0 Release Notes
### Features & Enhancements
- feat: Receivable/Payable Account column and filter in AR/AP report ([#30620](https://github.com/frappe/erpnext/pull/30620))
- feat(india): e-invoicing for intra-state union territory transactions ([#30626](https://github.com/frappe/erpnext/pull/30626))
- feat: Ignore permlevel for specific fields ([#30686](https://github.com/frappe/erpnext/pull/30686))
- feat: 'customer' column and more filter to Payment terms status report ([#30499](https://github.com/frappe/erpnext/pull/30499))
### Fixes
- fix: fallback to item_name if description is not found ([#30619](https://github.com/frappe/erpnext/pull/30619))
- fix: Deferred Revenue/Expense Account validation ([#30602](https://github.com/frappe/erpnext/pull/30602))
- fix(pos): reload doc before set value ([#30610](https://github.com/frappe/erpnext/pull/30610))
- fix: Exchange gain and loss button in Payment Entry ([#30606](https://github.com/frappe/erpnext/pull/30606))
- fix(pos): cannot change paid amount in pos payments ([#30657](https://github.com/frappe/erpnext/pull/30657))
- fix: hide pending qty only if original item is assigned ([#30599](https://github.com/frappe/erpnext/pull/30599))
- fix(pos): reload doc before set value ([#30611](https://github.com/frappe/erpnext/pull/30611))
- fix: Handle multiple item transfer in separate SEs against WO ([#30674](https://github.com/frappe/erpnext/pull/30674))
- fix(patch): check null values in is_cancelled patch ([#30594](https://github.com/frappe/erpnext/pull/30594))
- fix: Download JSON for GSTR-1 report ([#30651](https://github.com/frappe/erpnext/pull/30651))
- fix: remove bad defaults from BOM operation ([#30644](https://github.com/frappe/erpnext/pull/30644))
- fix: update translation ([#30474](https://github.com/frappe/erpnext/pull/30474))
- fix: dont reassign mutable (list) to a different field ([#30634](https://github.com/frappe/erpnext/pull/30634))
- fix: update translation ([#30654](https://github.com/frappe/erpnext/pull/30654))
- fix: ignore item-less maintenance visit for sr no ([#30684](https://github.com/frappe/erpnext/pull/30684))
- fix: removed unused courses template ([#30596](https://github.com/frappe/erpnext/pull/30596))
- fix: Implicit ignore pricing rule check on returns ([#30662](https://github.com/frappe/erpnext/pull/30662))
- fix: warehouse naming when suffix is present ([#30621](https://github.com/frappe/erpnext/pull/30621))
- fix: Ignore disabled tax categories ([#30542](https://github.com/frappe/erpnext/pull/30542))

View File

@@ -35,6 +35,7 @@ from erpnext.accounts.doctype.pricing_rule.utils import (
from erpnext.accounts.party import (
get_party_account,
get_party_account_currency,
get_party_gle_currency,
validate_party_frozen_disabled,
)
from erpnext.accounts.utils import get_account_currency, get_fiscal_years, validate_fiscal_year
@@ -149,6 +150,7 @@ class AccountsController(TransactionBase):
self.validate_inter_company_reference()
self.disable_pricing_rule_on_internal_transfer()
self.set_incoming_rate()
if self.meta.get_field("currency"):
@@ -168,6 +170,7 @@ class AccountsController(TransactionBase):
self.validate_party()
self.validate_currency()
self.validate_party_account_currency()
if self.doctype in ["Purchase Invoice", "Sales Invoice"]:
pos_check_field = "is_pos" if self.doctype == "Sales Invoice" else "is_paid"
@@ -181,6 +184,7 @@ class AccountsController(TransactionBase):
else:
self.validate_deferred_start_and_end_date()
self.validate_deferred_income_expense_account()
self.set_inter_company_account()
if self.doctype == "Purchase Invoice":
@@ -209,6 +213,27 @@ class AccountsController(TransactionBase):
(self.doctype, self.name),
)
def validate_deferred_income_expense_account(self):
field_map = {
"Sales Invoice": "deferred_revenue_account",
"Purchase Invoice": "deferred_expense_account",
}
for item in self.get("items"):
if item.get("enable_deferred_revenue") or item.get("enable_deferred_expense"):
if not item.get(field_map.get(self.doctype)):
default_deferred_account = frappe.db.get_value(
"Company", self.company, "default_" + field_map.get(self.doctype)
)
if not default_deferred_account:
frappe.throw(
_(
"Row #{0}: Please update deferred revenue/expense account in item row or default account in company master"
).format(item.idx)
)
else:
item.set(field_map.get(self.doctype), default_deferred_account)
def validate_deferred_start_and_end_date(self):
for d in self.items:
if d.get("enable_deferred_revenue") or d.get("enable_deferred_expense"):
@@ -361,6 +386,14 @@ class AccountsController(TransactionBase):
msg += _("Please create purchase from internal sale or delivery document itself")
frappe.throw(msg, title=_("Internal Sales Reference Missing"))
def disable_pricing_rule_on_internal_transfer(self):
if not self.get("ignore_pricing_rule") and self.is_internal_transfer():
self.ignore_pricing_rule = 1
frappe.msgprint(
_("Disabled pricing rules since this {} is an internal transfer").format(self.doctype),
alert=1,
)
def validate_due_date(self):
if self.get("is_pos"):
return
@@ -1095,11 +1128,10 @@ class AccountsController(TransactionBase):
{
"account": item.discount_account,
"against": supplier_or_customer,
dr_or_cr: flt(discount_amount, item.precision("discount_amount")),
dr_or_cr
+ "_in_account_currency": flt(
dr_or_cr: flt(
discount_amount * self.get("conversion_rate"), item.precision("discount_amount")
),
dr_or_cr + "_in_account_currency": flt(discount_amount, item.precision("discount_amount")),
"cost_center": item.cost_center,
"project": item.project,
},
@@ -1114,11 +1146,11 @@ class AccountsController(TransactionBase):
{
"account": income_or_expense_account,
"against": supplier_or_customer,
rev_dr_cr: flt(discount_amount, item.precision("discount_amount")),
rev_dr_cr
+ "_in_account_currency": flt(
rev_dr_cr: flt(
discount_amount * self.get("conversion_rate"), item.precision("discount_amount")
),
rev_dr_cr
+ "_in_account_currency": flt(discount_amount, item.precision("discount_amount")),
"cost_center": item.cost_center,
"project": item.project or self.project,
},
@@ -1415,6 +1447,27 @@ class AccountsController(TransactionBase):
# at quotation / sales order level and we shouldn't stop someone
# from creating a sales invoice if sales order is already created
def validate_party_account_currency(self):
if self.doctype not in ("Sales Invoice", "Purchase Invoice"):
return
if self.is_opening == "Yes":
return
party_type, party = self.get_party()
party_gle_currency = get_party_gle_currency(party_type, party, self.company)
party_account = (
self.get("debit_to") if self.doctype == "Sales Invoice" else self.get("credit_to")
)
party_account_currency = get_account_currency(party_account)
if not party_gle_currency and (party_account_currency != self.currency):
frappe.throw(
_("Party Account {0} currency and document currency should be same").format(
frappe.bold(party_account)
)
)
def delink_advance_entries(self, linked_doc_name):
total_allocated_amount = 0
for adv in self.advances:
@@ -1714,6 +1767,8 @@ class AccountsController(TransactionBase):
internal_party_field = "is_internal_customer"
elif self.doctype in ("Purchase Invoice", "Purchase Receipt", "Purchase Order"):
internal_party_field = "is_internal_supplier"
else:
return False
if self.get(internal_party_field) and (self.represents_company == self.company):
return True
@@ -1978,12 +2033,13 @@ def get_advance_journal_entries(
reference_condition = " and (" + " or ".join(conditions) + ")" if conditions else ""
# nosemgrep
journal_entries = frappe.db.sql(
"""
select
"Journal Entry" as reference_type, t1.name as reference_name,
t1.remark as remarks, t2.{0} as amount, t2.name as reference_row,
t2.reference_name as against_order
t2.reference_name as against_order, t2.exchange_rate
from
`tabJournal Entry` t1, `tabJournal Entry Account` t2
where
@@ -2426,11 +2482,21 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
parent_doctype, parent_doctype_name, child_doctype, child_docname, item_row
)
def validate_quantity(child_item, d):
if parent_doctype == "Sales Order" and flt(d.get("qty")) < flt(child_item.delivered_qty):
def validate_quantity(child_item, new_data):
if not flt(new_data.get("qty")):
frappe.throw(
_("Row # {0}: Quantity for Item {1} cannot be zero").format(
new_data.get("idx"), frappe.bold(new_data.get("item_code"))
),
title=_("Invalid Qty"),
)
if parent_doctype == "Sales Order" and flt(new_data.get("qty")) < flt(child_item.delivered_qty):
frappe.throw(_("Cannot set quantity less than delivered quantity"))
if parent_doctype == "Purchase Order" and flt(d.get("qty")) < flt(child_item.received_qty):
if parent_doctype == "Purchase Order" and flt(new_data.get("qty")) < flt(
child_item.received_qty
):
frappe.throw(_("Cannot set quantity less than received quantity"))
data = json.loads(trans_items)

View File

@@ -22,6 +22,9 @@ class QtyMismatchError(ValidationError):
class BuyingController(StockController, Subcontracting):
def __setup__(self):
self.flags.ignore_permlevel_for_fields = ["buying_price_list", "price_list_currency"]
def get_feed(self):
if self.get("supplier_name"):
return _("From {0} | {1} {2}").format(self.supplier_name, self.currency, self.grand_total)
@@ -303,14 +306,15 @@ class BuyingController(StockController, Subcontracting):
if self.is_internal_transfer():
if rate != d.rate:
d.rate = rate
d.discount_percentage = 0
d.discount_amount = 0
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
)
d.discount_percentage = 0.0
d.discount_amount = 0.0
d.margin_rate_or_amount = 0.0
def get_supplied_items_cost(self, item_row_id, reset_outgoing_rate=True):
supplied_items_cost = 0.0

View File

@@ -162,6 +162,7 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
{account_type_condition}
AND is_group = 0
AND company = %(company)s
AND disabled = %(disabled)s
AND (account_currency = %(currency)s or ifnull(account_currency, '') = '')
AND `{searchfield}` LIKE %(txt)s
{mcond}
@@ -175,6 +176,7 @@ def tax_account_query(doctype, txt, searchfield, start, page_len, filters):
dict(
account_types=filters.get("account_type"),
company=filters.get("company"),
disabled=filters.get("disabled", 0),
currency=company_currency,
txt="%{}%".format(txt),
offset=start,

View File

@@ -330,7 +330,6 @@ def make_return_doc(doctype, source_name, target_doc=None):
doc = frappe.get_doc(target)
doc.is_return = 1
doc.return_against = source.name
doc.ignore_pricing_rule = 1
doc.set_warehouse = ""
if doctype == "Sales Invoice" or doctype == "POS Invoice":
doc.is_pos = source.is_pos

View File

@@ -16,6 +16,9 @@ from erpnext.stock.utils import get_incoming_rate
class SellingController(StockController):
def __setup__(self):
self.flags.ignore_permlevel_for_fields = ["selling_price_list", "price_list_currency"]
def get_feed(self):
return _("To {0} | {1} {2}").format(self.customer_name, self.currency, self.grand_total)
@@ -443,15 +446,16 @@ class SellingController(StockController):
rate = flt(d.incoming_rate * d.conversion_factor, d.precision("rate"))
if d.rate != rate:
d.rate = rate
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
)
d.discount_percentage = 0
d.discount_amount = 0
frappe.msgprint(
_(
"Row {0}: Item rate has been updated as per valuation rate since its an internal stock transfer"
).format(d.idx),
alert=1,
)
d.discount_percentage = 0.0
d.discount_amount = 0.0
d.margin_rate_or_amount = 0.0
elif self.get("return_against"):
# Get incoming rate of return entry from reference document

View File

@@ -8,7 +8,7 @@ import frappe
from frappe import _
from frappe.email.inbox import link_communication_to_document
from frappe.model.mapper import get_mapped_doc
from frappe.utils import cint, cstr, get_fullname
from frappe.utils import cint, get_fullname
from erpnext.accounts.party import get_party_account_currency
from erpnext.setup.utils import get_exchange_rate
@@ -193,20 +193,20 @@ class Opportunity(TransactionBase):
if self.party_name and self.opportunity_from == "Customer":
if self.contact_person:
opts.description = "Contact " + cstr(self.contact_person)
opts.description = f"Contact {self.contact_person}"
else:
opts.description = "Contact customer " + cstr(self.party_name)
opts.description = f"Contact customer {self.party_name}"
elif self.party_name and self.opportunity_from == "Lead":
if self.contact_display:
opts.description = "Contact " + cstr(self.contact_display)
opts.description = f"Contact {self.contact_display}"
else:
opts.description = "Contact lead " + cstr(self.party_name)
opts.description = f"Contact lead {self.party_name}"
opts.subject = opts.description
opts.description += ". By : " + cstr(self.contact_by)
opts.description += f". By : {self.contact_by}"
if self.to_discuss:
opts.description += " To Discuss : " + cstr(self.to_discuss)
opts.description += f" To Discuss : {frappe.render_template(self.to_discuss, {'doc': self})}"
super(Opportunity, self).add_calendar_event(opts, force)

View File

@@ -2,6 +2,6 @@ def get_data():
return {
"fieldname": "opportunity",
"transactions": [
{"items": ["Quotation", "Supplier Quotation"]},
{"items": ["Quotation", "Request for Quotation", "Supplier Quotation"]},
],
}

View File

@@ -4,7 +4,7 @@
import unittest
import frappe
from frappe.utils import random_string, today
from frappe.utils import add_days, now_datetime, random_string, today
from erpnext.crm.doctype.lead.lead import make_customer
from erpnext.crm.doctype.opportunity.opportunity import make_quotation
@@ -58,6 +58,22 @@ class TestOpportunity(unittest.TestCase):
self.assertEqual(opp_doc.opportunity_from, "Customer")
self.assertEqual(opp_doc.party_name, customer.name)
def test_render_template_for_to_discuss(self):
doc = make_opportunity(with_items=0, opportunity_from="Lead")
doc.contact_by = "test@example.com"
doc.contact_date = add_days(today(), days=2)
doc.to_discuss = "{{ doc.name }} test data"
doc.save()
event = frappe.get_all(
"Event Participants",
fields=["parent"],
filters={"reference_doctype": doc.doctype, "reference_docname": doc.name},
)
event_description = frappe.db.get_value("Event", event[0].parent, "description")
self.assertTrue(doc.name in event_description)
def make_opportunity(**args):
args = frappe._dict(args)

View File

@@ -24,17 +24,17 @@ frappe.ui.form.on("E Commerce Settings", {
);
}
frappe.model.with_doctype("Item", () => {
frappe.model.with_doctype("Website Item", () => {
const web_item_meta = frappe.get_meta('Website Item');
const valid_fields = web_item_meta.fields.filter(
df => ["Link", "Table MultiSelect"].includes(df.fieldtype) && !df.hidden
).map(df => ({ label: df.label, value: df.fieldname }));
frm.fields_dict.filter_fields.grid.update_docfield_property(
frm.get_field("filter_fields").grid.update_docfield_property(
'fieldname', 'fieldtype', 'Select'
);
frm.fields_dict.filter_fields.grid.update_docfield_property(
frm.get_field("filter_fields").grid.update_docfield_property(
'fieldname', 'options', valid_fields
);
});

View File

@@ -26,7 +26,7 @@ class ECommerceSettings(Document):
self.is_redisearch_loaded = is_search_module_loaded()
def validate(self):
self.validate_field_filters()
self.validate_field_filters(self.filter_fields, self.enable_field_filters)
self.validate_attribute_filters()
self.validate_checkout()
self.validate_search_index_fields()
@@ -50,21 +50,22 @@ class ECommerceSettings(Document):
define_autocomplete_dictionary()
create_website_items_index()
def validate_field_filters(self):
if not (self.enable_field_filters and self.filter_fields):
@staticmethod
def validate_field_filters(filter_fields, enable_field_filters):
if not (enable_field_filters and filter_fields):
return
item_meta = frappe.get_meta("Item")
web_item_meta = frappe.get_meta("Website Item")
valid_fields = [
df.fieldname for df in item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
df.fieldname for df in web_item_meta.fields if df.fieldtype in ["Link", "Table MultiSelect"]
]
for f in self.filter_fields:
if f.fieldname not in valid_fields:
for row in filter_fields:
if row.fieldname not in valid_fields:
frappe.throw(
_(
"Filter Fields Row #{0}: Fieldname <b>{1}</b> must be of type 'Link' or 'Table MultiSelect'"
).format(f.idx, f.fieldname)
"Filter Fields Row #{0}: Fieldname {1} must be of type 'Link' or 'Table MultiSelect'"
).format(row.idx, frappe.bold(row.fieldname))
)
def validate_attribute_filters(self):

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2021, Frappe Technologies Pvt. Ltd. and Contributors
# Copyright (c) 2022, Frappe Technologies Pvt. Ltd. and Contributors
# See license.txt
import unittest
@@ -11,42 +11,34 @@ from erpnext.e_commerce.doctype.e_commerce_settings.e_commerce_settings import (
class TestECommerceSettings(unittest.TestCase):
def setUp(self):
frappe.db.sql("""delete from `tabSingles` where doctype="Shipping Cart Settings" """)
def get_cart_settings(self):
return frappe.get_doc({"doctype": "E Commerce Settings", "company": "_Test Company"})
# NOTE: Exchangrate API has all enabled currencies that ERPNext supports.
# We aren't checking just currency exchange record anymore
# while validating price list currency exchange rate to that of company.
# The API is being used to fetch the rate which again almost always
# gives back a valid value (for valid currencies).
# This makes the test obsolete.
# Commenting because im not sure if there's a better test we can write
# def test_exchange_rate_exists(self):
# frappe.db.sql("""delete from `tabCurrency Exchange`""")
# cart_settings = self.get_cart_settings()
# cart_settings.price_list = "_Test Price List Rest of the World"
# self.assertRaises(ShoppingCartSetupError, cart_settings.validate_price_list_exchange_rate)
# from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records as \
# currency_exchange_records
# frappe.get_doc(currency_exchange_records[0]).insert()
# cart_settings.validate_price_list_exchange_rate()
def tearDown(self):
frappe.db.rollback()
def test_tax_rule_validation(self):
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 0")
cart_settings = self.get_cart_settings()
cart_settings = frappe.get_doc("E Commerce Settings")
cart_settings.enabled = 1
if not frappe.db.get_value("Tax Rule", {"use_for_shopping_cart": 1}, "name"):
self.assertRaises(ShoppingCartSetupError, cart_settings.validate_tax_rule)
frappe.db.sql("update `tabTax Rule` set use_for_shopping_cart = 1")
def test_invalid_filter_fields(self):
"Check if Item fields are blocked in E Commerce Settings filter fields."
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
setup_e_commerce_settings({"enable_field_filters": 1})
create_custom_field(
"Item",
dict(owner="Administrator", fieldname="test_data", label="Test", fieldtype="Data"),
)
settings = frappe.get_doc("E Commerce Settings")
settings.append("filter_fields", {"fieldname": "test_data"})
self.assertRaises(frappe.ValidationError, settings.save)
def setup_e_commerce_settings(values_dict):
"Accepts a dict of values that updates E Commerce Settings."

View File

@@ -22,12 +22,14 @@ class ProductFiltersBuilder:
fields, filter_data = [], []
filter_fields = [row.fieldname for row in self.doc.filter_fields] # fields in settings
# filter valid field filters i.e. those that exist in Item
item_meta = frappe.get_meta("Item", cached=True)
fields = [item_meta.get_field(field) for field in filter_fields if item_meta.has_field(field)]
# filter valid field filters i.e. those that exist in Website Item
web_item_meta = frappe.get_meta("Website Item", cached=True)
fields = [
web_item_meta.get_field(field) for field in filter_fields if web_item_meta.has_field(field)
]
for df in fields:
item_filters, item_or_filters = {"published_in_website": 1}, []
item_filters, item_or_filters = {"published": 1}, []
link_doctype_values = self.get_filtered_link_doctype_records(df)
if df.fieldtype == "Link":
@@ -50,9 +52,13 @@ class ProductFiltersBuilder:
]
)
# exclude variants if mentioned in settings
if frappe.db.get_single_value("E Commerce Settings", "hide_variants"):
item_filters["variant_of"] = ["is", "not set"]
# Get link field values attached to published items
item_values = frappe.get_all(
"Item",
"Website Item",
fields=[df.fieldname],
filters=item_filters,
or_filters=item_or_filters,

View File

@@ -277,6 +277,54 @@ class TestProductDataEngine(unittest.TestCase):
# tear down
setup_e_commerce_settings({"enable_attribute_filters": 1, "hide_variants": 0})
def test_custom_field_as_filter(self):
"Test if custom field functions as filter correctly."
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
create_custom_field(
"Website Item",
dict(
owner="Administrator",
fieldname="supplier",
label="Supplier",
fieldtype="Link",
options="Supplier",
insert_after="on_backorder",
),
)
frappe.db.set_value(
"Website Item", {"item_code": "Test 11I Laptop"}, "supplier", "_Test Supplier"
)
frappe.db.set_value(
"Website Item", {"item_code": "Test 12I Laptop"}, "supplier", "_Test Supplier 1"
)
settings = frappe.get_doc("E Commerce Settings")
settings.append("filter_fields", {"fieldname": "supplier"})
settings.save()
filter_engine = ProductFiltersBuilder()
field_filters = filter_engine.get_field_filters()
custom_filter = field_filters[1]
filter_values = custom_filter[1]
self.assertEqual(custom_filter[0].options, "Supplier")
self.assertEqual(len(filter_values), 2)
self.assertIn("_Test Supplier", filter_values)
# test if custom filter works in query
field_filters = {"supplier": "_Test Supplier 1"}
engine = ProductQuery()
result = engine.query(
attributes={}, fields=field_filters, search_term=None, start=0, item_group=None
)
items = result.get("items")
# check if only 'Raw Material' are fetched in the right order
self.assertEqual(len(items), 1)
self.assertEqual(items[0].get("item_code"), "Test 12I Laptop")
def create_variant_web_item():
"Create Variant and Template Website Items."

View File

@@ -4,6 +4,7 @@ import frappe
from frappe import _
from frappe.utils import cint, cstr, flt, get_datetime, get_request_session, getdate, nowdate
from erpnext import get_company_currency
from erpnext.erpnext_integrations.doctype.shopify_log.shopify_log import (
dump_request_data,
make_shopify_log,
@@ -143,6 +144,10 @@ def create_sales_order(shopify_order, shopify_settings, company=None):
"taxes": get_order_taxes(shopify_order, shopify_settings),
"apply_discount_on": "Grand Total",
"discount_amount": get_discounted_amount(shopify_order),
"currency": frappe.get_value(
"Customer", customer or shopify_settings.default_customer, "default_currency"
)
or get_company_currency(shopify_settings.company),
}
)
@@ -178,6 +183,7 @@ def create_sales_invoice(shopify_order, shopify_settings, so, old_order_sync=Fal
si.set_posting_time = 1
si.posting_date = posting_date
si.due_date = posting_date
si.currency = so.currency
si.naming_series = shopify_settings.sales_invoice_series or "SI-Shopify-"
si.flags.ignore_mandatory = True
set_cost_center(si.items, shopify_settings.cost_center)

View File

@@ -37,7 +37,7 @@ frappe.ui.form.on("Shopify Settings", "refresh", function(frm){
}
let app_link = "<a href='https://frappecloud.com/marketplace/apps/ecommerce-integrations' target='_blank'>Ecommerce Integrations</a>"
let app_link = "<a href='https://frappecloud.com/marketplace/apps/ecommerce_integrations' target='_blank'>Ecommerce Integrations</a>"
frm.dashboard.add_comment(__("Shopify Integration will be removed from ERPNext in Version 14. Please install {0} app to continue using it.", [app_link]), "yellow", true);
})

View File

@@ -58,6 +58,7 @@ class ShopifySettings(unittest.TestCase):
"warehouse": "_Test Warehouse - _TC",
"cash_bank_account": "Cash - _TC",
"account": "Cash - _TC",
"company": "_Test Company",
"customer_group": "_Test Customer Group",
"cost_center": "Main - _TC",
"taxes": [{"shopify_tax": "International Shipping", "tax_account": "Legal Expenses - _TC"}],

View File

@@ -2,7 +2,6 @@
"actions": [],
"allow_import": 1,
"allow_rename": 1,
"autoname": "field:healthcare_service_unit_name",
"beta": 1,
"creation": "2016-09-21 13:48:14.731437",
"description": "Healthcare Service Unit",
@@ -207,7 +206,7 @@
],
"is_tree": 1,
"links": [],
"modified": "2021-08-19 14:09:11.643464",
"modified": "2022-04-07 03:11:36.023277",
"modified_by": "Administrator",
"module": "Healthcare",
"name": "Healthcare Service Unit",

View File

@@ -164,6 +164,7 @@ def create_sales_invoice():
sales_invoice.customer = frappe.db.get_value("Patient", patient, "customer")
sales_invoice.due_date = getdate()
sales_invoice.company = "_Test Company"
sales_invoice.currency = "INR"
sales_invoice.debit_to = get_receivable_account("_Test Company")
tests = [insulin_resistance_template, blood_test_template]

View File

@@ -12,6 +12,7 @@ from frappe.model.document import Document
from frappe.model.mapper import get_mapped_doc
from frappe.utils import flt, get_link_to_form, get_time, getdate
from erpnext import get_company_currency
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import (
get_income_account,
get_receivable_account,
@@ -252,6 +253,10 @@ def create_sales_invoice(appointment_doc):
sales_invoice = frappe.new_doc("Sales Invoice")
sales_invoice.patient = appointment_doc.patient
sales_invoice.customer = frappe.get_value("Patient", appointment_doc.patient, "customer")
sales_invoice.currency = frappe.get_value(
"Customer", sales_invoice.customer, "default_currency"
) or get_company_currency(appointment_doc.company)
sales_invoice.appointment = appointment_doc.name
sales_invoice.due_date = getdate()
sales_invoice.company = appointment_doc.company

View File

@@ -379,6 +379,7 @@ def create_patient(
patient.mobile = mobile
patient.email = email
patient.customer = customer
patient.default_currency = "INR"
patient.invite_user = create_user
patient.save(ignore_permissions=True)

View File

@@ -6,6 +6,8 @@ import frappe
from frappe.model.document import Document
from frappe.utils import flt
from erpnext import get_company_currency
class TherapyPlan(Document):
def validate(self):
@@ -72,6 +74,9 @@ def make_sales_invoice(reference_name, patient, company, therapy_plan_template):
si.company = company
si.patient = patient
si.customer = frappe.db.get_value("Patient", patient, "customer")
si.currency = frappe.get_value(
"Customer", si.customer, "default_currency"
) or get_company_currency(si.company)
item = frappe.db.get_value("Therapy Plan Template", therapy_plan_template, "linked_item")
price_list, price_list_currency = frappe.db.get_values(

View File

@@ -382,6 +382,7 @@ doc_events = {
"validate": [
"erpnext.regional.india.utils.validate_document_name",
"erpnext.regional.india.utils.update_taxable_values",
"erpnext.regional.india.utils.validate_sez_and_export_invoices",
],
},
"POS Invoice": {"on_submit": ["erpnext.regional.saudi_arabia.utils.create_qr_code"]},
@@ -592,6 +593,9 @@ accounting_dimension_doctypes = [
"Subscription Plan",
"POS Invoice",
"POS Invoice Item",
"Purchase Order",
"Purchase Receipt",
"Sales Order",
]
regional_overrides = {

View File

@@ -21,6 +21,9 @@ class Attendance(Document):
self.validate_employee_status()
self.check_leave_record()
def on_cancel(self):
self.unlink_attendance_from_checkins()
def validate_attendance_date(self):
date_of_joining = frappe.db.get_value("Employee", self.employee, "date_of_joining")
@@ -102,6 +105,35 @@ class Attendance(Document):
if not emp:
frappe.throw(_("Employee {0} is not active or does not exist").format(self.employee))
def unlink_attendance_from_checkins(self):
from frappe.utils import get_link_to_form
EmployeeCheckin = frappe.qb.DocType("Employee Checkin")
linked_logs = (
frappe.qb.from_(EmployeeCheckin)
.select(EmployeeCheckin.name)
.where(EmployeeCheckin.attendance == self.name)
.for_update()
.run(as_dict=True)
)
if linked_logs:
(
frappe.qb.update(EmployeeCheckin)
.set("attendance", "")
.where(EmployeeCheckin.attendance == self.name)
).run()
frappe.msgprint(
msg=_("Unlinked Attendance record from Employee Checkins: {}").format(
", ".join(get_link_to_form("Employee Checkin", log.name) for log in linked_logs)
),
title=_("Unlinked logs"),
indicator="blue",
is_minimizable=True,
wide=True,
)
@frappe.whitelist()
def get_events(start, end, filters=None):

View File

@@ -65,9 +65,10 @@ frappe.ui.form.on('Employee Advance', {
);
}
if (frm.doc.docstatus === 1 &&
(flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount) && flt(frm.doc.paid_amount) != flt(frm.doc.return_amount))) {
if (
frm.doc.docstatus === 1
&& (flt(frm.doc.claimed_amount) < flt(frm.doc.paid_amount) - flt(frm.doc.return_amount))
) {
if (frm.doc.repay_unclaimed_amount_from_salary == 0 && frappe.model.can_create("Journal Entry")) {
frm.add_custom_button(__("Return"), function() {
frm.trigger('make_return_entry');

View File

@@ -2,7 +2,7 @@
"actions": [],
"allow_import": 1,
"autoname": "naming_series:",
"creation": "2017-10-09 14:26:29.612365",
"creation": "2022-01-17 18:36:51.450395",
"doctype": "DocType",
"editable_grid": 1,
"engine": "InnoDB",
@@ -121,7 +121,7 @@
"fieldtype": "Select",
"label": "Status",
"no_copy": 1,
"options": "Draft\nPaid\nUnpaid\nClaimed\nCancelled",
"options": "Draft\nPaid\nUnpaid\nClaimed\nReturned\nPartly Claimed and Returned\nCancelled",
"read_only": 1
},
{
@@ -200,7 +200,7 @@
],
"is_submittable": 1,
"links": [],
"modified": "2021-09-11 18:38:38.617478",
"modified": "2022-05-23 19:33:52.345823",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Advance",
@@ -236,5 +236,6 @@
"search_fields": "employee,employee_name",
"sort_field": "modified",
"sort_order": "DESC",
"title_field": "employee_name",
"track_changes": 1
}

View File

@@ -29,19 +29,43 @@ class EmployeeAdvance(Document):
def on_cancel(self):
self.ignore_linked_doctypes = "GL Entry"
self.set_status(update=True)
def set_status(self, update=False):
precision = self.precision("paid_amount")
total_amount = flt(flt(self.claimed_amount) + flt(self.return_amount), precision)
status = None
def set_status(self):
if self.docstatus == 0:
self.status = "Draft"
if self.docstatus == 1:
if self.claimed_amount and flt(self.claimed_amount) == flt(self.paid_amount):
self.status = "Claimed"
elif self.paid_amount and self.advance_amount == flt(self.paid_amount):
self.status = "Paid"
status = "Draft"
elif self.docstatus == 1:
if flt(self.claimed_amount) > 0 and flt(self.claimed_amount, precision) == flt(
self.paid_amount, precision
):
status = "Claimed"
elif flt(self.return_amount) > 0 and flt(self.return_amount, precision) == flt(
self.paid_amount, precision
):
status = "Returned"
elif (
flt(self.claimed_amount) > 0
and (flt(self.return_amount) > 0)
and total_amount == flt(self.paid_amount, precision)
):
status = "Partly Claimed and Returned"
elif flt(self.paid_amount) > 0 and flt(self.advance_amount, precision) == flt(
self.paid_amount, precision
):
status = "Paid"
else:
self.status = "Unpaid"
status = "Unpaid"
elif self.docstatus == 2:
self.status = "Cancelled"
status = "Cancelled"
if update:
self.db_set("status", status)
else:
self.status = status
def set_total_advance_paid(self):
gle = frappe.qb.DocType("GL Entry")
@@ -89,8 +113,7 @@ class EmployeeAdvance(Document):
self.db_set("paid_amount", paid_amount)
self.db_set("return_amount", return_amount)
self.set_status()
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
self.set_status(update=True)
def update_claimed_amount(self):
claimed_amount = (
@@ -112,8 +135,7 @@ class EmployeeAdvance(Document):
frappe.db.set_value("Employee Advance", self.name, "claimed_amount", flt(claimed_amount))
self.reload()
self.set_status()
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
self.set_status(update=True)
@frappe.whitelist()
@@ -265,6 +287,7 @@ def make_return_entry(
"party_type": "Employee",
"party": employee,
"is_advance": "Yes",
"cost_center": erpnext.get_default_cost_center(company),
},
)
@@ -282,6 +305,7 @@ def make_return_entry(
"account_currency": bank_cash_account.account_currency,
"account_type": bank_cash_account.account_type,
"exchange_rate": flt(exchange_rate) if bank_cash_account.account_currency == currency else 1,
"cost_center": erpnext.get_default_cost_center(company),
},
)

View File

@@ -0,0 +1,15 @@
frappe.listview_settings["Employee Advance"] = {
get_indicator: function(doc) {
let status_color = {
"Draft": "red",
"Submitted": "blue",
"Cancelled": "red",
"Paid": "green",
"Unpaid": "orange",
"Claimed": "blue",
"Returned": "gray",
"Partly Claimed and Returned": "yellow"
};
return [__(doc.status), status_color[doc.status], "status,=,"+doc.status];
}
};

View File

@@ -12,13 +12,21 @@ from erpnext.hr.doctype.employee_advance.employee_advance import (
EmployeeAdvanceOverPayment,
create_return_through_additional_salary,
make_bank_entry,
make_return_entry,
)
from erpnext.hr.doctype.expense_claim.expense_claim import get_advances
from erpnext.hr.doctype.expense_claim.test_expense_claim import (
get_payable_account,
make_expense_claim,
)
from erpnext.payroll.doctype.salary_component.test_salary_component import create_salary_component
from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
class TestEmployeeAdvance(unittest.TestCase):
def setUp(self):
frappe.db.delete("Employee Advance")
def test_paid_amount_and_status(self):
employee_name = make_employee("_T@employe.advance")
advance = make_employee_advance(employee_name)
@@ -53,9 +61,108 @@ class TestEmployeeAdvance(unittest.TestCase):
self.assertEqual(advance.paid_amount, 0)
self.assertEqual(advance.status, "Unpaid")
advance.cancel()
advance.reload()
self.assertEqual(advance.status, "Cancelled")
def test_claimed_status(self):
# CLAIMED Status check, full amount claimed
payable_account = get_payable_account("_Test Company")
claim = make_expense_claim(
payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True
)
advance = make_employee_advance(claim.employee)
pe = make_payment_entry(advance)
pe.submit()
claim = get_advances_for_claim(claim, advance.name)
claim.save()
claim.submit()
advance.reload()
self.assertEqual(advance.claimed_amount, 1000)
self.assertEqual(advance.status, "Claimed")
# advance should not be shown in claims
advances = get_advances(claim.employee)
advances = [entry.name for entry in advances]
self.assertTrue(advance.name not in advances)
# cancel claim; status should be Paid
claim.cancel()
advance.reload()
self.assertEqual(advance.claimed_amount, 0)
self.assertEqual(advance.status, "Paid")
def test_partly_claimed_and_returned_status(self):
payable_account = get_payable_account("_Test Company")
claim = make_expense_claim(
payable_account, 1000, 1000, "_Test Company", "Travel Expenses - _TC", do_not_submit=True
)
advance = make_employee_advance(claim.employee)
pe = make_payment_entry(advance)
pe.submit()
# PARTLY CLAIMED AND RETURNED status check
# 500 Claimed, 500 Returned
claim = make_expense_claim(
payable_account, 500, 500, "_Test Company", "Travel Expenses - _TC", do_not_submit=True
)
advance = make_employee_advance(claim.employee)
pe = make_payment_entry(advance)
pe.submit()
claim = get_advances_for_claim(claim, advance.name, amount=500)
claim.save()
claim.submit()
advance.reload()
self.assertEqual(advance.claimed_amount, 500)
self.assertEqual(advance.status, "Paid")
entry = make_return_entry(
employee=advance.employee,
company=advance.company,
employee_advance_name=advance.name,
return_amount=flt(advance.paid_amount - advance.claimed_amount),
advance_account=advance.advance_account,
mode_of_payment=advance.mode_of_payment,
currency=advance.currency,
exchange_rate=advance.exchange_rate,
)
entry = frappe.get_doc(entry)
entry.insert()
entry.submit()
advance.reload()
self.assertEqual(advance.return_amount, 500)
self.assertEqual(advance.status, "Partly Claimed and Returned")
# advance should not be shown in claims
advances = get_advances(claim.employee)
advances = [entry.name for entry in advances]
self.assertTrue(advance.name not in advances)
# Cancel return entry; status should change to PAID
entry.cancel()
advance.reload()
self.assertEqual(advance.return_amount, 0)
self.assertEqual(advance.status, "Paid")
# advance should be shown in claims
advances = get_advances(claim.employee)
advances = [entry.name for entry in advances]
self.assertTrue(advance.name in advances)
def test_repay_unclaimed_amount_from_salary(self):
employee_name = make_employee("_T@employe.advance")
advance = make_employee_advance(employee_name, {"repay_unclaimed_amount_from_salary": 1})
pe = make_payment_entry(advance)
pe.submit()
args = {"type": "Deduction"}
create_salary_component("Advance Salary - Deduction", **args)
@@ -85,11 +192,13 @@ class TestEmployeeAdvance(unittest.TestCase):
advance.reload()
self.assertEqual(advance.return_amount, 1000)
self.assertEqual(advance.status, "Returned")
# update advance return amount on additional salary cancellation
additional_salary.cancel()
advance.reload()
self.assertEqual(advance.return_amount, 700)
self.assertEqual(advance.status, "Paid")
def tearDown(self):
frappe.db.rollback()

View File

@@ -5,7 +5,7 @@
import frappe
from frappe import _
from frappe.model.document import Document
from frappe.utils import cint, get_datetime
from frappe.utils import cint, get_datetime, get_link_to_form
from erpnext.hr.doctype.shift_assignment.shift_assignment import (
get_actual_start_end_datetime_of_shift,
@@ -127,19 +127,17 @@ def mark_attendance_and_link_log(
log_names = [x.name for x in logs]
employee = logs[0].employee
if attendance_status == "Skip":
frappe.db.sql(
"""update `tabEmployee Checkin`
set skip_auto_attendance = %s
where name in %s""",
("1", log_names),
)
skip_attendance_in_checkins(log_names)
return None
elif attendance_status in ("Present", "Absent", "Half Day"):
employee_doc = frappe.get_doc("Employee", employee)
if not frappe.db.exists(
duplicate = frappe.db.exists(
"Attendance",
{"employee": employee, "attendance_date": attendance_date, "docstatus": ("!=", "2")},
):
)
if not duplicate:
doc_dict = {
"doctype": "Attendance",
"employee": employee,
@@ -155,6 +153,12 @@ def mark_attendance_and_link_log(
}
attendance = frappe.get_doc(doc_dict).insert()
attendance.submit()
if attendance_status == "Absent":
attendance.add_comment(
text=_("Employee was marked Absent for not meeting the working hours threshold.")
)
frappe.db.sql(
"""update `tabEmployee Checkin`
set attendance = %s
@@ -163,12 +167,10 @@ def mark_attendance_and_link_log(
)
return attendance
else:
frappe.db.sql(
"""update `tabEmployee Checkin`
set skip_auto_attendance = %s
where name in %s""",
("1", log_names),
)
skip_attendance_in_checkins(log_names)
if duplicate:
add_comment_in_checkins(log_names, duplicate)
return None
else:
frappe.throw(_("{} is an invalid Attendance Status.").format(attendance_status))
@@ -223,11 +225,15 @@ def calculate_working_hours(logs, check_in_out_type, working_hours_calc_type):
in_log = out_log = None
if not in_log:
in_log = log if log.log_type == "IN" else None
if in_log and not in_time:
in_time = in_log.time
elif not out_log:
out_log = log if log.log_type == "OUT" else None
if in_log and out_log:
out_time = out_log.time
total_hours += time_diff_in_hours(in_log.time, out_log.time)
return total_hours, in_time, out_time
@@ -237,3 +243,29 @@ def time_diff_in_hours(start, end):
def find_index_in_dict(dict_list, key, value):
return next((index for (index, d) in enumerate(dict_list) if d[key] == value), None)
def add_comment_in_checkins(log_names, duplicate):
text = _("Auto Attendance skipped due to duplicate attendance record: {}").format(
get_link_to_form("Attendance", duplicate)
)
for name in log_names:
frappe.get_doc(
{
"doctype": "Comment",
"comment_type": "Comment",
"reference_doctype": "Employee Checkin",
"reference_name": name,
"content": text,
}
).insert(ignore_permissions=True)
def skip_attendance_in_checkins(log_names):
EmployeeCheckin = frappe.qb.DocType("Employee Checkin")
(
frappe.qb.update(EmployeeCheckin)
.set("skip_auto_attendance", 1)
.where(EmployeeCheckin.name.isin(log_names))
).run()

View File

@@ -54,6 +54,17 @@ class TestEmployeeCheckin(unittest.TestCase):
)
self.assertEqual(attendance_count, 1)
def test_unlink_attendance_on_cancellation(self):
employee = make_employee("test_mark_attendance_and_link_log@example.com")
logs = make_n_checkins(employee, 3)
frappe.db.delete("Attendance", {"employee": employee})
attendance = mark_attendance_and_link_log(logs, "Present", nowdate(), 8.2)
attendance.cancel()
linked_logs = frappe.db.get_all("Employee Checkin", {"attendance": attendance.name})
self.assertEquals(len(linked_logs), 0)
def test_calculate_working_hours(self):
check_in_out_type = [
"Alternating entries as IN and OUT during the same shift",
@@ -103,6 +114,11 @@ class TestEmployeeCheckin(unittest.TestCase):
)
self.assertEqual(working_hours, (4.5, logs_type_2[1].time, logs_type_2[-1].time))
working_hours = calculate_working_hours(
[logs_type_2[1], logs_type_2[-1]], check_in_out_type[1], working_hours_calc_type[1]
)
self.assertEqual(working_hours, (5.0, logs_type_2[1].time, logs_type_2[-1].time))
def make_n_checkins(employee, n, hours_to_reverse=1):
logs = [make_checkin(employee, now_datetime() - timedelta(hours=hours_to_reverse, minutes=n + 1))]

View File

@@ -171,7 +171,7 @@ frappe.ui.form.on("Expense Claim", {
['docstatus', '=', 1],
['employee', '=', frm.doc.employee],
['paid_amount', '>', 0],
['status', '!=', 'Claimed']
['status', 'not in', ['Claimed', 'Returned', 'Partly Claimed and Returned']]
]
};
});

View File

@@ -414,25 +414,27 @@ def get_expense_claim_account(expense_claim_type, company):
@frappe.whitelist()
def get_advances(employee, advance_id=None):
advance = frappe.qb.DocType("Employee Advance")
query = frappe.qb.from_(advance).select(
advance.name,
advance.posting_date,
advance.paid_amount,
advance.claimed_amount,
advance.advance_account,
)
if not advance_id:
condition = "docstatus=1 and employee={0} and paid_amount > 0 and paid_amount > claimed_amount + return_amount".format(
frappe.db.escape(employee)
query = query.where(
(advance.docstatus == 1)
& (advance.employee == employee)
& (advance.paid_amount > 0)
& (advance.status.notin(["Claimed", "Returned", "Partly Claimed and Returned"]))
)
else:
condition = "name={0}".format(frappe.db.escape(advance_id))
query = query.where(advance.name == advance_id)
return frappe.db.sql(
"""
select
name, posting_date, paid_amount, claimed_amount, advance_account
from
`tabEmployee Advance`
where {0}
""".format(
condition
),
as_dict=1,
)
return query.run(as_dict=True)
@frappe.whitelist()

View File

@@ -6,6 +6,7 @@
import frappe
from frappe import _
from frappe.utils import get_link_to_form
from frappe.website.website_generator import WebsiteGenerator
from erpnext.hr.doctype.staffing_plan.staffing_plan import (
@@ -33,26 +34,32 @@ class JobOpening(WebsiteGenerator):
self.staffing_plan = staffing_plan[0].name
self.planned_vacancies = staffing_plan[0].vacancies
elif not self.planned_vacancies:
planned_vacancies = frappe.db.sql(
"""
select vacancies from `tabStaffing Plan Detail`
where parent=%s and designation=%s""",
(self.staffing_plan, self.designation),
self.planned_vacancies = frappe.db.get_value(
"Staffing Plan Detail",
{"parent": self.staffing_plan, "designation": self.designation},
"vacancies",
)
self.planned_vacancies = planned_vacancies[0][0] if planned_vacancies else None
if self.staffing_plan and self.planned_vacancies:
staffing_plan_company = frappe.db.get_value("Staffing Plan", self.staffing_plan, "company")
lft, rgt = frappe.get_cached_value("Company", staffing_plan_company, ["lft", "rgt"])
designation_counts = get_designation_counts(self.designation, self.company)
designation_counts = get_designation_counts(self.designation, self.company, self.name)
current_count = designation_counts["employee_count"] + designation_counts["job_openings"]
if self.planned_vacancies <= current_count:
number_of_positions = frappe.db.get_value(
"Staffing Plan Detail",
{"parent": self.staffing_plan, "designation": self.designation},
"number_of_positions",
)
if number_of_positions <= current_count:
frappe.throw(
_(
"Job Openings for designation {0} already open or hiring completed as per Staffing Plan {1}"
).format(self.designation, self.staffing_plan)
"Job Openings for the designation {0} are already open or the hiring is complete as per the Staffing Plan {1}"
).format(
frappe.bold(self.designation), get_link_to_form("Staffing Plan", self.staffing_plan)
),
title=_("Vacancies fulfilled"),
)
def get_context(self, context):

View File

@@ -3,8 +3,77 @@
import unittest
# test_records = frappe.get_test_records('Job Opening')
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, getdate
from erpnext.hr.doctype.employee.test_employee import make_employee
from erpnext.hr.doctype.staffing_plan.test_staffing_plan import make_company
class TestJobOpening(unittest.TestCase):
pass
class TestJobOpening(FrappeTestCase):
def setUp(self):
frappe.db.delete("Staffing Plan")
frappe.db.delete("Staffing Plan Detail")
frappe.db.delete("Job Opening")
make_company("_Test Opening Company", "_TOC")
frappe.db.delete("Employee", {"company": "_Test Opening Company"})
def test_vacancies_fulfilled(self):
make_employee(
"test_job_opening@example.com", company="_Test Opening Company", designation="Designer"
)
staffing_plan = frappe.get_doc(
{
"doctype": "Staffing Plan",
"company": "_Test Opening Company",
"name": "Test",
"from_date": getdate(),
"to_date": add_days(getdate(), 10),
}
)
staffing_plan.append(
"staffing_details",
{"designation": "Designer", "vacancies": 1, "estimated_cost_per_position": 50000},
)
staffing_plan.insert()
staffing_plan.submit()
self.assertEqual(staffing_plan.staffing_details[0].number_of_positions, 2)
# allows creating 1 job opening as per vacancy
opening_1 = get_job_opening()
opening_1.insert()
# vacancies as per staffing plan already fulfilled via job opening and existing employee count
opening_2 = get_job_opening(job_title="Designer New")
self.assertRaises(frappe.ValidationError, opening_2.insert)
# allows updating existing job opening
opening_1.status = "Closed"
opening_1.save()
def get_job_opening(**args):
args = frappe._dict(args)
opening = frappe.db.exists("Job Opening", {"job_title": args.job_title or "Designer"})
if opening:
return frappe.get_doc("Job Opening", opening)
opening = frappe.get_doc(
{
"doctype": "Job Opening",
"job_title": "Designer",
"designation": "Designer",
"company": "_Test Opening Company",
"status": "Open",
}
)
opening.update(args)
return opening

View File

@@ -237,7 +237,7 @@
"index_web_pages_for_search": 1,
"is_submittable": 1,
"links": [],
"modified": "2021-10-01 15:28:26.335104",
"modified": "2022-04-07 09:50:33.145825",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Allocation",
@@ -278,5 +278,7 @@
"show_name_in_global_search": 1,
"sort_field": "modified",
"sort_order": "DESC",
"timeline_field": "employee"
"timeline_field": "employee",
"title_field": "employee_name",
"track_changes": 1
}

View File

@@ -254,7 +254,18 @@ class LeaveAllocation(Document):
# Adding a day to include To Date in the difference
date_difference = date_diff(self.to_date, self.from_date) + 1
if date_difference < self.total_leaves_allocated:
frappe.throw(_("Total allocated leaves are more than days in the period"), OverAllocationError)
if frappe.db.get_value("Leave Type", self.leave_type, "allow_over_allocation"):
frappe.msgprint(
_("<b>Total Leaves Allocated</b> are more than the number of days in the allocation period"),
indicator="orange",
alert=True,
)
else:
frappe.throw(
_("<b>Total Leaves Allocated</b> are more than the number of days in the allocation period"),
exc=OverAllocationError,
title=_("Over Allocation"),
)
def create_leave_ledger_entry(self, submit=True):
if self.unused_leaves:

View File

@@ -68,22 +68,44 @@ class TestLeaveAllocation(FrappeTestCase):
self.assertRaises(frappe.ValidationError, doc.save)
def test_validation_for_over_allocation(self):
leave_type = create_leave_type(leave_type_name="Test Over Allocation", is_carry_forward=1)
leave_type.save()
doc = frappe.get_doc(
{
"doctype": "Leave Allocation",
"__islocal": 1,
"employee": self.employee.name,
"employee_name": self.employee.employee_name,
"leave_type": "_Test Leave Type",
"leave_type": leave_type.name,
"from_date": getdate("2015-09-1"),
"to_date": getdate("2015-09-30"),
"new_leaves_allocated": 35,
"carry_forward": 1,
}
)
# allocated leave more than period
self.assertRaises(OverAllocationError, doc.save)
leave_type.allow_over_allocation = 1
leave_type.save()
# allows creating a leave allocation with more leave days than period days
doc = frappe.get_doc(
{
"doctype": "Leave Allocation",
"__islocal": 1,
"employee": self.employee.name,
"employee_name": self.employee.employee_name,
"leave_type": leave_type.name,
"from_date": getdate("2015-09-1"),
"to_date": getdate("2015-09-30"),
"new_leaves_allocated": 35,
"carry_forward": 1,
}
).insert()
def test_validation_for_over_allocation_post_submission(self):
allocation = frappe.get_doc(
{

View File

@@ -744,7 +744,7 @@ class TestLeaveApplication(unittest.TestCase):
i = 0
while i < 14:
allocate_earned_leaves(ignore_duplicates=True)
allocate_earned_leaves()
i += 1
self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 6)
@@ -752,7 +752,7 @@ class TestLeaveApplication(unittest.TestCase):
frappe.db.set_value("Leave Type", leave_type, "max_leaves_allowed", 0)
i = 0
while i < 6:
allocate_earned_leaves(ignore_duplicates=True)
allocate_earned_leaves()
i += 1
self.assertEqual(get_leave_balance_on(employee.name, leave_type, nowdate()), 9)

View File

@@ -7,7 +7,7 @@ from frappe import _
from frappe.model.document import Document
from frappe.utils import getdate, nowdate
from erpnext.hr.doctype.leave_allocation.leave_allocation import get_unused_leaves
from erpnext.hr.doctype.leave_application.leave_application import get_leaves_for_period
from erpnext.hr.doctype.leave_ledger_entry.leave_ledger_entry import create_leave_ledger_entry
from erpnext.hr.utils import set_employee_name, validate_active_employee
from erpnext.payroll.doctype.salary_structure_assignment.salary_structure_assignment import (
@@ -107,7 +107,10 @@ class LeaveEncashment(Document):
self.leave_balance = (
allocation.total_leaves_allocated
- allocation.carry_forwarded_leaves_count
- get_unused_leaves(self.employee, self.leave_type, allocation.from_date, self.encashment_date)
# adding this because the function returns a -ve number
+ get_leaves_for_period(
self.employee, self.leave_type, allocation.from_date, self.encashment_date
)
)
encashable_days = self.leave_balance - frappe.db.get_value(
@@ -126,14 +129,25 @@ class LeaveEncashment(Document):
return True
def get_leave_allocation(self):
leave_allocation = frappe.db.sql(
"""select name, to_date, total_leaves_allocated, carry_forwarded_leaves_count from `tabLeave Allocation` where '{0}'
between from_date and to_date and docstatus=1 and leave_type='{1}'
and employee= '{2}'""".format(
self.encashment_date or getdate(nowdate()), self.leave_type, self.employee
),
as_dict=1,
) # nosec
date = self.encashment_date or getdate()
LeaveAllocation = frappe.qb.DocType("Leave Allocation")
leave_allocation = (
frappe.qb.from_(LeaveAllocation)
.select(
LeaveAllocation.name,
LeaveAllocation.from_date,
LeaveAllocation.to_date,
LeaveAllocation.total_leaves_allocated,
LeaveAllocation.carry_forwarded_leaves_count,
)
.where(
((LeaveAllocation.from_date <= date) & (date <= LeaveAllocation.to_date))
& (LeaveAllocation.docstatus == 1)
& (LeaveAllocation.leave_type == self.leave_type)
& (LeaveAllocation.employee == self.employee)
)
).run(as_dict=True)
return leave_allocation[0] if leave_allocation else None

View File

@@ -4,26 +4,42 @@
import unittest
import frappe
from frappe.utils import add_months, today
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, get_year_ending, get_year_start, getdate
from erpnext.hr.doctype.employee.test_employee import make_employee
from erpnext.hr.doctype.holiday_list.test_holiday_list import set_holiday_list
from erpnext.hr.doctype.leave_period.test_leave_period import create_leave_period
from erpnext.hr.doctype.leave_policy.test_leave_policy import create_leave_policy
from erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment import (
create_assignment_for_multiple_employees,
)
from erpnext.payroll.doctype.salary_slip.test_salary_slip import (
make_holiday_list,
make_leave_application,
)
from erpnext.payroll.doctype.salary_structure.test_salary_structure import make_salary_structure
test_dependencies = ["Leave Type"]
test_records = frappe.get_test_records("Leave Type")
class TestLeaveEncashment(unittest.TestCase):
class TestLeaveEncashment(FrappeTestCase):
def setUp(self):
frappe.db.sql("""delete from `tabLeave Period`""")
frappe.db.sql("""delete from `tabLeave Policy Assignment`""")
frappe.db.sql("""delete from `tabLeave Allocation`""")
frappe.db.sql("""delete from `tabLeave Ledger Entry`""")
frappe.db.sql("""delete from `tabAdditional Salary`""")
frappe.db.delete("Leave Period")
frappe.db.delete("Leave Policy Assignment")
frappe.db.delete("Leave Allocation")
frappe.db.delete("Leave Ledger Entry")
frappe.db.delete("Additional Salary")
frappe.db.delete("Leave Encashment")
if not frappe.db.exists("Leave Type", "_Test Leave Type Encashment"):
frappe.get_doc(test_records[2]).insert()
date = getdate()
year_start = getdate(get_year_start(date))
year_end = getdate(get_year_ending(date))
make_holiday_list("_Test Leave Encashment", year_start, year_end)
# create the leave policy
leave_policy = create_leave_policy(
@@ -32,9 +48,9 @@ class TestLeaveEncashment(unittest.TestCase):
leave_policy.submit()
# create employee, salary structure and assignment
self.employee = make_employee("test_employee_encashment@example.com")
self.employee = make_employee("test_employee_encashment@example.com", company="_Test Company")
self.leave_period = create_leave_period(add_months(today(), -3), add_months(today(), 3))
self.leave_period = create_leave_period(year_start, year_end, "_Test Company")
data = {
"assignment_based_on": "Leave Period",
@@ -53,27 +69,15 @@ class TestLeaveEncashment(unittest.TestCase):
other_details={"leave_encashment_amount_per_day": 50},
)
def tearDown(self):
for dt in [
"Leave Period",
"Leave Allocation",
"Leave Ledger Entry",
"Additional Salary",
"Leave Encashment",
"Salary Structure",
"Leave Policy",
]:
frappe.db.sql("delete from `tab%s`" % dt)
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_leave_balance_value_and_amount(self):
frappe.db.sql("""delete from `tabLeave Encashment`""")
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
payroll_date=today(),
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()
@@ -88,15 +92,46 @@ class TestLeaveEncashment(unittest.TestCase):
add_sal = frappe.get_all("Additional Salary", filters={"ref_docname": leave_encashment.name})[0]
self.assertTrue(add_sal)
def test_creation_of_leave_ledger_entry_on_submit(self):
frappe.db.sql("""delete from `tabLeave Encashment`""")
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_leave_balance_value_with_leaves_and_amount(self):
date = self.leave_period.from_date
leave_application = make_leave_application(
self.employee, date, add_days(date, 3), "_Test Leave Type Encashment"
)
leave_application.reload()
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
payroll_date=today(),
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()
self.assertEqual(leave_encashment.leave_balance, 10 - leave_application.total_leave_days)
# encashable days threshold is 5, total leaves are 6, so encashable days = 6-5 = 1
# with charge of 50 per day
self.assertEqual(leave_encashment.encashable_days, leave_encashment.leave_balance - 5)
self.assertEqual(leave_encashment.encashment_amount, 50)
leave_encashment.submit()
# assert links
add_sal = frappe.get_all("Additional Salary", filters={"ref_docname": leave_encashment.name})[0]
self.assertTrue(add_sal)
@set_holiday_list("_Test Leave Encashment", "_Test Company")
def test_creation_of_leave_ledger_entry_on_submit(self):
leave_encashment = frappe.get_doc(
dict(
doctype="Leave Encashment",
employee=self.employee,
leave_type="_Test Leave Type Encashment",
leave_period=self.leave_period.name,
encashment_date=self.leave_period.to_date,
currency="INR",
)
).insert()

View File

@@ -4,6 +4,7 @@
import unittest
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, add_months, get_first_day, get_last_day, getdate
from erpnext.hr.doctype.leave_application.test_leave_application import (
@@ -18,7 +19,7 @@ from erpnext.hr.doctype.leave_policy_assignment.leave_policy_assignment import (
test_dependencies = ["Employee"]
class TestLeavePolicyAssignment(unittest.TestCase):
class TestLeavePolicyAssignment(FrappeTestCase):
def setUp(self):
for doctype in [
"Leave Period",
@@ -39,6 +40,9 @@ class TestLeavePolicyAssignment(unittest.TestCase):
leave_policy = create_leave_policy()
leave_policy.submit()
self.employee.date_of_joining = get_first_day(leave_period.from_date)
self.employee.save()
data = {
"assignment_based_on": "Leave Period",
"leave_policy": leave_policy.name,
@@ -187,19 +191,6 @@ class TestLeavePolicyAssignment(unittest.TestCase):
)
self.assertEqual(leaves_allocated, 3)
# if the daily job is not completed yet, there is another check present
# to ensure leave is not already allocated to avoid duplication
from erpnext.hr.utils import allocate_earned_leaves
allocate_earned_leaves()
leaves_allocated = frappe.db.get_value(
"Leave Allocation",
{"leave_policy_assignment": leave_policy_assignments[0]},
"total_leaves_allocated",
)
self.assertEqual(leaves_allocated, 3)
def test_earned_leave_alloc_for_passed_months_with_cf_leaves_based_on_leave_period(self):
from erpnext.hr.doctype.leave_allocation.test_leave_allocation import create_leave_allocation
@@ -241,20 +232,6 @@ class TestLeavePolicyAssignment(unittest.TestCase):
self.assertEqual(details.unused_leaves, 5)
self.assertEqual(details.total_leaves_allocated, 7)
# if the daily job is not completed yet, there is another check present
# to ensure leave is not already allocated to avoid duplication
from erpnext.hr.utils import is_earned_leave_already_allocated
frappe.flags.current_date = get_last_day(getdate())
allocation = frappe.get_doc("Leave Allocation", details.name)
# 1 leave is still pending to be allocated, irrespective of carry forwarded leaves
self.assertFalse(
is_earned_leave_already_allocated(
allocation, leave_policy.leave_policy_details[0].annual_allocation
)
)
def test_earned_leave_alloc_for_passed_months_based_on_joining_date(self):
# tests leave alloc for earned leaves for assignment based on joining date in policy assignment
leave_type = create_earned_leave_type("Test Earned Leave")
@@ -287,19 +264,6 @@ class TestLeavePolicyAssignment(unittest.TestCase):
self.assertEqual(effective_from, self.employee.date_of_joining)
self.assertEqual(leaves_allocated, 3)
# to ensure leave is not already allocated to avoid duplication
from erpnext.hr.utils import allocate_earned_leaves
frappe.flags.current_date = get_last_day(getdate())
allocate_earned_leaves()
leaves_allocated = frappe.db.get_value(
"Leave Allocation",
{"leave_policy_assignment": leave_policy_assignments[0]},
"total_leaves_allocated",
)
self.assertEqual(leaves_allocated, 3)
def test_grant_leaves_on_doj_for_earned_leaves_based_on_leave_period(self):
# tests leave alloc based on leave period for earned leaves with "based on doj" configuration in leave type
leave_period, leave_policy = setup_leave_period_and_policy(
@@ -329,20 +293,6 @@ class TestLeavePolicyAssignment(unittest.TestCase):
)
self.assertEqual(leaves_allocated, 3)
# if the daily job is not completed yet, there is another check present
# to ensure leave is not already allocated to avoid duplication
from erpnext.hr.utils import allocate_earned_leaves
frappe.flags.current_date = get_first_day(getdate())
allocate_earned_leaves()
leaves_allocated = frappe.db.get_value(
"Leave Allocation",
{"leave_policy_assignment": leave_policy_assignments[0]},
"total_leaves_allocated",
)
self.assertEqual(leaves_allocated, 3)
def test_grant_leaves_on_doj_for_earned_leaves_based_on_joining_date(self):
# tests leave alloc based on joining date for earned leaves with "based on doj" configuration in leave type
leave_type = create_earned_leave_type("Test Earned Leave", based_on_doj=True)
@@ -376,21 +326,7 @@ class TestLeavePolicyAssignment(unittest.TestCase):
self.assertEqual(effective_from, self.employee.date_of_joining)
self.assertEqual(leaves_allocated, 3)
# to ensure leave is not already allocated to avoid duplication
from erpnext.hr.utils import allocate_earned_leaves
frappe.flags.current_date = get_first_day(getdate())
allocate_earned_leaves()
leaves_allocated = frappe.db.get_value(
"Leave Allocation",
{"leave_policy_assignment": leave_policy_assignments[0]},
"total_leaves_allocated",
)
self.assertEqual(leaves_allocated, 3)
def tearDown(self):
frappe.db.rollback()
frappe.db.set_value("Employee", self.employee.name, "date_of_joining", self.original_doj)
frappe.flags.current_date = None

View File

@@ -19,6 +19,7 @@
"fraction_of_daily_salary_per_leave",
"is_optional_leave",
"allow_negative",
"allow_over_allocation",
"include_holiday",
"is_compensatory",
"carry_forward_section",
@@ -211,15 +212,23 @@
"fieldtype": "Float",
"label": "Fraction of Daily Salary per Leave",
"mandatory_depends_on": "eval:doc.is_ppl == 1"
},
{
"default": "0",
"description": "Allows allocating more leaves than the number of days in the allocation period.",
"fieldname": "allow_over_allocation",
"fieldtype": "Check",
"label": "Allow Over Allocation"
}
],
"icon": "fa fa-flag",
"idx": 1,
"links": [],
"modified": "2021-10-02 11:59:40.503359",
"modified": "2022-05-09 05:01:38.957545",
"modified_by": "Administrator",
"module": "HR",
"name": "Leave Type",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
@@ -251,5 +260,6 @@
],
"sort_field": "modified",
"sort_order": "DESC",
"states": [],
"track_changes": 1
}

View File

@@ -84,7 +84,7 @@ class ShiftAssignment(Document):
@frappe.whitelist()
def get_events(start, end, filters=None):
events = []
from frappe.desk.calendar import get_event_conditions
employee = frappe.db.get_value(
"Employee", {"user_id": frappe.session.user}, ["name", "company"], as_dict=True
@@ -95,20 +95,22 @@ def get_events(start, end, filters=None):
employee = ""
company = frappe.db.get_value("Global Defaults", None, "default_company")
from frappe.desk.reportview import get_filters_cond
conditions = get_filters_cond("Shift Assignment", filters, [])
add_assignments(events, start, end, conditions=conditions)
conditions = get_event_conditions("Shift Assignment", filters)
events = add_assignments(start, end, conditions=conditions)
return events
def add_assignments(events, start, end, conditions=None):
def add_assignments(start, end, conditions=None):
events = []
query = """select name, start_date, end_date, employee_name,
employee, docstatus, shift_type
from `tabShift Assignment` where
start_date >= %(start_date)s
or end_date <= %(end_date)s
or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
(
start_date >= %(start_date)s
or end_date <= %(end_date)s
or (%(start_date)s between start_date and end_date and %(end_date)s between start_date and end_date)
)
and docstatus = 1"""
if conditions:
query += conditions

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