Compare commits

..

566 Commits

Author SHA1 Message Date
Frappe PR Bot
c15cff05b0 chore(release): Bumped to Version 13.36.3
## [13.36.3](https://github.com/frappe/erpnext/compare/v13.36.2...v13.36.3) (2022-08-09)

### Bug Fixes

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

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

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

(cherry picked from commit 17b9bfd249)

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

[skip ci]

(cherry picked from commit 2defb89962)

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

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

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

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

i fixed both errors and all working perfectly.

(cherry picked from commit ea88451875)

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

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

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

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

### Bug Fixes

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

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

* fix: update fr translation

* fix: update fr translation

* chore: Replace apostrophe encoding by symbol

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

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

(cherry picked from commit af38baeb3b)

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

(cherry picked from commit 9541354ec7)

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

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

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

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

* Update member.js

* fix: Route condition set with proper filter

* fix: Route condition set with proper filter

* fix: Route condition set with proper filter

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

* fix: update fr translations

* fix: update fr translations

* fix: update fr translations

* fix: update fr translations

* chore: Update french translation

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

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

IN,IM to IN,EIN

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

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

### Bug Fixes

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

(cherry picked from commit bf2833b8ee)

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

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

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

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

* fix brazilian portuguese translations

* minor adjustments

* fix minor adjustments

* fix: remove legacy pt_br.csv

* chore: Fix translation quotation marks

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

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

### Bug Fixes

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

### Features

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

### Performance Improvements

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

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

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

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

### Bug Fixes

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

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

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

### Bug Fixes

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

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

### Bug Fixes

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

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

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

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

### Bug Fixes

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

### Features

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

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

(cherry picked from commit 7e40c86c56)

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

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

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

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

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

(cherry picked from commit 5d73697c64)

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

Modify opts parameter misspell

closes #31474

(cherry picked from commit 2a619fd789)

Co-authored-by: gn306029 <gn306029@users.noreply.github.com>
2022-06-29 14:58:03 +05:30
Frappe PR Bot
43cb4fcbb1 chore(release): Bumped to Version 13.34.2
## [13.34.2](https://github.com/frappe/erpnext/compare/v13.34.1...v13.34.2) (2022-06-28)

### Bug Fixes

* add UOM validation for planned-qty ([559bde3](559bde3135))
* dont update RM items table if not required (backport [#31408](https://github.com/frappe/erpnext/issues/31408)) ([#31457](https://github.com/frappe/erpnext/issues/31457)) ([8155306](815530650c))
* General Ledger and TB opening entries mismatch issues ([a0c5c73](a0c5c730f5))
* Monthly depreciation using WDV method ([e7659a1](e7659a10e4))
* Quotation and Sales Order item sync ([2219132](2219132fdb))
* Respect system precision for user facing balance qty values ([#30837](https://github.com/frappe/erpnext/issues/30837)) ([642b9c5](642b9c5466))
* **Salary Slip:** Components not updated when amount evaluates to 0 due to payment days ([#31425](https://github.com/frappe/erpnext/issues/31425)) ([abfe926](abfe926a45))
* translation for filter status on report ([736f206](736f20656d))
* update ru translate (backport [#31404](https://github.com/frappe/erpnext/issues/31404)) ([#31417](https://github.com/frappe/erpnext/issues/31417)) ([8b78a12](8b78a122e7))
2022-06-28 07:31:44 +00:00
Deepesh Garg
0d5bb92149 Merge pull request #31464 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-06-28 13:00:06 +05:30
mergify[bot]
815530650c fix: dont update RM items table if not required (backport #31408) (#31457)
fix: dont update RM items table if not required (#31408)

Currently on PO update RM item table is auto computed again and again,
if there was any transfer/consumption against that then it will be lost.

This change:
1. Disables updating RM table if no change in qty of FG was made. Since
   RM table can't possibly be different with same FG qty.
2. Blocks update completely if qty is changed and RM items are already
   transferred.

(cherry picked from commit dd11f26eba)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-28 10:28:11 +05:30
Deepesh Garg
8ab65bc44e Merge pull request #31453 from frappe/mergify/bp/version-13-hotfix/pr-31446
fix: Quotation and Sales Order item sync (backport #31446)
2022-06-28 08:49:21 +05:30
mergify[bot]
5e7cad476f refactor: clean up product bundle client side code (backport #31455) (#31456)
refactor: clean up product bundle client side code (#31455)

refactor: clean up product bundle cient side code

- Remove deprecated CUR_FRM scripts
- Remove client side fetches and move it to doctype schema

(cherry picked from commit 20dac08f5f)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-27 18:33:17 +05:30
Deepesh Garg
2219132fdb fix: Quotation and Sales Order item sync
(cherry picked from commit 58fe220479)
2022-06-27 05:48:39 +00:00
Deepesh Garg
873d1ecdf0 Merge pull request #31447 from frappe/mergify/bp/version-13-hotfix/pr-31439
fix: General Ledger and TB opening entries mismatch issues (backport #31439)
2022-06-27 09:47:00 +05:30
Deepesh Garg
a0c5c730f5 fix: General Ledger and TB opening entries mismatch issues
(cherry picked from commit 6acd0325be)
2022-06-24 16:15:38 +00:00
Nabin Hait
e7659a10e4 fix: Monthly depreciation using WDV method 2022-06-24 21:12:31 +05:30
Sagar Sharma
96bd493a6f Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31412 2022-06-24 13:17:43 +05:30
Marica
5f8d8c096c Merge pull request #31440 from frappe/mergify/bp/version-13-hotfix/pr-31421
fix: add UOM validation for planned-qty (backport #31421)
2022-06-24 13:02:44 +05:30
s-aga-r
559bde3135 fix: add UOM validation for planned-qty
(cherry picked from commit 00807abe31)
2022-06-24 07:10:55 +00:00
Deepesh Garg
d1bb94bb1d Merge pull request #31431 from frappe/mergify/bp/version-13-hotfix/pr-31395
fix: filter set in Bank Clearance Summary (backport #31395)
2022-06-23 14:26:45 +05:30
Rucha Mahabal
abfe926a45 fix(Salary Slip): Components not updated when amount evaluates to 0 due to payment days (#31425)
* fix(Salary Slip): Components not updated when amount evaluates to 0 due to payment days

* fix: remove 0 valued components that have been updated later
2022-06-23 11:01:00 +05:30
Nihantra C. Patel
4b53ec22c5 Update bank_clearance_summary.py
(cherry picked from commit 0097a2b60c)
2022-06-23 05:25:17 +00:00
Marica
87f77813ea Merge pull request #31422 from frappe/mergify/bp/version-13-hotfix/pr-31420
fix: translation for filter status on report (backport #31420)
2022-06-22 14:01:42 +05:30
Marica
b4e64d0ebb Merge pull request #31423 from marination/bom-update-log-cleanup-perf-hotfix
chore: Clear Progress section for completed logs & `on_submit` UX
2022-06-22 14:01:19 +05:30
marination
fcec318588 chore: Clear Progress section for completed logs & on_submit UX
- Delete `BOM Update Batch` table on 'Completed' log, to save space
- Hide Progress section on 'Completed' log
- Enqueue `on_submit` for 'Update Cost' job, getting leaf boms could take time for huge DBs. Users have to wait for screen to unfreeze.
- Add error handling to `process_boms_cost_level_wise` (Called via cron job and on submit, both in background)
2022-06-22 12:27:08 +05:30
hrzzz
736f20656d fix: translation for filter status on report
(cherry picked from commit 8b1ff96e30)
2022-06-22 06:16:52 +00:00
mergify[bot]
8b78a122e7 fix: update ru translate (backport #31404) (#31417)
* fix: update ru translate (#31404)

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

fix logic

* 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

* Update ru.csv

* Update ru.csv

(cherry picked from commit ce1b4e40a1)

# Conflicts:
#	erpnext/translations/ru.csv

* chore: Fix merge conflicts

Co-authored-by: Vladislav <integration.into.society@gmail.com>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-06-21 20:14:13 +05:30
Marica
1e34616c91 Merge pull request #31393 from frappe/mergify/bp/version-13-hotfix/pr-30837
fix: Respect system precision for user facing balance qty values (backport #30837)
2022-06-21 20:13:23 +05:30
Frappe PR Bot
0a25d28e34 chore(release): Bumped to Version 13.34.1
## [13.34.1](https://github.com/frappe/erpnext/compare/v13.34.0...v13.34.1) (2022-06-21)

### Bug Fixes

* Conversion rate validation for multi-currency invoices ([4186aaf](4186aafd07))
* **india:** e-invoice eligibility if company gstin is not configured ([#31247](https://github.com/frappe/erpnext/issues/31247)) ([7696ae4](7696ae4de1))
* internal transfer GLE validation ([8a4cd2a](8a4cd2aba1))
* Merge Conflicts ([0f3a02d](0f3a02db57))
* Pick Template BOM if variant BOM absent in WO popup from SO ([7c35887](7c35887d07))
* Quotation lost update ([3b9f943](3b9f943335))
* Spelling mistake in quotation depend on (backport [#31362](https://github.com/frappe/erpnext/issues/31362)) ([#31363](https://github.com/frappe/erpnext/issues/31363)) ([ebcdaf7](ebcdaf7c82))
* transaction date gets unset in material request ([#31387](https://github.com/frappe/erpnext/issues/31387)) ([4e2ed6f](4e2ed6f9d9)), closes [#31327](https://github.com/frappe/erpnext/issues/31327)
* UOM handling for transaction without item (backport [#31389](https://github.com/frappe/erpnext/issues/31389)) ([#31391](https://github.com/frappe/erpnext/issues/31391)) ([051e5cd](051e5cd741))

### Performance Improvements

* GLE reposting with progress and chunking (backport [#31343](https://github.com/frappe/erpnext/issues/31343)) ([#31373](https://github.com/frappe/erpnext/issues/31373)) ([f19ed0b](f19ed0b74c))
2022-06-21 11:14:34 +00:00
s-aga-r
def622c13e fix: set default_bom for item
(cherry picked from commit dc2830da4d)

# Conflicts:
#	erpnext/manufacturing/doctype/bom/test_bom.py
2022-06-21 11:13:31 +00:00
Ankush Menat
d6d2215d8e Merge pull request #31414 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-06-21 16:39:04 +05:30
Deepesh Garg
e43e442448 Merge pull request #31413 from frappe/mergify/bp/version-13-hotfix/pr-31264
fix: internal transfer GLE validation (backport #31264)
2022-06-21 14:56:56 +05:30
Ankush Menat
8a4cd2aba1 fix: internal transfer GLE validation
(cherry picked from commit 65b21ee7d6)
2022-06-21 09:02:02 +00:00
Marica
3f4d00d288 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-30837 2022-06-21 11:02:46 +05:30
Deepesh Garg
8b3fc15ca8 Merge pull request #31397 from frappe/mergify/bp/version-13-hotfix/pr-31396
fix: Quotation lost update (backport #31396)
2022-06-21 10:28:45 +05:30
Deepesh Garg
760ba0877c Merge pull request #31411 from frappe/mergify/bp/version-13-hotfix/pr-31350
fix: Conversion rate validation for multi-currency invoices (backport #31350)
2022-06-21 10:28:15 +05:30
Deepesh Garg
da70b69d68 test: Add test case
(cherry picked from commit 8f37393044)
2022-06-21 03:40:13 +00:00
Deepesh Garg
4186aafd07 fix: Conversion rate validation for multi-currency invoices
(cherry picked from commit d05d15346a)
2022-06-21 03:40:13 +00:00
marination
70a7dfe2f0 chore: Missing import flt 2022-06-20 17:18:01 +05:30
Marica
e982abbe4d chore: Change autoname to v13 compatible value (#31407)
- 'autoincrement' is present only in v14
- 'hash' is automatically still used in tables but change value for safety
2022-06-20 17:09:52 +05:30
marination
5bcfbbe124 chore: fix merge conflict 2022-06-20 16:59:18 +05:30
Deepesh Garg
8e2e61ef84 chore: resolve conflicts 2022-06-18 20:23:58 +05:30
Deepesh Garg
b3169edfc8 Merge pull request #31275 from frappe/mergify/bp/version-13-hotfix/pr-31247
fix(india): e-invoice eligibility if company gstin is not configured (backport #31247)
2022-06-17 21:41:44 +05:30
Deepesh Garg
8d63abb442 chore: fix condition
(cherry picked from commit e457288dba)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.py
2022-06-17 15:39:53 +00:00
Deepesh Garg
3b9f943335 fix: Quotation lost update
(cherry picked from commit 02f9441e1a)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.py
2022-06-17 15:39:52 +00:00
Marica
642b9c5466 fix: Respect system precision for user facing balance qty values (#30837)
* fix: Respect system precision for user facing balance qty values

- `get_precision` -> `set_precision`
- Use system wide currency precision for `stock_value`
- Round of qty defiiciency as per user defined precision (system flt precision), so that it is WYSIWYG for users

* fix: Consider system precision when validating future negative qty

* test: Immediate Negative Qty precision test

- Test for Immediate Negative Qty precision
- Stock Entry Negative Qty message: Format available qty in system precision
- Pass `stock_uom` as confugrable option in `make_item`

* test: Future Negative Qty validation with precision

* fix: Use `get_field_precision` for currency precision as it used to

- `get_field_precision` defaults to number format for precision (maintain old behaviour)
- Don't pass `currency` to `get_field_precision` as its not used anymore

(cherry picked from commit d6078aa911)

# Conflicts:
#	erpnext/stock/doctype/stock_ledger_entry/test_stock_ledger_entry.py
2022-06-17 09:46:09 +00:00
mergify[bot]
051e5cd741 fix: UOM handling for transaction without item (backport #31389) (#31391)
fix: UOM handling for transaction without item (#31389)

If invoice is made without item code then UOM, Stock UOM and
conversion_factor all need to be manually added, this is confusing and
leads missing them out leads to errors.

Simplest solution:

- if either UOM exists then set both to same uom conversion factor to
- also set conversion factor based on UOM conversions

(cherry picked from commit 10583eb3ce)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-17 15:11:28 +05:30
mergify[bot]
4e2ed6f9d9 fix: transaction date gets unset in material request (#31387)
* fix: transaction date gets unset in material request (#31327)

* fix: set date correctly in material request

* fix: use only `transaction_date` in `get_item_details`

* fix: resolve merge conflict

Co-authored-by: Sagar Vora <sagar@resilient.tech>
2022-06-17 12:04:10 +05:30
Marica
2d6e518f87 Merge pull request #31380 from frappe/mergify/bp/version-13-hotfix/pr-31372
chore: Fix a potential variable misuse bug (backport #31372)
2022-06-16 12:47:58 +05:30
Marica
0f3a02db57 fix: Merge Conflicts 2022-06-16 12:23:13 +05:30
Jingxuan He
2cd03196a4 chore: Fix a potential variable misuse bug (#31372)
* Fix a potential variable misuse bug

* chore: Separate check (separate line) for empty table in Pricing Rule

* chore: Code readability & check for field in row (now row itself)

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

# Conflicts:
#	erpnext/accounts/doctype/pricing_rule/pricing_rule.py
2022-06-16 06:47:49 +00:00
Ankush Menat
f19ed0b74c perf: GLE reposting with progress and chunking (backport #31343) (#31373)
* fix: dont use cached doc for GLE reposts

ported from https://github.com/frappe/erpnext/pull/31240

* perf: GLE reposting with progress and chunking

If stock voucher count goes >1000 then fetching all gles and reposting
them all at once requires much more memory and can cause crash.

- This PR ensures that GLE reposting is done in chunks of 100 vouchers.
- This PR also starts keeping track of how many such chunks were
  processed so in future progress is resumed in event of timeout.

* test: add "actual" test for chunked GLE reposting
2022-06-15 20:54:20 +05:30
Marica
001130c0da Merge pull request #31368 from frappe/mergify/bp/version-13-hotfix/pr-31353
fix: Pick Template BOM if variant BOM absent in WO popup from SO (backport #31353)
2022-06-15 15:42:58 +05:30
marination
7c35887d07 fix: Pick Template BOM if variant BOM absent in WO popup from SO
- Use `get_default_bom` in sales_order.py (reduce duplicate utility functions)
- Remove redundant if else in `get_work_order_items`
- `get_default_bom`: If no BOM and template exists try to fetch template BOM
- test: `get_work_order_items` via SO and if right BOM is picked

(cherry picked from commit 9f2d325e67)
2022-06-15 09:07:54 +00:00
mergify[bot]
ebcdaf7c82 fix: Spelling mistake in quotation depend on (backport #31362) (#31363)
* fix: Spelling mistake in quotation depend on (#31362)

Update quotation.json

(cherry picked from commit 37e9622426)

* chore: bump modified

Co-authored-by: Nihantra C. Patel <99652762+nihantra@users.noreply.github.com>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-15 12:05:46 +05:30
Frappe PR Bot
943d83b739 chore(release): Bumped to Version 13.34.0
# [13.34.0](https://github.com/frappe/erpnext/compare/v13.33.0...v13.34.0) (2022-06-14)

### Bug Fixes

* (auto-merge) Use `frappe.log_error` instead of `doc.log_error` ([bced6a0](bced6a07b4))
* `test_work_order_with_non_stock_item` ([b827c3b](b827c3b3c9))
* Add cost center in loan document ([c19dfbe](c19dfbe98a))
* **asset:** failing test case ([#31277](https://github.com/frappe/erpnext/issues/31277)) ([8a4c9d1](8a4c9d1238))
* Auto Insert Item Price If Missing when discount & blank UOM (backport [#31168](https://github.com/frappe/erpnext/issues/31168)) ([#31267](https://github.com/frappe/erpnext/issues/31267)) ([e69bff0](e69bff0caa))
* Call `calculate_cost` for Draft BOM and typo in argument ([d035aa2](d035aa2afb))
* Company address filter in quotation ([d375939](d375939475))
* DB update child items, remove redundancy, fix perf ([cbc52a2](cbc52a2e45))
* Depreciate Asset before generating GL Entries on sale ([#30759](https://github.com/frappe/erpnext/issues/30759)) ([dfbfe40](dfbfe403e9))
* Get fresh RM rate in `calculate_rm_cost` ([9a513fd](9a513fda74))
* **India:** Incorrect taxable in GSTR-3B report ([e5d2c59](e5d2c59929))
* **India:** Sales taxes and charges template fetching in quotation ([a1ba847](a1ba8475d0))
* locale Currency and Float setting in update_employee ([391ed9c](391ed9c567))
* misaligned columns in print format of AR/AP report ([81e32e2](81e32e2855))
* Partially Ordered status for quotation ([37ba550](37ba550398))
* purchase invoice standalone return GLEs (backport [#31209](https://github.com/frappe/erpnext/issues/31209)) ([#31263](https://github.com/frappe/erpnext/issues/31263)) ([6d99b5a](6d99b5a95a))
* Reset represents company on disabling internal customer and supplier (backport [#31302](https://github.com/frappe/erpnext/issues/31302)) ([#31306](https://github.com/frappe/erpnext/issues/31306)) ([fb9b302](fb9b302ecf))
* Safe cast `row.rate` (in case of faulty exploded items, edge case but oh well) ([6d65e2b](6d65e2bab4))
* Supplied Qty not updated on Stock Entry cancel ([79b2062](79b20622c9))
* Trial Balance failing to ignore Finance Book ([00371f4](00371f4a22))
* typo in sql condition ([894f945](894f945be7))
* update fr translation (backport [#31232](https://github.com/frappe/erpnext/issues/31232)) ([#31334](https://github.com/frappe/erpnext/issues/31334)) ([5d0f271](5d0f271451))
* update Period Closing Voucher per Company ([5ebbe81](5ebbe81543))
* update ru translate (backport [#31200](https://github.com/frappe/erpnext/issues/31200)) ([#31304](https://github.com/frappe/erpnext/issues/31304)) ([77e4755](77e4755c1f))
* Use `frappe.as_unicode` to decode output of redis module list (backport [#31282](https://github.com/frappe/erpnext/issues/31282)) ([#31283](https://github.com/frappe/erpnext/issues/31283)) ([633a452](633a4521e4))
* **ux:** hide new version btn on unsaved BOM (backport [#31297](https://github.com/frappe/erpnext/issues/31297)) ([#31298](https://github.com/frappe/erpnext/issues/31298)) ([9f6b32a](9f6b32af12))
* **UX:** use doc.status for Job Card status ([#31320](https://github.com/frappe/erpnext/issues/31320)) ([78473b8](78473b8d99))

### Features

* Add german translations ([a3f2cf3](a3f2cf3917))
* Level-wise BOM cost updation ([74d7d81](74d7d81d6e))
* Only update exploded items rate and amount ([a26da58](a26da58718))
* Track progress in Log Batch/Job wise ([3b2a8bf](3b2a8bf837))

### Performance Improvements

* `get_boms_in_bottom_up_order` ([87c2b3b](87c2b3be0b))
* `get_next_higher_level_boms` ([767a775](767a775709))
* Use cached doc instead of `get_doc` ([faa69c9](faa69c942b))
2022-06-14 07:45:40 +00:00
Deepesh Garg
662a63b3f5 Merge pull request #31349 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-06-14 13:13:45 +05:30
Deepesh Garg
55e0c03ef0 Merge pull request #31347 from frappe/mergify/bp/version-13-hotfix/pr-31322
fix: Company address filter in quotation (backport #31322)
2022-06-14 12:44:59 +05:30
Deepesh Garg
da1a948a28 chore: resolve conflicts 2022-06-14 11:36:43 +05:30
Deepesh Garg
823cf88c3c chore: linting issues
(cherry picked from commit fb3da124e5)
2022-06-14 05:47:58 +00:00
Deepesh Garg
37ba550398 fix: Partially Ordered status for quotation
(cherry picked from commit 118c786e63)

# Conflicts:
#	erpnext/selling/doctype/quotation/quotation.json
2022-06-14 05:47:57 +00:00
Deepesh Garg
a1ba8475d0 fix(India): Sales taxes and charges template fetching in quotation
(cherry picked from commit 243625898e)
2022-06-14 05:47:55 +00:00
Deepesh Garg
d375939475 fix: Company address filter in quotation
(cherry picked from commit 2fc04f661a)
2022-06-14 05:47:54 +00:00
Marica
c5bda9cb09 Merge pull request #31344 from frappe/mergify/bp/version-13-hotfix/pr-31341
fix: Supplied Qty not updated on Stock Entry cancel (backport #31341)
2022-06-13 23:24:49 +05:30
Marica
6064ca6fed test: Pass "yes" instead of 1 for is_subcontracted in create_purchase_order 2022-06-13 21:06:04 +05:30
marination
86a0ba5c9f test: PO Supplied Qty reset on cancel/submit
(cherry picked from commit b8f468cb4f)
2022-06-13 15:13:54 +00:00
marination
79b20622c9 fix: Supplied Qty not updated on Stock Entry cancel
- Loop over PO supplied items and update them as data from SE will exclude a row if supplied qty becomes 0 on cancel
- Use DB API insteaf of raw SQL

(cherry picked from commit fa1d9d548e)
2022-06-13 15:13:53 +00:00
Saqib Ansari
fb1325d7a5 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31247 2022-06-13 17:08:23 +05:30
mergify[bot]
5d0f271451 fix: update fr translation (backport #31232) (#31334)
* fix: update fr translation (#31232)

* update fr translation

* fix:update fr translation

* fix:update fr translation

* fix:update fr translation

* fix:update fr translation

* fix:update fr translation

* fix:update fr translation

* fix:update fr translation

* Update fr.csv

update typo

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* update fr translation

* fix: Use elision instead of HTML code equivalent

* fix: Use elision instead of HTML code equivalent (pt 2)

* fix: Use elision/single quote instead of HTML code equivalent (pt 3)

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

* fix: Accidental '=' instead of comma

Co-authored-by: HENRY Florian <florian.henry@open-concept.pro>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-06-13 12:18:46 +05:30
Marica
1e6e652988 Merge pull request #31314 from frappe/mergify/bp/version-13-hotfix/pr-31303
fix: locale Currency and Float setting in update_employee (backport #31303)
2022-06-13 10:49:29 +05:30
Marica
ff770bbf04 Merge pull request #31321 from frappe/mergify/bp/version-13-hotfix/pr-31320
fix(UX): use doc.status for Job Card status (backport #31320)
2022-06-13 10:30:05 +05:30
Ankush Menat
78473b8d99 fix(UX): use doc.status for Job Card status (#31320)
- Use doc.status directly for indicator - single source of truth
- Update status to cancelled when doc is cancelled

(cherry picked from commit 39ec0aca95)
2022-06-13 10:04:53 +05:30
Deepesh Garg
977d6969d5 Merge pull request #31318 from frappe/mergify/bp/version-13-hotfix/pr-31295
fix: update Period Closing Voucher per Company (backport #31295)
2022-06-11 23:44:22 +05:30
mergify[bot]
50a4c2e9dc refactor: remove add_fetch (backport #31315) (#31319)
* refactor: remove add_fetch (#31315)

- Sales Team already had fetch from set up
- Set up fetch from on sales partner in sales transaction

Reason for removal: the JS code applies arbitrarily to any field called "sales_person"

(cherry picked from commit 1646fbe478)

# Conflicts:
#	erpnext/selling/sales_common.js

* chore: conflicts

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-10 18:30:50 +05:30
hendrik
5ebbe81543 fix: update Period Closing Voucher per Company
Validate period closing voucher company-wise

(cherry picked from commit 74b274f555)
2022-06-10 09:23:36 +00:00
Deepesh Garg
395f86f42b Merge pull request #31310 from frappe/mergify/bp/version-13-hotfix/pr-31294
fix(India): Incorrect taxable in GSTR-3B report (backport #31294)
2022-06-10 14:27:20 +05:30
Deepesh Garg
9e0cb2a467 Merge pull request #31262 from frappe/mergify/bp/version-13-hotfix/pr-30155
fix: Add cost center in loan document (backport #30155)
2022-06-10 13:16:33 +05:30
Deepesh Garg
1aaca097b3 chore: Linting Issues 2022-06-10 12:51:16 +05:30
Deepesh Garg
309bdf257d Merge pull request #31139 from frappe/mergify/bp/version-13-hotfix/pr-31102
feat: Add german translations (backport #31102)
2022-06-10 12:42:10 +05:30
Deepesh Garg
4c9422fb1b chore: resolve conflicts 2022-06-10 12:39:12 +05:30
RJPvT
391ed9c567 fix: locale Currency and Float setting in update_employee
In fieldtypes locale settings (example NL) . and , changes whereby the field is inproperly filled

(cherry picked from commit 17887cde71)
2022-06-10 06:05:51 +00:00
Deepesh Garg
95f8784ea9 chore: Resolve conflicts 2022-06-10 10:59:46 +05:30
Deepesh Garg
176a6722e5 chore: cleanup
(cherry picked from commit 50aafdbe99)
2022-06-10 05:19:55 +00:00
Deepesh Garg
e5d2c59929 fix(India): Incorrect taxable in GSTR-3B report
(cherry picked from commit 20f568c159)
2022-06-10 05:19:54 +00:00
Deepesh Garg
384ce92b4b Merge pull request #31307 from frappe/mergify/bp/version-13-hotfix/pr-31216
fix: Trial Balance failing to ignore Finance Book (backport #31216)
2022-06-10 00:10:23 +05:30
Sun Howwrongbum
894f945be7 fix: typo in sql condition
(cherry picked from commit ee2949aa3f)
2022-06-09 15:05:15 +00:00
Deepesh Garg
44642dba39 chore: Linting Issues
(cherry picked from commit b9dbb36d0e)
2022-06-09 15:05:14 +00:00
Sun Howwrongbum
00371f4a22 fix: Trial Balance failing to ignore Finance Book
(cherry picked from commit 48bde2de2a)
2022-06-09 15:05:14 +00:00
mergify[bot]
fb9b302ecf fix: Reset represents company on disabling internal customer and supplier (backport #31302) (#31306)
fix: Reset represents company on disabling internal customer and supplier (#31302)

(cherry picked from commit c13e5ad741)

Co-authored-by: Deepesh Garg <deepeshgarg6@gmail.com>
2022-06-09 19:20:53 +05:30
mergify[bot]
77e4755c1f fix: update ru translate (backport #31200) (#31304)
* fix: update ru translate (#31200)

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

* Update ru.csv

fix logic

* Update ru.csv

* Update ru.csv

* Update ru.csv

(cherry picked from commit 2675751d6c)

# Conflicts:
#	erpnext/translations/ru.csv

* fix: Merge conflicts

Co-authored-by: Vladislav <integration.into.society@gmail.com>
Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-06-09 19:16:48 +05:30
Marica
bb431bb21f Merge pull request #31299 from frappe/mergify/bp/version-13-hotfix/pr-31296
fix: misaligned columns in print format of AR/AP report (backport #31296)
2022-06-09 18:31:20 +05:30
Marica
48de5ab62a Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31296 2022-06-09 18:09:09 +05:30
Marica
3816ae21bb Merge pull request #31078 from marination/v13-perf-bom-update-tool
perf: BOM Update Tool (backport)
2022-06-09 17:51:28 +05:30
meaziz
9347cbbc9f chore: Asset Arabic translation Fix (#31221)
Update ar.csv

Fix Translation arabic translation that caused an error when submitting an asset if user language was arabic
2022-06-09 17:43:31 +05:30
ruthra kumar
81e32e2855 fix: misaligned columns in print format of AR/AP report
(cherry picked from commit bbaa14af16)
2022-06-09 12:06:11 +00:00
mergify[bot]
9f6b32af12 fix(ux): hide new version btn on unsaved BOM (backport #31297) (#31298)
fix(ux): hide new version btn on unsaved BOM (#31297)

(cherry picked from commit d9a5213952)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-06-09 17:22:50 +05:30
marination
5a08850aa1 chore: Less hacky tests, versioning (replace bom) and clearing log data (update cost)
- Remove `auto_commit_on_many_writes` in `update_cost_in_level()` as commits happen every N BOMs
- Auto commit every 50 BOMs
- test: Remove hacky `frappe.flags.in_test` returns
- test: Enqueue `now` if in tests (for update cost and replace bom)
- Replace BOM: Copy bom object to `_doc_before_save` so that version.py finds a difference between the two
- Replace BOM: Add reference to version
- Update Cost: Unset `processed_boms` if Log is completed (useless after completion)
- test: `update_cost_in_all_boms_in_test` works close to actual prod implementation (only call Cron job manually)
- Test: use `enqueue_replace_bom`  so that test works closest to production behaviour

Co-authored-by: Ankush Menat <ankushmenat@gmail.com>
2022-06-09 16:56:19 +05:30
Marica
7a868a46d5 Merge branch 'version-13-hotfix' into v13-perf-bom-update-tool 2022-06-09 13:33:52 +05:30
mergify[bot]
633a4521e4 fix: Use frappe.as_unicode to decode output of redis module list (backport #31282) (#31283)
fix: Use `frappe.as_unicode` to decode output of redis module list (#31282)

- As of redis 7, a list is added to the result of fetching the module list
- This list cannot be "decoded",so use `frappe.as_unicode` that handles bytes as well as other types

(cherry picked from commit 2832731601)

Co-authored-by: Marica <maricadsouza221197@gmail.com>
2022-06-08 18:12:02 +05:30
Saqib Ansari
e1fe901a91 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31247 2022-06-08 14:21:31 +05:30
Saqib Ansari
8a4c9d1238 fix(asset): failing test case (#31277) 2022-06-08 14:12:59 +05:30
Marica
8656020c00 Merge branch 'version-13-hotfix' into v13-perf-bom-update-tool 2022-06-08 14:09:51 +05:30
marination
289d65a4ed chore: get_valuation_rate sider fixes
- Use qb instead of db.sql
- Don't use `args` as argument for function
- Cleaner variable names
2022-06-08 14:08:45 +05:30
marination
b529a610fb test: Fix test_update_bom_cost_in_all_boms
- Use base_rate for assertions as rate is subject to change due to conversion factor (USD)
2022-06-08 14:08:12 +05:30
marination
c7accb9c33 test: Util to update cost in all BOMs
- Utility to update cost in all BOMs without cron jobs or background jobs (run immediately)
- Re-use util wherever all bom costs are to be updated
- Skip explicit commits if in test
- Specify company in test records (dirty data sometimes, company wh mismatch)
- Skip background jobs queueing if in test
2022-06-08 14:07:34 +05:30
Saqib Ansari
7696ae4de1 fix(india): e-invoice eligibility if company gstin is not configured (#31247)
(cherry picked from commit fb4f8d870b)
2022-06-08 04:06:58 +00:00
Ganga Manoj
dfbfe403e9 fix: Depreciate Asset before generating GL Entries on sale (#30759) 2022-06-08 09:35:43 +05:30
mergify[bot]
e69bff0caa fix: Auto Insert Item Price If Missing when discount & blank UOM (backport #31168) (#31267)
fix: Auto Insert Item Price If Missing when discount & blank UOM (#31168)

* fix: Auto Insert Item Price If Missing when discount and blank UOM

fixes wrong item price insert when discount is used and adds uom=stock_uom instead of blank as price is converted to stock uom

* unit tests added for item with discount

I have added test  for auto_insert_price where discount is used.

* unit test issue fixed

fixed make_sales_order as some of the test that depended on it were failing due to passing of incorrect parameters.

Co-authored-by: Ankush Menat <me@ankush.dev>
(cherry picked from commit b3ccc4bfb9)

Co-authored-by: maharshivpatel <39730881+maharshivpatel@users.noreply.github.com>
2022-06-07 16:04:00 +05:30
Ankush Menat
0e53edfd49 test: sales register report with conditions (#31266) 2022-06-07 16:03:29 +05:30
mergify[bot]
6d99b5a95a fix: purchase invoice standalone return GLEs (backport #31209) (#31263)
* test: create stock test mixin for assertion/utils

(cherry picked from commit 293eb8d722)

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

* fix: purchase invoice return GLe

voucher_wise_stock_value contains tuples and the condition was looking
for string, so it's never triggered.

Caused by https://github.com/frappe/erpnext/pull/24200

(cherry picked from commit 7726271e2a)

* chore: conflicts

Co-authored-by: Ankush Menat <me@ankush.dev>
Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-07 15:43:37 +05:30
Frappe PR Bot
3b1f9fe03b chore(release): Bumped to Version 13.33.0
# [13.33.0](https://github.com/frappe/erpnext/compare/v13.32.0...v13.33.0) (2022-06-07)

### Bug Fixes

* Close unsecured terms loans ([d6d1d79](d6d1d79ba0))
* Consider only Approved leave applications in LWP, Employee Benefit calculations ([7f84c86](7f84c86d43))
* display currencies in validation message. ([ef22337](ef22337a9b))
* incorrect billed_qty in sales order analysis report when multiple delivery notes for item (backport [#31194](https://github.com/frappe/erpnext/issues/31194)) ([#31250](https://github.com/frappe/erpnext/issues/31250)) ([3b1f6da](3b1f6da741))
* incorrect LWP calculation for half days in employee benefit application ([10f0c93](10f0c935fe))
* **India:** GSTIN filter in GSTR-1 report ([abe9fe7](abe9fe70ce))
* **India:** Supplies from composite dealer not showing up ([15712c7](15712c742b))
* **job card:** only hold during draft state (backport [#31243](https://github.com/frappe/erpnext/issues/31243)) ([#31249](https://github.com/frappe/erpnext/issues/31249)) ([a7fc278](a7fc278b60))
* **Leave Application:** 'Cancelled' status shown as 'Open' in list view ([8b48d45](8b48d45286))
* leave balance for earned leaves in backdated Leave Application dashboard (backport [#31253](https://github.com/frappe/erpnext/issues/31253)) ([#31256](https://github.com/frappe/erpnext/issues/31256)) ([a22d92f](a22d92f946))
* only fetch membership expiry if not already set in `member.js` ([#31259](https://github.com/frappe/erpnext/issues/31259)) ([d433784](d433784171))
* Parent dimension filters in orders ([b3cbcd8](b3cbcd871b))
* Pluralize year text instead of optional bracket (backport [#31210](https://github.com/frappe/erpnext/issues/31210)) ([#31212](https://github.com/frappe/erpnext/issues/31212)) ([b31709c](b31709c793))
* re-validate warehouse after 'update items' (backport [#31203](https://github.com/frappe/erpnext/issues/31203)) ([#31206](https://github.com/frappe/erpnext/issues/31206)) ([3a718c7](3a718c7d5f))
* remove leave policy assignment creation patch (backport [#31097](https://github.com/frappe/erpnext/issues/31097)) ([#31204](https://github.com/frappe/erpnext/issues/31204)) ([4aeb448](4aeb448fea))
* Remove redundant query ([3c4cf59](3c4cf5929f))
* Reverse provisional entries on Purchase Invoice cancel ([1fba432](1fba432786))
* **Sales Register:** incorrect query with dimensions (backport [#31242](https://github.com/frappe/erpnext/issues/31242)) ([#31251](https://github.com/frappe/erpnext/issues/31251)) ([0badfc8](0badfc8748))
* Simply cancel reverse entries ([100b8d9](100b8d9b96))

### Features

* **india:** Improve E-way Bill Cancellation. ([#31088](https://github.com/frappe/erpnext/issues/31088)) ([622d25e](622d25e126))
2022-06-07 09:59:51 +00:00
Deepesh Garg
5f7f8361d9 Merge pull request #31265 from frappe/version-13-hotfix
chore: weekly version-13 release
2022-06-07 15:28:17 +05:30
Deepesh Garg
f087246e38 Merge pull request #31261 from frappe/mergify/bp/version-13-hotfix/pr-31258
fix: Close unsecured terms loans (backport #31258)
2022-06-07 14:52:47 +05:30
Deepesh Garg
c19dfbe98a fix: Add cost center in loan document
(cherry picked from commit 5d66cc4c4a)

# Conflicts:
#	erpnext/loan_management/doctype/loan_interest_accrual/loan_interest_accrual.py
#	erpnext/patches.txt
2022-06-07 08:40:48 +00:00
Deepesh Garg
ef8483d2ea chore: Resolve conflicts 2022-06-07 14:10:44 +05:30
Deepesh Garg
8cb85fa90b Merge pull request #31260 from frappe/mergify/bp/version-13-hotfix/pr-31233
fix: Reverse provisional entries on Purchase Invoice cancel (backport #31233)
2022-06-07 14:03:44 +05:30
Rucha Mahabal
d433784171 fix: only fetch membership expiry if not already set in member.js (#31259) 2022-06-07 14:01:12 +05:30
Deepesh Garg
d6d1d79ba0 fix: Close unsecured terms loans
(cherry picked from commit 815141bf57)

# Conflicts:
#	erpnext/loan_management/doctype/loan/loan.py
2022-06-07 08:24:23 +00:00
Deepesh Garg
42a0b82c71 test: Add test coverage for cancellation
(cherry picked from commit dc8e80ea81)
2022-06-07 08:01:46 +00:00
Deepesh Garg
100b8d9b96 fix: Simply cancel reverse entries
(cherry picked from commit 86a24f3d22)
2022-06-07 08:01:45 +00:00
Deepesh Garg
1fba432786 fix: Reverse provisional entries on Purchase Invoice cancel
(cherry picked from commit 61fa4eb6c9)
2022-06-07 08:01:45 +00:00
Rucha Mahabal
149c6031a1 chore: add missing import 2022-06-07 11:08:29 +05:30
Rucha Mahabal
ad1b419368 test: Employee Benefit Application
- make `get_no_of_days` a function for reusability
2022-06-07 11:08:29 +05:30
Rucha Mahabal
10f0c935fe fix: incorrect LWP calculation for half days in employee benefit application 2022-06-07 11:08:29 +05:30
Rucha Mahabal
8b48d45286 fix(Leave Application): 'Cancelled' status shown as 'Open' in list view 2022-06-07 11:08:29 +05:30
Rucha Mahabal
144d71c6af refactor: rewrite lwp queries using query builder 2022-06-07 11:08:29 +05:30
Rucha Mahabal
7f84c86d43 fix: Consider only Approved leave applications in LWP, Employee Benefit calculations
- do not allow submitting leave applications with 'Cancelled' status
2022-06-07 11:08:29 +05:30
mergify[bot]
a22d92f946 fix: leave balance for earned leaves in backdated Leave Application dashboard (backport #31253) (#31256)
fix: leave balance for earned leaves in backdated Leave Application dashboard

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-06-07 10:22:27 +05:30
Deepesh Garg
86856491b7 Merge pull request #31235 from frappe/mergify/bp/version-13-hotfix/pr-31219
fix: Parent dimension filters in orders (backport #31219)
2022-06-06 20:53:33 +05:30
Deepesh Garg
60d378aed2 chore: Resolve conflicts 2022-06-06 20:36:40 +05:30
mergify[bot]
3b1f6da741 fix: incorrect billed_qty in sales order analysis report when multiple delivery notes for item (backport #31194) (#31250)
* fix: incorrect billed_qty when item has multiple Delivery note

sales order analysis report returns incorrect billed_qty value for
an SO item has multiple delivery notes

(cherry picked from commit 0331e37982)

* test: multiple delivery notes and billed quantity

(cherry picked from commit 4f1bfbb93d)

Co-authored-by: ruthra kumar <ruthra@erpnext.com>
2022-06-06 19:55:18 +05:30
mergify[bot]
a7fc278b60 fix(job card): only hold during draft state (backport #31243) (#31249)
* fix(job card): only hold during draft state (#31243)

(cherry picked from commit ee5bc58e9b)

# Conflicts:
#	erpnext/patches.txt

* chore: conflicts

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-06-06 19:54:56 +05:30
mergify[bot]
0badfc8748 fix(Sales Register): incorrect query with dimensions (backport #31242) (#31251)
fix(Sales Register): incorrect query with dimensions

If accounting dimension is also part of the default filters then same
query is repeated with incorrect syntax.

e.g. `item_group = (child1, child2)` instead of `in` query.

fix: don't add default filter if they are part of dimensions to be
added.

(cherry picked from commit c3219ebad1)

Co-authored-by: Ankush Menat <ankush@frappe.io>
2022-06-06 19:54:41 +05:30
marination
d3b06a682c chore: get_valuation_rate in bom.py must always return float & goto Item master if no bins 2022-06-06 18:15:07 +05:30
marination
7bd5558c31 chore: Miscellanous fixes/enhancements
- `get_valuation_rate`: if no bins are found return 0, SLEs do not exist either
- `get_valuation_rate`: Compute average valuation rate via query
- `get_rm_rate_map`: set order_by as None to avoid creating sort index (modified) each time query runs (seen in process list)
- BOM Update Batch: add status field and hide `boms_updated` so that  users can see progress without loading all updated boms (too much data)
- BOM Update Batch: set batch row status to completed after job runs
- BOM Update Log: remove `parent_boms` field (just pass parent boms to processing function) & remove Paused state (not used)
- Move job to long queue to avoid choking default queue
- `update_cost_in_boms`: use `get_doc` as each BOM is accessed only once. Use `for_update` to lock BOM row
- Commit after every 100 BOMs
2022-06-06 17:04:06 +05:30
Deepesh Garg
b58c7750c6 Merge pull request #31237 from frappe/mergify/bp/version-13-hotfix/pr-31223
fix: display currencies in validation message. (backport #31223)
2022-06-06 14:48:21 +05:30
Deepesh Garg
aaaacf9a8f Merge pull request #31241 from frappe/mergify/bp/version-13-hotfix/pr-31230
fix: Remove redundant query (backport #31230)
2022-06-06 14:48:00 +05:30
Deepesh Garg
3c4cf5929f fix: Remove redundant query
(cherry picked from commit a200e7e1fb)
2022-06-06 06:54:41 +00:00
Deepesh Garg
ed89963d65 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31223 2022-06-06 12:24:34 +05:30
Deepesh Garg
281fe34457 Merge pull request #31236 from frappe/mergify/bp/version-13-hotfix/pr-31231
fix(India): Supplies from composite dealer not showing up (backport #31231)
2022-06-06 12:24:20 +05:30
Deepesh Garg
d07014340f Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31223 2022-06-06 11:50:30 +05:30
Deepesh Garg
fa0984f192 Merge pull request #31234 from frappe/mergify/bp/version-13-hotfix/pr-31218
fix(India): GSTIN filter in GSTR-1 report (backport #31218)
2022-06-06 11:45:41 +05:30
Deepesh Garg
3ea2c95768 Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31223 2022-06-06 10:42:48 +05:30
Deepesh Garg
23d94c135f Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31231 2022-06-06 10:42:41 +05:30
Deepesh Garg
66bc9a974e Merge branch 'version-13-hotfix' into mergify/bp/version-13-hotfix/pr-31218 2022-06-06 10:42:28 +05:30
Deepesh Garg
91716e9c26 Merge pull request #31238 from frappe/mergify/bp/version-13-hotfix/pr-31217
ci: stale apt cache (backport #31217)
2022-06-06 10:06:41 +05:30
Ankush Menat
2db12d7bfa ci: stale apt cache (#31217)
(cherry picked from commit c7efa3b44d)
2022-06-06 04:03:14 +00:00
Devin Slauenwhite
f4a4dacb22 chore: linter
(cherry picked from commit b061ea4cd2)
2022-06-06 03:37:41 +00:00
Devin Slauenwhite
ef22337a9b fix: display currencies in validation message.
(cherry picked from commit 3a1c923e76)
2022-06-06 03:37:40 +00:00
Deepesh Garg
15712c742b fix(India): Supplies from composite dealer not showing up
(cherry picked from commit db07831db7)
2022-06-06 03:30:59 +00:00
Deepesh Garg
b3cbcd871b fix: Parent dimension filters in orders
(cherry picked from commit 3f376cc3a5)

# Conflicts:
#	erpnext/accounts/doctype/purchase_invoice/purchase_invoice.js
#	erpnext/accounts/doctype/sales_invoice/sales_invoice.js
2022-06-06 03:29:07 +00:00
Deepesh Garg
abe9fe70ce fix(India): GSTIN filter in GSTR-1 report
(cherry picked from commit f0ac394d6e)
2022-06-06 03:28:38 +00:00
marination
3b2a8bf837 feat: Track progress in Log Batch/Job wise
- This was done due to stale reads while the background jobs tried updating status of the log
- Added a table where all bom jobs within log will be tracked with what level they are processing
- Cron job will check if table jobs are all processed every 5 mins
- If yes, it will prepare parents and call `process_boms_cost_level_wise` to start next level
- If pending jobs, do nothing
- Current BOM Level is being tracked that helps adding rows to the table
- Individual bom cost jobs (that are queued) will process and update boms > will update BOM Update Batch table row with list of updated BOMs
2022-06-02 13:41:56 +05:30
mergify[bot]
b31709c793 fix: Pluralize year text instead of optional bracket (backport #31210) (#31212)
Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
Co-authored-by: Mohammad Hussain Nagaria <34810212+NagariaHussain@users.noreply.github.com>
2022-06-01 16:47:02 +05:30
mergify[bot]
3a718c7d5f fix: re-validate warehouse after 'update items' (backport #31203) (#31206)
fix: re-validate warehouse after 'update items' (#31203)

(cherry picked from commit c84e11ac82)

Co-authored-by: Ankush Menat <me@ankush.dev>
2022-06-01 15:24:55 +05:30
mergify[bot]
8b985d632f test: fix attendance tests for unmarked days (backport #31205) (#31208)
test: fix attendance tests for unmarked days (#31205)

* test: fix attendance tests for unmarked days

* chore: remove unused import

(cherry picked from commit 536f1dfc4b)

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-06-01 14:15:59 +05:30
mergify[bot]
4aeb448fea fix: remove leave policy assignment creation patch (backport #31097) (#31204)
* fix: remove leave policy assignment creation patch (#31097)

(cherry picked from commit d4b9cc0242)

# Conflicts:
#	erpnext/patches.txt

* chore: fix conflicts

Co-authored-by: Rucha Mahabal <ruchamahabal2@gmail.com>
2022-06-01 12:46:17 +05:30
Deepesh Garg
910ab405ae Merge pull request #31188 from frappe/mergify/bp/version-13-hotfix/pr-31088
feat(india): Check E-way Bill Status before Cancellation. (backport #31088)
2022-05-31 21:41:54 +05:30
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
marination
e6ad56cd68 chore: Limit Update Cost jobs & db_update only if changed values
- If `Update Cost` job is ongoing, then block creation of new ones since all BOMs are updated
- `db_update` in `calculate_rm_cost` only if changed values to reduce redundant row updates
- Misc: Use variable for batch size
2022-05-31 16:01:22 +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
maharshivpatel
622d25e126 feat(india): Improve E-way Bill Cancellation. (#31088)
(cherry picked from commit a8f98f3f96)
2022-05-31 06:45:23 +00:00
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
marination
bced6a07b4 fix: (auto-merge) Use frappe.log_error instead of doc.log_error
- The latter is only on develop
2022-05-27 22:06:12 +05:30
marination
6d65e2bab4 fix: Safe cast row.rate (in case of faulty exploded items, edge case but oh well) 2022-05-27 22:01:26 +05:30
marination
767a775709 perf: get_next_higher_level_boms
- Separate getting dependants and checking if they are valid (loop within loop led to redundant processing that slowed down function)
- Adding to above, the same dependant(parent) was repeatedly processed as many children shared it. Expensive.
- Use a parent-child map similar to child-parent map to check if all children are resolved
- `map.get()` reduced time: 10 mins -> 0.9s~1 second (as compared to `get_cached_doc` or query)
- Total time: 17 seconds to process 6599 leaf boms and 4.2L parent boms
- Previous Total time: >10 mins (I terminated it due to not wanting to waste time XD)
2022-05-27 21:16:07 +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
marination
12f0a9a183 chore: Change BOM Progress field types to Long Text 2022-05-27 17:05:29 +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
marination
a26da58718 feat: Only update exploded items rate and amount
- Generate RM-Rate map from Items table (will include subassembly items with rate)
- Function to reset exploded item rate from above map
- `db_update` exploded item rate only if rate is changed
- Via Update Cost, only update exploded items rate, do not regenerate table again
- Exploded Items are regenerated on Save and Replace BOM job
- `calculate_exploded_cost` is run only via non doc events (Update Cost button, Update BOMs Cost Job)
2022-05-27 15:10:50 +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
barredterra
a3f2cf3917 feat: Add german translations
(cherry picked from commit 2388d86623)

# Conflicts:
#	erpnext/translations/de.csv
2022-05-26 06:20:15 +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
marination
196a824c4f style: Update docstrings and fix/add type hints + Collapsible progress section in Log 2022-05-25 16:48:07 +05:30
marination
74d7d81d6e feat: Level-wise BOM cost updation
- Process BOMs level wise and Pause after level is complete
- Cron job will resume Paused jobs, which will again process the new level and pause at the end
- This will go on until all BOMs are updated
- Added Progress section with fields to track updated BOMs in Log
- Cleanup: Add BOM Updation utils file to contain helper functions/sub-functions
- Cleanup: BOM Update Log file will only contain functions that are in direct context of the Log

Co-authored-by: Gavin D'souza <gavin18d@gmail.com>
2022-05-25 16:47:54 +05:30
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
marination
b827c3b3c9 fix: test_work_order_with_non_stock_item
- Use the right price list and currency to avoid rate conversion (1000/62.9), since rates are reset correctly now
- Use RM rate based on Price List in BOM. Non stock item has no valuation
2022-05-20 12:34:15 +05:30
marination
9a513fda74 fix: Get fresh RM rate in calculate_rm_cost 2022-05-20 12:23:52 +05:30
marination
faa69c942b perf: Use cached doc instead of get_doc
- Doc is only used to iterate over items(which wont change) and change rate/amount of rows
- These changes are inserted in db via `db_update`, so no harm
- Tested locally: refetching cached doc after db update, reflects fresh data.
2022-05-20 12:23:42 +05:30
marination
d035aa2afb fix: Call calculate_cost for Draft BOM and typo in argument 2022-05-20 12:23:32 +05:30
marination
cbc52a2e45 fix: DB update child items, remove redundancy, fix perf
- Move `get_boms_in_bottom_up_order` in bom update tool’s file
- Remove repeated rm cost update from `update_cost`. `calculate_cost` handles RM cost update
- db_update children in `calculate_cost` optionally
- Don’t call `update_exploded_items` and regenerate exploded items in `update_cost`. They will stay the same (except cost)
2022-05-20 12:23:18 +05:30
marination
87c2b3be0b perf: get_boms_in_bottom_up_order
- Create child-parent map once and fetch value from child key to get parents
- Get parents recursively for a leaf node (get all ancestors)
- Approx. 44 secs for 4lakh 70k boms
2022-05-20 12:20:24 +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
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
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
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
318 changed files with 164036 additions and 10149 deletions

View File

@@ -31,6 +31,7 @@ ignore =
E124, # closing bracket, irritating while writing QB code
E131, # continuation line unaligned for hanging indent
E123, # closing bracket does not match indentation of opening bracket's line
E101, # ensured by use of black
max-line-length = 200
exclude=.github/helper/semgrep_rules

View File

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

View File

@@ -11,7 +11,7 @@ fi
cd ~ || exit
sudo apt-get install redis-server libcups2-dev
sudo apt update && sudo apt install redis-server libcups2-dev
pip install frappe-bench

View File

@@ -25,7 +25,7 @@ jobs:
fail-fast: false
matrix:
container: [1, 2, 3]
container: [1, 2]
name: Python Unit Tests

View File

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

View File

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

View File

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

View File

@@ -4,7 +4,7 @@ import frappe
from erpnext.hooks import regional_overrides
__version__ = "13.29.2"
__version__ = "13.36.3"
def get_default_company(user=None):
@@ -149,6 +149,7 @@ def allow_regional(fn):
return caller
@frappe.whitelist()
def get_last_membership(member):
"""Returns last membership if exists"""
last_membership = frappe.get_all(

View File

@@ -234,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

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

View File

@@ -43,7 +43,7 @@ class GLEntry(Document):
self.validate_and_set_fiscal_year()
self.pl_must_have_cost_center()
if not self.flags.from_repost:
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
self.check_mandatory()
self.validate_cost_center()
self.check_pl_account()
@@ -52,7 +52,7 @@ class GLEntry(Document):
def on_update(self):
adv_adj = self.flags.adv_adj
if not self.flags.from_repost:
if not self.flags.from_repost and self.voucher_type != "Period Closing Voucher":
self.validate_account_details(adv_adj)
self.validate_dimensions_for_pl_and_bs()
self.validate_allowed_dimensions()

View File

@@ -149,22 +149,6 @@ frappe.ui.form.on("Journal Entry", {
}
});
}
else if(frm.doc.voucher_type=="Opening Entry") {
return frappe.call({
type:"GET",
method: "erpnext.accounts.doctype.journal_entry.journal_entry.get_opening_accounts",
args: {
"company": frm.doc.company
},
callback: function(r) {
frappe.model.clear_table(frm.doc, "accounts");
if(r.message) {
update_jv_details(frm.doc, r.message);
}
cur_frm.set_value("is_opening", "Yes");
}
});
}
}
},

View File

@@ -137,7 +137,8 @@
"fieldname": "finance_book",
"fieldtype": "Link",
"label": "Finance Book",
"options": "Finance Book"
"options": "Finance Book",
"read_only": 1
},
{
"fieldname": "2_add_edit_gl_entries",
@@ -538,7 +539,7 @@
"idx": 176,
"is_submittable": 1,
"links": [],
"modified": "2022-04-06 17:18:46.865259",
"modified": "2022-06-23 22:01:32.348337",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry",

View File

@@ -25,7 +25,10 @@ from erpnext.accounts.utils import (
get_stock_and_account_balance,
)
from erpnext.controllers.accounts_controller import AccountsController
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.hr.doctype.expense_claim.expense_claim import (
get_outstanding_amount_for_claim,
update_reimbursed_amount,
)
class StockAccountInvalidTransaction(frappe.ValidationError):
@@ -935,15 +938,12 @@ class JournalEntry(AccountsController):
def validate_expense_claim(self):
for d in self.accounts:
if d.reference_type == "Expense Claim":
sanctioned_amount, reimbursed_amount = frappe.db.get_value(
"Expense Claim", d.reference_name, ("total_sanctioned_amount", "total_amount_reimbursed")
)
pending_amount = flt(sanctioned_amount) - flt(reimbursed_amount)
if d.debit > pending_amount:
outstanding_amt = get_outstanding_amount_for_claim(d.reference_name)
if d.debit > outstanding_amt:
frappe.throw(
_(
"Row No {0}: Amount cannot be greater than Pending Amount against Expense Claim {1}. Pending Amount is {2}"
).format(d.idx, d.reference_name, pending_amount)
"Row No {0}: Amount cannot be greater than the Outstanding Amount against Expense Claim {1}. Outstanding Amount is {2}"
).format(d.idx, d.reference_name, outstanding_amt)
)
def validate_credit_debit_note(self):
@@ -1192,24 +1192,6 @@ def get_payment_entry(ref_doc, args):
return je if args.get("journal_entry") else je.as_dict()
@frappe.whitelist()
def get_opening_accounts(company):
"""get all balance sheet accounts for opening entry"""
accounts = frappe.db.sql_list(
"""select
name from tabAccount
where
is_group=0 and report_type='Balance Sheet' and company={0} and
name not in (select distinct account from tabWarehouse where
account is not null and account != '')
order by name asc""".format(
frappe.db.escape(company)
)
)
return [{"account": a, "balance": get_balance_on(a)} for a in accounts]
@frappe.whitelist()
@frappe.validate_and_sanitize_search_inputs
def get_against_jv(doctype, txt, searchfield, start, page_len, filters):

View File

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

View File

@@ -30,7 +30,10 @@ from erpnext.controllers.accounts_controller import (
get_supplier_block_status,
validate_taxes_and_charges,
)
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
from erpnext.hr.doctype.expense_claim.expense_claim import (
get_outstanding_amount_for_claim,
update_reimbursed_amount,
)
from erpnext.setup.utils import get_exchange_rate
@@ -302,7 +305,7 @@ class PaymentEntry(AccountsController):
def validate_reference_documents(self):
if self.party_type == "Student":
valid_reference_doctypes = "Fees"
valid_reference_doctypes = ("Fees", "Journal Entry")
elif self.party_type == "Customer":
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry", "Dunning")
elif self.party_type == "Supplier":
@@ -357,6 +360,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))
@@ -1643,12 +1652,7 @@ def get_reference_details(reference_doctype, reference_name, party_account_curre
outstanding_amount = ref_doc.get("outstanding_amount")
bill_no = ref_doc.get("bill_no")
elif reference_doctype == "Expense Claim":
outstanding_amount = (
flt(ref_doc.get("total_sanctioned_amount"))
+ flt(ref_doc.get("total_taxes_and_charges"))
- flt(ref_doc.get("total_amount_reimbursed"))
- flt(ref_doc.get("total_advance_amount"))
)
outstanding_amount = get_outstanding_amount_for_claim(ref_doc)
elif reference_doctype == "Employee Advance":
outstanding_amount = flt(ref_doc.advance_amount) - flt(ref_doc.paid_amount)
if party_account_currency != ref_doc.currency:

View File

@@ -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

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

View File

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

View File

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

@@ -222,9 +222,6 @@ class POSInvoice(SalesInvoice):
allow_negative_stock = frappe.db.get_single_value("Stock Settings", "allow_negative_stock")
for d in self.get("items"):
is_service_item = not (frappe.db.get_value("Item", d.get("item_code"), "is_stock_item"))
if is_service_item:
return
if d.serial_no:
self.validate_pos_reserved_serial_nos(d)
self.validate_delivered_serial_nos(d)

View File

@@ -9,7 +9,7 @@ from frappe import _
from frappe.core.page.background_jobs.background_jobs import get_info
from frappe.model.document import Document
from frappe.model.mapper import map_child_doc, map_doc
from frappe.utils import flt, getdate, nowdate
from frappe.utils import cint, flt, getdate, nowdate
from frappe.utils.background_jobs import enqueue
from frappe.utils.scheduler import is_scheduler_inactive
@@ -219,6 +219,9 @@ class POSInvoiceMergeLog(Document):
invoice.taxes_and_charges = None
invoice.ignore_pricing_rule = 1
invoice.customer = self.customer
invoice.disable_rounded_total = cint(
frappe.db.get_value("POS Profile", invoice.pos_profile, "disable_rounded_total")
)
if self.merge_invoices_based_on == "Customer Group":
invoice.flags.ignore_pos_profile = True

View File

@@ -44,6 +44,7 @@
"write_off_account",
"write_off_cost_center",
"account_for_change_amount",
"disable_rounded_total",
"column_break_23",
"income_account",
"expense_account",
@@ -358,6 +359,13 @@
"fieldname": "validate_stock_on_save",
"fieldtype": "Check",
"label": "Validate Stock on Save"
},
{
"default": "0",
"description": "If enabled, the consolidated invoices will have rounded total disabled",
"fieldname": "disable_rounded_total",
"fieldtype": "Check",
"label": "Disable Rounded Total"
}
],
"icon": "icon-cog",
@@ -385,7 +393,7 @@
"link_fieldname": "pos_profile"
}
],
"modified": "2022-03-21 13:29:28.480533",
"modified": "2022-07-21 11:16:46.911173",
"modified_by": "Administrator",
"module": "Accounts",
"name": "POS Profile",

View File

@@ -36,10 +36,15 @@ class PricingRule(Document):
self.margin_rate_or_amount = 0.0
def validate_duplicate_apply_on(self):
field = apply_on_dict.get(self.apply_on)
values = [d.get(frappe.scrub(self.apply_on)) for d in self.get(field) if field]
if len(values) != len(set(values)):
frappe.throw(_("Duplicate {0} found in the table").format(self.apply_on))
if self.apply_on != "Transaction":
apply_on_table = apply_on_dict.get(self.apply_on)
if not apply_on_table:
return
apply_on_field = frappe.scrub(self.apply_on)
values = [d.get(apply_on_field) for d in self.get(apply_on_table) if d.get(apply_on_field)]
if len(values) != len(set(values)):
frappe.throw(_("Duplicate {0} found in the table").format(self.apply_on))
def validate_mandatory(self):
for apply_on, field in apply_on_dict.items():

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

@@ -45,8 +45,6 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
if (this.frm.doc.supplier && this.frm.doc.__islocal) {
this.frm.trigger('supplier');
}
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
},
refresh: function(doc) {

View File

@@ -158,20 +158,10 @@ class PurchaseInvoice(BuyingController):
if tds_category and not for_validate:
self.apply_tds = 1
self.tax_withholding_category = tds_category
self.set_onload("supplier_tds", tds_category)
super(PurchaseInvoice, self).set_missing_values(for_validate)
def check_conversion_rate(self):
default_currency = erpnext.get_company_currency(self.company)
if not default_currency:
throw(_("Please enter default currency in Company Master"))
if (
(self.currency == default_currency and flt(self.conversion_rate) != 1.00)
or not self.conversion_rate
or (self.currency != default_currency and flt(self.conversion_rate) == 1.00)
):
throw(_("Conversion rate cannot be 0 or 1"))
def validate_credit_to_acc(self):
if not self.credit_to:
self.credit_to = get_party_account("Supplier", self.supplier, self.company)
@@ -540,7 +530,16 @@ class PurchaseInvoice(BuyingController):
from_repost=from_repost,
)
elif self.docstatus == 2:
provisional_entries = [a for a in gl_entries if a.voucher_type == "Purchase Receipt"]
make_reverse_gl_entries(voucher_type=self.doctype, voucher_no=self.name)
if provisional_entries:
for entry in provisional_entries:
frappe.db.set_value(
"GL Entry",
{"voucher_type": "Purchase Receipt", "voucher_detail_no": entry.voucher_detail_no},
"is_cancelled",
1,
)
if update_outstanding == "No":
update_outstanding_amt(
@@ -1078,7 +1077,7 @@ class PurchaseInvoice(BuyingController):
# Stock ledger value is not matching with the warehouse amount
if (
self.update_stock
and voucher_wise_stock_value.get(item.name)
and voucher_wise_stock_value.get((item.name, item.warehouse))
and warehouse_debit_amount
!= flt(voucher_wise_stock_value.get((item.name, item.warehouse)), net_amt_precision)
):

View File

@@ -26,12 +26,13 @@ from erpnext.stock.doctype.purchase_receipt.test_purchase_receipt import (
make_purchase_receipt,
)
from erpnext.stock.doctype.stock_entry.test_stock_entry import get_qty_after_transaction
from erpnext.stock.tests.test_utils import StockTestMixin
test_dependencies = ["Item", "Cost Center", "Payment Term", "Payment Terms Template"]
test_ignore = ["Serial No"]
class TestPurchaseInvoice(unittest.TestCase):
class TestPurchaseInvoice(unittest.TestCase, StockTestMixin):
@classmethod
def setUpClass(self):
unlink_payment_on_cancel_of_invoice()
@@ -659,6 +660,80 @@ class TestPurchaseInvoice(unittest.TestCase):
self.assertEqual(expected_values[gle.account][0], gle.debit)
self.assertEqual(expected_values[gle.account][1], gle.credit)
def test_standalone_return_using_pi(self):
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry
item = self.make_item().name
company = "_Test Company with perpetual inventory"
warehouse = "Stores - TCP1"
make_stock_entry(item_code=item, target=warehouse, qty=50, rate=120)
return_pi = make_purchase_invoice(
is_return=1,
item=item,
qty=-10,
update_stock=1,
rate=100,
company=company,
warehouse=warehouse,
cost_center="Main - TCP1",
)
# assert that stock consumption is with actual rate
self.assertGLEs(
return_pi,
[{"credit": 1200, "debit": 0}],
gle_filters={"account": "Stock In Hand - TCP1"},
)
# assert loss booked in COGS
self.assertGLEs(
return_pi,
[{"credit": 0, "debit": 200}],
gle_filters={"account": "Cost of Goods Sold - TCP1"},
)
def test_return_with_lcv(self):
from erpnext.controllers.sales_and_purchase_return import make_return_doc
from erpnext.stock.doctype.landed_cost_voucher.test_landed_cost_voucher import (
create_landed_cost_voucher,
)
item = self.make_item().name
company = "_Test Company with perpetual inventory"
warehouse = "Stores - TCP1"
cost_center = "Main - TCP1"
pi = make_purchase_invoice(
item=item,
company=company,
warehouse=warehouse,
cost_center=cost_center,
update_stock=1,
qty=10,
rate=100,
)
# Create landed cost voucher - will increase valuation of received item by 10
create_landed_cost_voucher("Purchase Invoice", pi.name, pi.company, charges=100)
return_pi = make_return_doc(pi.doctype, pi.name)
return_pi.save().submit()
# assert that stock consumption is with actual in rate
self.assertGLEs(
return_pi,
[{"credit": 1100, "debit": 0}],
gle_filters={"account": "Stock In Hand - TCP1"},
)
# assert loss booked in COGS
self.assertGLEs(
return_pi,
[{"credit": 0, "debit": 100}],
gle_filters={"account": "Cost of Goods Sold - TCP1"},
)
def test_multi_currency_gle(self):
pi = make_purchase_invoice(
supplier="_Test Supplier USD",
@@ -1492,9 +1567,41 @@ class TestPurchaseInvoice(unittest.TestCase):
check_gl_entries(self, pr.name, expected_gle_for_purchase_receipt, pr.posting_date)
# Cancel purchase invoice to check reverse provisional entry cancellation
pi.cancel()
expected_gle_for_purchase_receipt_post_pi_cancel = [
["Provision Account - _TC", 0, 250, pi.posting_date],
["_Test Account Cost for Goods Sold - _TC", 250, 0, pi.posting_date],
]
check_gl_entries(
self, pr.name, expected_gle_for_purchase_receipt_post_pi_cancel, pr.posting_date
)
company.enable_provisional_accounting_for_non_stock_items = 0
company.save()
def test_item_less_defaults(self):
pi = frappe.new_doc("Purchase Invoice")
pi.supplier = "_Test Supplier"
pi.company = "_Test Company"
pi.append(
"items",
{
"item_name": "Opening item",
"qty": 1,
"uom": "Tonne",
"stock_uom": "Kg",
"rate": 1000,
"expense_account": "Stock Received But Not Billed - _TC",
},
)
pi.save()
self.assertEqual(pi.items[0].conversion_factor, 1000)
def check_gl_entries(doc, voucher_no, expected_gle, posting_date):
gl_entries = frappe.db.sql(

View File

@@ -53,7 +53,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
me.frm.refresh_fields();
}
erpnext.queries.setup_warehouse_query(this.frm);
erpnext.accounts.dimensions.setup_dimension_filters(this.frm, this.frm.doctype);
},
refresh: function(doc, dt, dn) {
@@ -475,9 +474,17 @@ 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");
}
},
is_cash_or_non_trade_discount() {
this.frm.set_df_property("additional_discount_account", "hidden", 1 - this.frm.doc.is_cash_or_non_trade_discount);
if (!this.frm.doc.is_cash_or_non_trade_discount) {
this.frm.set_value("additional_discount_account", "");
}
}
});
// for backward compatibility: combine new and previous states
@@ -885,27 +892,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;
@@ -916,7 +940,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

@@ -106,6 +106,7 @@
"loyalty_redemption_cost_center",
"section_break_49",
"apply_discount_on",
"is_cash_or_non_trade_discount",
"base_discount_amount",
"additional_discount_account",
"column_break_51",
@@ -413,7 +414,7 @@
},
{
"default": "0",
"depends_on": "eval: doc.is_return && doc.return_against",
"depends_on": "eval: doc.is_return",
"fieldname": "update_billed_amount_in_sales_order",
"fieldtype": "Check",
"hide_days": 1,
@@ -1988,7 +1989,7 @@
{
"fieldname": "additional_discount_account",
"fieldtype": "Link",
"label": "Additional Discount Account",
"label": "Discount Account",
"options": "Account"
},
{
@@ -2026,6 +2027,13 @@
"fieldtype": "Currency",
"label": "Amount Eligible for Commission",
"read_only": 1
},
{
"default": "0",
"depends_on": "eval: doc.apply_discount_on == \"Grand Total\"",
"fieldname": "is_cash_or_non_trade_discount",
"fieldtype": "Check",
"label": "Is Cash or Non Trade Discount"
}
],
"icon": "fa fa-file-text",
@@ -2038,7 +2046,7 @@
"link_fieldname": "consolidated_invoice"
}
],
"modified": "2022-03-08 16:08:53.517903",
"modified": "2022-07-11 17:43:56.435382",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Sales Invoice",

View File

@@ -116,6 +116,7 @@ class SalesInvoice(SellingController):
self.set_income_account_for_fixed_assets()
self.validate_item_cost_centers()
self.validate_income_account()
self.check_conversion_rate()
validate_inter_company_party(
self.doctype, self.customer, self.company, self.inter_company_invoice_reference
@@ -1039,7 +1040,7 @@ class SalesInvoice(SellingController):
)
if grand_total and not self.is_internal_transfer():
# Didnot use base_grand_total to book rounding loss gle
# Did not use base_grand_total to book rounding loss gle
gl_entries.append(
self.get_gl_dict(
{
@@ -1064,6 +1065,22 @@ class SalesInvoice(SellingController):
)
)
if self.apply_discount_on == "Grand Total" and self.get("is_cash_or_discount_account"):
gl_entries.append(
self.get_gl_dict(
{
"account": self.additional_discount_account,
"against": self.debit_to,
"debit": self.base_discount_amount,
"debit_in_account_currency": self.discount_amount,
"cost_center": self.cost_center,
"project": self.project,
},
self.currency,
item=self,
)
)
def make_tax_gl_entries(self, gl_entries):
for tax in self.get("taxes"):
amount, base_amount = self.get_tax_amounts(tax, self.enable_discount_accounting)
@@ -1113,24 +1130,24 @@ class SalesInvoice(SellingController):
asset = self.get_asset(item)
if self.is_return:
if asset.calculate_depreciation:
self.reverse_depreciation_entry_made_after_sale(asset)
self.reset_depreciation_schedule(asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_regain(
asset, item.base_net_amount, item.finance_book
)
asset.db_set("disposal_date", None)
if asset.calculate_depreciation:
self.reverse_depreciation_entry_made_after_sale(asset)
self.reset_depreciation_schedule(asset)
else:
if asset.calculate_depreciation:
self.depreciate_asset(asset)
fixed_asset_gl_entries = get_gl_entries_on_asset_disposal(
asset, item.base_net_amount, item.finance_book
)
asset.db_set("disposal_date", self.posting_date)
if asset.calculate_depreciation:
self.depreciate_asset(asset)
for gle in fixed_asset_gl_entries:
gle["against"] = self.customer
gl_entries.append(self.get_gl_dict(gle, item=item))
@@ -1198,6 +1215,7 @@ class SalesInvoice(SellingController):
asset.save()
make_depreciation_entry(asset.name, self.posting_date)
asset.load_from_db()
def reset_depreciation_schedule(self, asset):
asset.flags.ignore_validate_update_after_submit = True
@@ -1207,6 +1225,7 @@ class SalesInvoice(SellingController):
self.modify_depreciation_schedule_for_asset_repairs(asset)
asset.save()
asset.load_from_db()
def modify_depreciation_schedule_for_asset_repairs(self, asset):
asset_repairs = frappe.get_all(
@@ -2154,11 +2173,13 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
target_detail_field = "sales_invoice_item" if doctype == "Sales Invoice" else "sales_order_item"
source_document_warehouse_field = "target_warehouse"
target_document_warehouse_field = "from_warehouse"
received_items = get_received_items(source_name, target_doctype, target_detail_field)
else:
source_doc = frappe.get_doc(doctype, source_name)
target_doctype = "Sales Invoice" if doctype == "Purchase Invoice" else "Sales Order"
source_document_warehouse_field = "from_warehouse"
target_document_warehouse_field = "target_warehouse"
received_items = {}
validate_inter_company_transaction(source_doc, doctype)
details = get_inter_company_details(source_doc, doctype)
@@ -2224,12 +2245,17 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
shipping_address_name=target_doc.shipping_address_name,
)
def update_item(source, target, source_parent):
target.qty = flt(source.qty) - received_items.get(source.name, 0.0)
item_field_map = {
"doctype": target_doctype + " Item",
"field_no_map": ["income_account", "expense_account", "cost_center", "warehouse"],
"field_map": {
"rate": "rate",
},
"postprocess": update_item,
"condition": lambda doc: doc.qty > 0,
}
if doctype in ["Sales Invoice", "Sales Order"]:
@@ -2267,6 +2293,28 @@ def make_inter_company_transaction(doctype, source_name, target_doc=None):
return doclist
def get_received_items(reference_name, doctype, reference_fieldname):
target_doctypes = frappe.get_all(
doctype,
filters={"inter_company_invoice_reference": reference_name, "docstatus": 1},
as_list=True,
)
if target_doctypes:
target_doctypes = list(target_doctypes[0])
received_items_map = frappe._dict(
frappe.get_all(
doctype + " Item",
filters={"parent": ("in", target_doctypes)},
fields=[reference_fieldname, "qty"],
as_list=1,
)
)
return received_items_map
def set_purchase_references(doc):
# add internal PO or PR links if any
if doc.is_internal_transfer():

View File

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

View File

@@ -1612,6 +1612,17 @@ class TestSalesInvoice(unittest.TestCase):
self.assertTrue(gle)
def test_invoice_exchange_rate(self):
si = create_sales_invoice(
customer="_Test Customer USD",
debit_to="_Test Receivable USD - _TC",
currency="USD",
conversion_rate=1,
do_not_save=1,
)
self.assertRaises(frappe.ValidationError, si.save)
def test_invalid_currency(self):
# Customer currency = USD
@@ -2609,6 +2620,216 @@ class TestSalesInvoice(unittest.TestCase):
einvoice = make_einvoice(si)
validate_totals(einvoice)
def test_einvoice_discounts(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
frappe.db.set_single_value("E Invoice Settings", "dont_show_discounts_in_e_invoice", False)
# Normal Itemized Discount
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[0].price_list_rate = 12
si.items[0].discount_percentage = 16.6666666667
si.items[0].rate = 10
si.items[1].price_list_rate = 15
si.items[1].discount_amount = 5
si.items[1].rate = 10
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 4000)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 2100)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 222)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5555)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on net total
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Net Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 253.61)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 66.57)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 243.11)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5613.71)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on grand total (Itemized Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 214.93)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 56.42)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 239.89)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5604.75)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
# Invoice Discount on grand total (Cash/Non-Trade Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 222.0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 5555.0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 400)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 20)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 10)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[1].price_list_rate = 15
si.items[1].discount_amount = -5
si.items[1].rate = 20
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 20)
def test_einvoice_without_discounts(self):
from erpnext.regional.india.e_invoice.utils import make_einvoice, validate_totals
frappe.db.set_single_value("E Invoice Settings", "dont_show_discounts_in_e_invoice", True)
# Normal Itemized Discount
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[0].price_list_rate = 12
si.items[0].discount_percentage = 16.6666666667
si.items[0].rate = 10
si.items[1].price_list_rate = 15
si.items[1].discount_amount = 5
si.items[1].rate = 10
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 10)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 10)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 18)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 5)
# Invoice Discount on net total
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Net Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 11.87)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 14.84)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 17.81)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 4.95)
# Invoice Discount on grand total (Itemized Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 11.89)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 14.87)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 17.84)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 4.96)
# Invoice Discount on grand total (Cash/Non-Trade Discount)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = "Grand Total"
si.is_cash_or_non_trade_discount = 1
si.discount_amount = 400
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][0]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][2]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][3]["Discount"], 0)
self.assertEqual(einvoice["ValDtls"]["Discount"], 400)
self.assertEqual(einvoice["ItemList"][0]["UnitPrice"], 12)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 15)
self.assertEqual(einvoice["ItemList"][2]["UnitPrice"], 18)
self.assertEqual(einvoice["ItemList"][3]["UnitPrice"], 5)
si = get_sales_invoice_for_e_invoice()
si.apply_discount_on = ""
si.items[1].price_list_rate = 15
si.items[1].discount_amount = -5
si.items[1].rate = 20
si.save()
einvoice = make_einvoice(si)
validate_totals(einvoice)
self.assertEqual(einvoice["ItemList"][1]["Discount"], 0)
self.assertEqual(einvoice["ItemList"][1]["UnitPrice"], 20)
def test_item_tax_net_range(self):
item = create_item("T Shirt")
@@ -3086,6 +3307,39 @@ 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
@@ -3175,6 +3429,36 @@ def get_sales_invoice_for_e_invoice():
},
)
si.append(
"items",
{
"item_code": "_Test Item",
"uom": "Nos",
"warehouse": "_Test Warehouse - _TC",
"qty": 111,
"price_list_rate": 20,
"discount_percentage": 10,
"income_account": "Sales - _TC",
"expense_account": "Cost of Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
},
)
si.append(
"items",
{
"item_code": "_Test Item 2",
"uom": "Nos",
"warehouse": "_Test Warehouse - _TC",
"qty": 1111,
"price_list_rate": 10,
"rate": 5,
"income_account": "Sales - _TC",
"expense_account": "Cost of Goods Sold - _TC",
"cost_center": "_Test Cost Center - _TC",
},
)
return si

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

View File

@@ -212,7 +212,7 @@ def set_address_details(
else:
party_details.update(get_company_address(company))
if doctype and doctype in ["Delivery Note", "Sales Invoice", "Sales Order"]:
if doctype and doctype in ["Delivery Note", "Sales Invoice", "Sales Order", "Quotation"]:
if party_details.company_address:
party_details.update(
get_fetch_values(doctype, "company_address", party_details.company_address)
@@ -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

@@ -42,7 +42,7 @@
{% if(filters.show_future_payments) { %}
{% var balance_row = data.slice(-1).pop();
var start = filters.based_on_payment_terms ? 13 : 11;
var start = report.columns.findIndex((elem) => (elem.fieldname == 'age'));
var range1 = report.columns[start].label;
var range2 = report.columns[start+1].label;
var range3 = report.columns[start+2].label;

View File

@@ -43,7 +43,7 @@ def get_columns():
"options": "Account",
"width": 170,
},
{"label": _("Amount"), "fieldname": "amount", "width": 120},
{"label": _("Amount"), "fieldname": "amount", "fieldtype": "Currency", "width": 120},
]
return columns

View File

@@ -198,10 +198,12 @@ 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
query = (
frappe.qb.from_(loan_doc)
@@ -214,14 +216,12 @@ 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")))
)
if doctype == "Loan Repayment":
query.where(loan_doc.repay_from_salary == 0)
entries = query.run(as_dict=1)
loan_docs.extend(entries)
@@ -267,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 ""
@@ -468,7 +468,7 @@ def get_accountwise_gle(filters, accounting_dimensions, gl_entries, gle_map):
update_value_in_dict(totals, "opening", gle)
update_value_in_dict(totals, "closing", gle)
elif gle.posting_date <= to_date:
elif gle.posting_date <= to_date or (cstr(gle.is_opening) == "Yes" and show_opening_entries):
if not group_by_voucher_consolidated:
update_value_in_dict(gle_map[group_by_value].totals, "total", gle)
update_value_in_dict(gle_map[group_by_value].totals, "closing", gle)

View File

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

View File

@@ -443,12 +443,6 @@ def get_grand_total(filters, doctype):
] # nosec
def get_deducted_taxes():
return frappe.db.sql_list(
"select name from `tabPurchase Taxes and Charges` where add_deduct_tax = 'Deduct'"
)
def get_tax_accounts(
item_list,
columns,
@@ -462,6 +456,7 @@ def get_tax_accounts(
tax_columns = []
invoice_item_row = {}
itemised_tax = {}
add_deduct_tax = "charge_type"
tax_amount_precision = (
get_field_precision(
@@ -477,13 +472,13 @@ def get_tax_accounts(
conditions = ""
if doctype == "Purchase Invoice":
conditions = " and category in ('Total', 'Valuation and Total') and base_tax_amount_after_discount_amount != 0"
add_deduct_tax = "add_deduct_tax"
deducted_tax = get_deducted_taxes()
tax_details = frappe.db.sql(
"""
select
name, parent, description, item_wise_tax_detail,
charge_type, base_tax_amount_after_discount_amount
charge_type, {add_deduct_tax}, base_tax_amount_after_discount_amount
from `tab%s`
where
parenttype = %s and docstatus = 1
@@ -491,12 +486,22 @@ def get_tax_accounts(
and parent in (%s)
%s
order by description
"""
""".format(
add_deduct_tax=add_deduct_tax
)
% (tax_doctype, "%s", ", ".join(["%s"] * len(invoice_item_row)), conditions),
tuple([doctype] + list(invoice_item_row)),
)
for name, parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
for (
name,
parent,
description,
item_wise_tax_detail,
charge_type,
add_deduct_tax,
tax_amount,
) in tax_details:
description = handle_html(description)
if description not in tax_columns and tax_amount:
# as description is text editor earlier and markup can break the column convention in reports
@@ -529,7 +534,9 @@ def get_tax_accounts(
if item_tax_amount:
tax_value = flt(item_tax_amount, tax_amount_precision)
tax_value = (
tax_value * -1 if (doctype == "Purchase Invoice" and name in deducted_tax) else tax_value
tax_value * -1
if (doctype == "Purchase Invoice" and add_deduct_tax == "Deduct")
else tax_value
)
itemised_tax.setdefault(d.name, {})[description] = frappe._dict(

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

@@ -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

@@ -346,9 +346,13 @@ def get_columns(invoice_list, additional_table_columns):
def get_conditions(filters):
conditions = ""
accounting_dimensions = get_accounting_dimensions(as_list=False) or []
accounting_dimensions_list = [d.fieldname for d in accounting_dimensions]
if filters.get("company"):
conditions += " and company=%(company)s"
if filters.get("customer"):
if filters.get("customer") and "customer" not in accounting_dimensions_list:
conditions += " and customer = %(customer)s"
if filters.get("from_date"):
@@ -359,32 +363,18 @@ def get_conditions(filters):
if filters.get("owner"):
conditions += " and owner = %(owner)s"
if filters.get("mode_of_payment"):
conditions += """ and exists(select name from `tabSales Invoice Payment`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
def get_sales_invoice_item_field_condition(field, table="Sales Invoice Item") -> str:
if not filters.get(field) or field in accounting_dimensions_list:
return ""
return f""" and exists(select name from `tab{table}`
where parent=`tabSales Invoice`.name
and ifnull(`tab{table}`.{field}, '') = %({field})s)"""
if filters.get("cost_center"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.cost_center, '') = %(cost_center)s)"""
if filters.get("warehouse"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.warehouse, '') = %(warehouse)s)"""
if filters.get("brand"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.brand, '') = %(brand)s)"""
if filters.get("item_group"):
conditions += """ and exists(select name from `tabSales Invoice Item`
where parent=`tabSales Invoice`.name
and ifnull(`tabSales Invoice Item`.item_group, '') = %(item_group)s)"""
accounting_dimensions = get_accounting_dimensions(as_list=False)
conditions += get_sales_invoice_item_field_condition("mode_of_payments", "Sales Invoice Payment")
conditions += get_sales_invoice_item_field_condition("cost_center")
conditions += get_sales_invoice_item_field_condition("warehouse")
conditions += get_sales_invoice_item_field_condition("brand")
conditions += get_sales_invoice_item_field_condition("item_group")
if accounting_dimensions:
common_condition = """
@@ -405,7 +395,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

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

View File

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

View File

@@ -160,14 +160,12 @@ def get_rootwise_opening_balances(filters, report_type):
if filters.project:
additional_conditions += " and project = %(project)s"
if filters.finance_book:
fb_conditions = " AND finance_book = %(finance_book)s"
if filters.include_default_book_entries:
fb_conditions = (
" AND (finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)"
)
additional_conditions += fb_conditions
if filters.get("include_default_book_entries"):
additional_conditions += (
" AND (finance_book in (%(finance_book)s, %(company_fb)s, '') OR finance_book IS NULL)"
)
else:
additional_conditions += " AND (finance_book in (%(finance_book)s, '') OR finance_book IS NULL)"
accounting_dimensions = get_accounting_dimensions(as_list=False)
@@ -188,9 +186,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

@@ -0,0 +1,49 @@
import unittest
from typing import List, Tuple
from erpnext.tests.utils import ReportFilters, ReportName, execute_script_report
DEFAULT_FILTERS = {
"company": "_Test Company",
"from_date": "2010-01-01",
"to_date": "2030-01-01",
"period_start_date": "2010-01-01",
"period_end_date": "2030-01-01",
}
REPORT_FILTER_TEST_CASES: List[Tuple[ReportName, ReportFilters]] = [
("General Ledger", {"group_by": "Group by Voucher (Consolidated)"}),
("General Ledger", {"group_by": "Group by Voucher (Consolidated)", "include_dimensions": 1}),
("Accounts Payable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}),
("Accounts Receivable", {"range1": 30, "range2": 60, "range3": 90, "range4": 120}),
("Consolidated Financial Statement", {"report": "Balance Sheet"}),
("Consolidated Financial Statement", {"report": "Profit and Loss Statement"}),
("Consolidated Financial Statement", {"report": "Cash Flow"}),
("Gross Profit", {"group_by": "Invoice"}),
("Gross Profit", {"group_by": "Item Code"}),
("Gross Profit", {"group_by": "Item Group"}),
("Gross Profit", {"group_by": "Customer"}),
("Gross Profit", {"group_by": "Customer Group"}),
("Item-wise Sales Register", {}),
("Item-wise Purchase Register", {}),
("Sales Register", {}),
("Sales Register", {"item_group": "All Item Groups"}),
("Purchase Register", {}),
]
OPTIONAL_FILTERS = {}
class TestReports(unittest.TestCase):
def test_execute_all_accounts_reports(self):
"""Test that all script report in stock modules are executable with supported filters"""
for report, filter in REPORT_FILTER_TEST_CASES:
with self.subTest(report=report):
execute_script_report(
report_name=report,
module="Accounts",
filters=filter,
default_filters=DEFAULT_FILTERS,
optional_filters=OPTIONAL_FILTERS if filter.get("_optional") else None,
)

View File

@@ -62,8 +62,8 @@ class TestUtils(unittest.TestCase):
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)
se2 = make_stock_entry(posting_date="2022-02-01", **stock_entry)
for doc in (se1, se2, se3):
vouchers.append((doc.doctype, doc.name))

View File

@@ -3,13 +3,23 @@
from json import loads
from typing import List, Tuple
from typing import TYPE_CHECKING, List, Optional, Tuple
import frappe
import frappe.defaults
from frappe import _, throw
from frappe.model.meta import get_field_precision
from frappe.utils import cint, cstr, flt, formatdate, get_number_format_info, getdate, now, nowdate
from frappe.utils import (
cint,
create_batch,
cstr,
flt,
formatdate,
get_number_format_info,
getdate,
now,
nowdate,
)
from six import string_types
import erpnext
@@ -19,6 +29,9 @@ from erpnext.accounts.doctype.account.account import get_account_currency # noq
from erpnext.stock import get_warehouse_account_map
from erpnext.stock.utils import get_stock_value_on
if TYPE_CHECKING:
from erpnext.stock.doctype.repost_item_valuation.repost_item_valuation import RepostItemValuation
class FiscalYearError(frappe.ValidationError):
pass
@@ -28,6 +41,9 @@ class PaymentEntryUnlinkError(frappe.ValidationError):
pass
GL_REPOSTING_CHUNK = 100
@frappe.whitelist()
def get_fiscal_year(
date=None, fiscal_year=None, label="Date", verbose=1, company=None, as_dict=False
@@ -1122,38 +1138,55 @@ def update_gl_entries_after(
def repost_gle_for_stock_vouchers(
stock_vouchers, posting_date, company=None, warehouse_account=None
stock_vouchers: List[Tuple[str, str]],
posting_date: str,
company: Optional[str] = None,
warehouse_account=None,
repost_doc: Optional["RepostItemValuation"] = None,
):
if not stock_vouchers:
return
def _delete_gl_entries(voucher_type, voucher_no):
frappe.db.sql(
"""delete from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""",
(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)
precision = get_field_precision(frappe.get_meta("GL Entry").get_field("debit")) or 2
gle = get_voucherwise_gl_entries(stock_vouchers, posting_date)
for voucher_type, voucher_no in stock_vouchers:
existing_gle = gle.get((voucher_type, voucher_no), [])
voucher_obj = frappe.get_cached_doc(voucher_type, voucher_no)
expected_gle = voucher_obj.get_gl_entries(warehouse_account)
if expected_gle:
if not existing_gle or not compare_existing_and_expected_gle(
existing_gle, expected_gle, precision
):
stock_vouchers = sort_stock_vouchers_by_posting_date(stock_vouchers)
if repost_doc and repost_doc.gl_reposting_index:
# Restore progress
stock_vouchers = stock_vouchers[cint(repost_doc.gl_reposting_index) :]
for stock_vouchers_chunk in create_batch(stock_vouchers, GL_REPOSTING_CHUNK):
gle = get_voucherwise_gl_entries(stock_vouchers_chunk, posting_date)
for voucher_type, voucher_no in stock_vouchers_chunk:
existing_gle = gle.get((voucher_type, voucher_no), [])
voucher_obj = frappe.get_doc(voucher_type, voucher_no)
expected_gle = voucher_obj.get_gl_entries(warehouse_account)
if expected_gle:
if not existing_gle or not compare_existing_and_expected_gle(
existing_gle, expected_gle, precision
):
_delete_gl_entries(voucher_type, voucher_no)
voucher_obj.make_gl_entries(gl_entries=expected_gle, from_repost=True)
else:
_delete_gl_entries(voucher_type, voucher_no)
voucher_obj.make_gl_entries(gl_entries=expected_gle, from_repost=True)
else:
_delete_gl_entries(voucher_type, voucher_no)
if not frappe.flags.in_test:
frappe.db.commit()
if repost_doc:
repost_doc.db_set(
"gl_reposting_index", cint(repost_doc.gl_reposting_index) + len(stock_vouchers_chunk)
)
def _delete_gl_entries(voucher_type, voucher_no):
frappe.db.sql(
"""delete from `tabGL Entry`
where voucher_type=%s and voucher_no=%s""",
(voucher_type, voucher_no),
)
def sort_stock_vouchers_by_posting_date(
@@ -1167,6 +1200,9 @@ def sort_stock_vouchers_by_posting_date(
.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)
.orderby(sle.posting_date)
.orderby(sle.posting_time)
.orderby(sle.creation)
).run(as_dict=True)
sorted_vouchers = [(sle.voucher_type, sle.voucher_no) for sle in sles]

View File

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

View File

@@ -257,6 +257,7 @@ class Asset(AccountsController):
number_of_pending_depreciations += 1
skip_row = False
should_get_last_day = is_last_day_of_the_month(finance_book.depreciation_start_date)
for n in range(start[finance_book.idx - 1], number_of_pending_depreciations):
# If depreciation is already completed (for double declining balance)
@@ -270,6 +271,9 @@ class Asset(AccountsController):
finance_book.depreciation_start_date, n * cint(finance_book.frequency_of_depreciation)
)
if should_get_last_day:
schedule_date = get_last_day(schedule_date)
# schedule date will be a year later from start date
# so monthly schedule date is calculated by removing 11 months from it
monthly_schedule_date = add_months(schedule_date, -finance_book.frequency_of_depreciation + 1)
@@ -349,61 +353,16 @@ class Asset(AccountsController):
skip_row = True
if depreciation_amount > 0:
# With monthly depreciation, each depreciation is divided by months remaining until next date
if self.allow_monthly_depreciation:
# month range is 1 to 12
# In pro rata case, for first and last depreciation, month range would be different
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
)
for r in range(month_range):
if has_pro_rata and n == 0:
# For first entry of monthly depr
if r == 0:
days_until_first_depr = date_diff(monthly_schedule_date, self.available_for_use_date) + 1
per_day_amt = depreciation_amount / days
depreciation_amount_for_current_month = per_day_amt * days_until_first_depr
depreciation_amount -= depreciation_amount_for_current_month
date = monthly_schedule_date
amount = depreciation_amount_for_current_month
else:
date = add_months(monthly_schedule_date, r)
amount = depreciation_amount / (month_range - 1)
elif (has_pro_rata and n == cint(number_of_pending_depreciations) - 1) and r == cint(
month_range
) - 1:
# For last entry of monthly depr
date = last_schedule_date
amount = depreciation_amount / month_range
else:
date = add_months(monthly_schedule_date, r)
amount = depreciation_amount / month_range
self.append(
"schedules",
{
"schedule_date": date,
"depreciation_amount": amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
else:
self.append(
"schedules",
{
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
self.append(
"schedules",
{
"schedule_date": schedule_date,
"depreciation_amount": depreciation_amount,
"depreciation_method": finance_book.depreciation_method,
"finance_book": finance_book.finance_book,
"finance_book_id": finance_book.idx,
},
)
# depreciation schedules need to be cleared before modification due to increase in asset life/asset sales
# JE: Journal Entry, FB: Finance Book
@@ -845,16 +804,11 @@ class Asset(AccountsController):
if args.get("rate_of_depreciation") and on_validate:
return args.get("rate_of_depreciation")
no_of_years = (
flt(args.get("total_number_of_depreciations") * flt(args.get("frequency_of_depreciation")))
/ 12
)
value = flt(args.get("expected_value_after_useful_life")) / flt(self.gross_purchase_amount)
# square root of flt(salvage_value) / flt(asset_cost)
depreciation_rate = math.pow(value, 1.0 / flt(no_of_years, 2))
depreciation_rate = math.pow(value, 1.0 / flt(args.get("total_number_of_depreciations"), 2))
return 100 * (1 - flt(depreciation_rate, float_precision))
return flt((100 * (1 - depreciation_rate)), float_precision)
def get_pro_rata_amt(self, row, depreciation_amount, from_date, to_date):
days = date_diff(to_date, from_date)
@@ -1103,9 +1057,18 @@ def is_cwip_accounting_enabled(asset_category):
def get_total_days(date, frequency):
period_start_date = add_months(date, cint(frequency) * -1)
if is_last_day_of_the_month(date):
period_start_date = get_last_day(period_start_date)
return date_diff(date, period_start_date)
def is_last_day_of_the_month(date):
last_day_of_the_month = get_last_day(date)
return getdate(last_day_of_the_month) == getdate(date)
@erpnext.allow_regional
def get_depreciation_amount(asset, depreciable_value, row):
if row.depreciation_method in ("Straight Line", "Manual"):

View File

@@ -145,6 +145,7 @@ class TestAsset(AssetSetup):
def test_is_fixed_asset_set(self):
asset = create_asset(is_existing_asset=1)
doc = frappe.new_doc("Purchase Invoice")
doc.company = "_Test Company"
doc.supplier = "_Test Supplier"
doc.append("items", {"item_code": "Macbook Pro", "qty": 1, "asset": asset.name})
@@ -201,23 +202,23 @@ class TestAsset(AssetSetup):
depreciation_start_date="2020-12-31",
submit=1,
)
post_depreciation_entries(date="2021-01-01")
si = make_sales_invoice(asset=asset.name, item_code="Macbook Pro", company="_Test Company")
si.customer = "_Test Customer"
si.due_date = nowdate()
si.get("items")[0].rate = 25000
si.insert()
si.set_posting_time = 1
si.posting_date = "2021-10-31"
si.due_date = "2021-10-31"
si.get("items")[0].rate = 75000
si.submit()
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Sold")
expected_gle = (
("_Test Accumulated Depreciations - _TC", 20490.2, 0.0),
("_Test Accumulated Depreciations - _TC", 50490.2, 0.0),
("_Test Fixed Asset - _TC", 0.0, 100000.0),
("_Test Gain/Loss on Asset Disposal - _TC", 54509.8, 0.0),
("Debtors - _TC", 25000.0, 0.0),
("_Test Gain/Loss on Asset Disposal - _TC", 0.0, 25490.2),
("Debtors - _TC", 75000.0, 0.0),
)
gle = frappe.db.sql(
@@ -227,9 +228,14 @@ class TestAsset(AssetSetup):
si.name,
)
self.assertEqual(gle, expected_gle)
for i, gle_entry in enumerate(gle):
self.assertEqual(gle_entry[0], expected_gle[i][0])
self.assertEqual(flt(gle_entry[1], 1), flt(expected_gle[i][1], 1))
self.assertEqual(flt(gle_entry[2], 1), flt(expected_gle[i][2], 1))
si.load_from_db()
si.cancel()
self.assertEqual(frappe.db.get_value("Asset", asset.name, "status"), "Partially Depreciated")
def test_expense_head(self):
@@ -696,6 +702,41 @@ class TestDepreciationMethods(AssetSetup):
asset.reload()
self.assertEquals(asset.finance_books[0].value_after_depreciation, 98000.0)
def test_monthly_depreciation_by_wdv_method(self):
existing_precision = frappe.db.get_default("float_precision")
frappe.db.set_default("float_precision", 3)
asset = create_asset(
calculate_depreciation=1,
available_for_use_date="2022-02-15",
purchase_date="2022-02-15",
depreciation_method="Written Down Value",
gross_purchase_amount=10000,
expected_value_after_useful_life=5000,
depreciation_start_date="2022-02-28",
total_number_of_depreciations=5,
frequency_of_depreciation=1,
)
expected_schedules = [
["2022-02-28", 647.25, 647.25],
["2022-03-31", 1210.71, 1857.96],
["2022-04-30", 1053.99, 2911.95],
["2022-05-31", 917.55, 3829.5],
["2022-06-30", 798.77, 4628.27],
["2022-07-15", 371.73, 5000.0],
]
schedules = [
[
cstr(d.schedule_date),
flt(d.depreciation_amount, 2),
flt(d.accumulated_depreciation_amount, 2),
]
for d in asset.get("schedules")
]
self.assertEqual(schedules, expected_schedules)
frappe.db.set_default("float_precision", existing_precision)
class TestDepreciationBasics(AssetSetup):
def test_depreciation_without_pro_rata(self):
@@ -782,7 +823,7 @@ class TestDepreciationBasics(AssetSetup):
expected_values = [["2020-12-31", 30000.0], ["2021-12-31", 30000.0], ["2022-12-31", 30000.0]]
for i, schedule in enumerate(asset.schedules):
self.assertEqual(expected_values[i][0], schedule.schedule_date)
self.assertEqual(getdate(expected_values[i][0]), schedule.schedule_date)
self.assertEqual(expected_values[i][1], schedule.depreciation_amount)
def test_set_accumulated_depreciation(self):
@@ -1256,6 +1297,32 @@ class TestDepreciationBasics(AssetSetup):
asset.cost_center = "Main - _TC"
asset.submit()
def test_depreciation_on_final_day_of_the_month(self):
"""Tests if final day of the month is picked each time, if the depreciation start date is the last day of the month."""
asset = create_asset(
item_code="Macbook Pro",
calculate_depreciation=1,
purchase_date="2020-01-30",
available_for_use_date="2020-02-15",
depreciation_start_date="2020-02-29",
frequency_of_depreciation=1,
total_number_of_depreciations=5,
submit=1,
)
expected_dates = [
"2020-02-29",
"2020-03-31",
"2020-04-30",
"2020-05-31",
"2020-06-30",
"2020-07-15",
]
for i, schedule in enumerate(asset.schedules):
self.assertEqual(getdate(expected_dates[i]), getdate(schedule.schedule_date))
def create_asset_data():
if not frappe.db.exists("Asset Category", "Computers"):

View File

@@ -43,8 +43,6 @@ frappe.ui.form.on("Purchase Order", {
erpnext.queries.setup_queries(frm, "Warehouse", function() {
return erpnext.queries.warehouse(frm.doc);
});
erpnext.accounts.dimensions.setup_dimension_filters(frm, frm.doctype);
},
apply_tds: function(frm) {
@@ -427,7 +425,7 @@ erpnext.buying.PurchaseOrderController = erpnext.buying.BuyingController.extend(
company: me.frm.doc.company
},
allow_child_item_selection: true,
child_fielname: "items",
child_fieldname: "items",
child_columns: ["item_code", "qty"]
})
}, __("Get Items From"));

View File

@@ -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

@@ -140,6 +140,43 @@ class TestPurchaseOrder(FrappeTestCase):
# ordered qty decreases as ordered qty is 0 (deleted row)
self.assertEqual(get_ordered_qty(), existing_ordered_qty - 10) # 0
def test_supplied_items_validations_on_po_update_after_submit(self):
po = create_purchase_order(item_code="_Test FG Item", is_subcontracted="Yes", qty=5, rate=100)
item = po.items[0]
original_supplied_items = {po.name: po.required_qty for po in po.supplied_items}
# Just update rate
trans_item = [
{
"item_code": "_Test FG Item",
"rate": 20,
"qty": 5,
"conversion_factor": 1.0,
"docname": item.name,
}
]
update_child_qty_rate("Purchase Order", json.dumps(trans_item), po.name)
po.reload()
new_supplied_items = {po.name: po.required_qty for po in po.supplied_items}
self.assertEqual(set(original_supplied_items.keys()), set(new_supplied_items.keys()))
# Update qty to 2x
trans_item[0]["qty"] *= 2
update_child_qty_rate("Purchase Order", json.dumps(trans_item), po.name)
po.reload()
new_supplied_items = {po.name: po.required_qty for po in po.supplied_items}
self.assertEqual(2 * sum(original_supplied_items.values()), sum(new_supplied_items.values()))
# Set transfer qty and attempt to update qty, shouldn't be allowed
po.supplied_items[0].supplied_qty = 2
po.supplied_items[0].db_update()
trans_item[0]["qty"] *= 2
with self.assertRaises(frappe.ValidationError):
update_child_qty_rate("Purchase Order", json.dumps(trans_item), po.name)
def test_update_child(self):
mr = make_material_request(qty=10)
po = make_purchase_order(mr.name)

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

@@ -113,7 +113,7 @@ class RequestforQuotation(BuyingController):
def get_link(self):
# RFQ link for supplier portal
return get_url("/rfq/" + self.name)
return get_url("/app/request-for-quotation/" + self.name)
def update_supplier_part_no(self, supplier):
self.vendor = supplier
@@ -181,12 +181,20 @@ class RequestforQuotation(BuyingController):
doc_args = self.as_dict()
doc_args.update({"supplier": data.get("supplier"), "supplier_name": data.get("supplier_name")})
# Get Contact Full Name
supplier_name = None
if data.get("contact"):
contact_name = frappe.db.get_value(
"Contact", data.get("contact"), ["first_name", "middle_name", "last_name"]
)
supplier_name = (" ").join(x for x in contact_name if x) # remove any blank values
args = {
"update_password_link": update_password_link,
"message": frappe.render_template(self.message_for_supplier, doc_args),
"rfq_link": rfq_link,
"user_fullname": full_name,
"supplier_name": data.get("supplier_name"),
"supplier_name": supplier_name or data.get("supplier_name"),
"supplier_salutation": self.salutation or "Dear Mx.",
}

View File

@@ -84,6 +84,9 @@ class Supplier(TransactionBase):
self.save()
def validate_internal_supplier(self):
if not self.is_internal_supplier:
self.represents_company = ""
internal_supplier = frappe.db.get_value(
"Supplier",
{

View File

@@ -59,6 +59,7 @@ frappe.query_reports["Purchase Order Analysis"] = {
for (let option of status){
options.push({
"value": option,
"label": __(option),
"description": ""
})
}

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
@@ -46,6 +47,7 @@ from erpnext.controllers.print_settings import (
from erpnext.controllers.sales_and_purchase_return import validate_return
from erpnext.exceptions import InvalidCurrency
from erpnext.setup.utils import get_exchange_rate
from erpnext.stock.doctype.item.item import get_uom_conv_factor
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
from erpnext.stock.get_item_details import (
_get_item_tax_template,
@@ -149,6 +151,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 +171,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"
@@ -383,6 +387,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
@@ -538,6 +550,15 @@ class AccountsController(TransactionBase):
if ret.get("pricing_rules"):
self.apply_pricing_rule_on_items(item, ret)
self.set_pricing_rule_details(item, ret)
else:
# Transactions line item without item code
uom = item.get("uom")
stock_uom = item.get("stock_uom")
if bool(uom) != bool(stock_uom): # xor
item.stock_uom = item.uom = uom or stock_uom
item.conversion_factor = get_uom_conv_factor(item.get("uom"), item.get("stock_uom"))
if self.doctype == "Purchase Invoice":
self.set_expense_account(for_validate)
@@ -1117,11 +1138,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,
},
@@ -1136,11 +1156,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,
},
@@ -1437,6 +1457,34 @@ 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)
allow_multi_currency_invoices_against_single_party_account = frappe.db.get_singles_value(
"Accounts Settings", "allow_multi_currency_invoices_against_single_party_account"
)
if (
not party_gle_currency
and (party_account_currency != self.currency)
and not allow_multi_currency_invoices_against_single_party_account
):
frappe.throw(
_("Party Account {0} currency ({1}) and document currency ({2}) should be same").format(
frappe.bold(party_account), party_account_currency, self.currency
)
)
def delink_advance_entries(self, linked_doc_name):
total_allocated_amount = 0
for adv in self.advances:
@@ -1736,6 +1784,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
@@ -1803,6 +1853,17 @@ class AccountsController(TransactionBase):
jv.save()
jv.submit()
def check_conversion_rate(self):
default_currency = erpnext.get_company_currency(self.company)
if not default_currency:
throw(_("Please enter default currency in Company Master"))
if (
(self.currency == default_currency and flt(self.conversion_rate) != 1.00)
or not self.conversion_rate
or (self.currency != default_currency and flt(self.conversion_rate) == 1.00)
):
throw(_("Conversion rate cannot be 0 or 1"))
@frappe.whitelist()
def get_tax_rate(account_head):
@@ -2384,7 +2445,7 @@ def update_bin_on_delete(row, doctype):
update_bin_qty(row.item_code, row.warehouse, qty_dict)
def validate_and_delete_children(parent, data):
def validate_and_delete_children(parent, data) -> bool:
deleted_children = []
updated_item_names = [d.get("docname") for d in data]
for item in parent.items:
@@ -2403,6 +2464,8 @@ def validate_and_delete_children(parent, data):
for d in deleted_children:
update_bin_on_delete(d, parent.doctype)
return bool(deleted_children)
@frappe.whitelist()
def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, child_docname="items"):
@@ -2449,20 +2512,55 @@ 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"))
def should_update_supplied_items(doc) -> bool:
"""Subcontracted PO can allow following changes *after submit*:
1. Change rate of subcontracting - regardless of other changes.
2. Change qty and/or add new items and/or remove items
Exception: Transfer/Consumption is already made, qty change not allowed.
"""
supplied_items_processed = any(
item.supplied_qty or item.consumed_qty or item.returned_qty for item in doc.supplied_items
)
update_supplied_items = (
any_qty_changed or items_added_or_removed or any_conversion_factor_changed
)
if update_supplied_items and supplied_items_processed:
frappe.throw(_("Item qty can not be updated as raw materials are already processed."))
return update_supplied_items
data = json.loads(trans_items)
any_qty_changed = False # updated to true if any item's qty changes
items_added_or_removed = False # updated to true if any new item is added or removed
any_conversion_factor_changed = False
sales_doctypes = ["Sales Order", "Sales Invoice", "Delivery Note", "Quotation"]
parent = frappe.get_doc(parent_doctype, parent_doctype_name)
check_doc_permissions(parent, "write")
validate_and_delete_children(parent, data)
_removed_items = validate_and_delete_children(parent, data)
items_added_or_removed |= _removed_items
for d in data:
new_child_flag = False
@@ -2473,6 +2571,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
if not d.get("docname"):
new_child_flag = True
items_added_or_removed = True
check_doc_permissions(parent, "create")
child_item = get_new_child_item(d)
else:
@@ -2495,6 +2594,7 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
qty_unchanged = prev_qty == new_qty
uom_unchanged = prev_uom == new_uom
conversion_factor_unchanged = prev_con_fac == new_con_fac
any_conversion_factor_changed |= not conversion_factor_unchanged
date_unchanged = (
prev_date == getdate(new_date) if prev_date and new_date else False
) # in case of delivery note etc
@@ -2508,6 +2608,8 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
continue
validate_quantity(child_item, d)
if flt(child_item.get("qty")) != flt(d.get("qty")):
any_qty_changed = True
child_item.qty = flt(d.get("qty"))
rate_precision = child_item.precision("rate") or 2
@@ -2613,10 +2715,12 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name, chil
parent.update_ordered_and_reserved_qty()
parent.update_receiving_percentage()
if parent.is_subcontracted == "Yes":
parent.update_reserved_qty_for_subcontract()
parent.create_raw_materials_supplied("supplied_items")
if should_update_supplied_items(parent):
parent.update_reserved_qty_for_subcontract()
parent.create_raw_materials_supplied("supplied_items")
parent.save()
else:
else: # Sales Order
parent.validate_warehouse()
parent.update_reserved_qty()
parent.update_project()
parent.update_prevdoc_status("submit")

View File

@@ -299,21 +299,23 @@ class BuyingController(StockController, Subcontracting):
raise_error_if_no_rate=False,
)
rate = flt(outgoing_rate * d.conversion_factor, d.precision("rate"))
rate = flt(outgoing_rate * (d.conversion_factor or 1), d.precision("rate"))
else:
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), "rate")
field = "incoming_rate" if self.get("is_internal_supplier") else "rate"
rate = frappe.db.get_value(ref_doctype, d.get(frappe.scrub(ref_doctype)), field)
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

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

View File

@@ -316,7 +316,7 @@ def get_returned_qty_map_for_row(return_against, party, row_name, doctype):
return data[0]
def make_return_doc(doctype, source_name, target_doc=None):
def make_return_doc(doctype: str, source_name: str, target_doc=None):
from frappe.model.mapper import get_mapped_doc
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos

View File

@@ -446,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
@@ -613,13 +614,13 @@ class SellingController(StockController):
stock_items = [d.item_code, d.description, d.warehouse, ""]
non_stock_items = [d.item_code, d.description]
duplicate_items_msg = _("Item {0} entered multiple times.").format(frappe.bold(d.item_code))
duplicate_items_msg += "<br><br>"
duplicate_items_msg += _("Please enable {} in {} to allow same item in multiple rows").format(
frappe.bold("Allow Item to Be Added Multiple Times in a Transaction"),
get_link_to_form("Selling Settings", "Selling Settings"),
)
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
duplicate_items_msg = _("Item {0} entered multiple times.").format(frappe.bold(d.item_code))
duplicate_items_msg += "<br><br>"
duplicate_items_msg += _("Please enable {} in {} to allow same item in multiple rows").format(
frappe.bold("Allow Item to Be Added Multiple Times in a Transaction"),
get_link_to_form("Selling Settings", "Selling Settings"),
)
if stock_items in check_list:
frappe.throw(duplicate_items_msg)
else:

View File

@@ -35,7 +35,8 @@ status_map = {
["Draft", None],
["Open", "eval:self.docstatus==1"],
["Lost", "eval:self.status=='Lost'"],
["Ordered", "has_sales_order"],
["Partially Ordered", "is_partially_ordered"],
["Ordered", "is_fully_ordered"],
["Cancelled", "eval:self.docstatus==2"],
],
"Sales Order": [

View File

@@ -166,7 +166,7 @@ class StockController(AccountsController):
"against": warehouse_account[sle.warehouse]["account"],
"cost_center": item_row.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(sle.stock_value_difference, precision),
"debit": -1 * flt(sle.stock_value_difference, precision),
"project": item_row.get("project") or self.get("project"),
"is_opening": item_row.get("is_opening") or self.get("is_opening") or "No",
},

View File

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

View File

@@ -500,6 +500,9 @@ class calculate_taxes_and_totals(object):
else:
self.doc.grand_total = flt(self.doc.net_total)
if self.doc.apply_discount_on == "Grand Total" and self.doc.get("is_cash_or_non_trade_discount"):
self.doc.grand_total -= self.doc.discount_amount
if self.doc.get("taxes"):
self.doc.total_taxes_and_charges = flt(
self.doc.grand_total - self.doc.net_total - flt(self.doc.rounding_adjustment),
@@ -594,6 +597,12 @@ class calculate_taxes_and_totals(object):
if not self.doc.apply_discount_on:
frappe.throw(_("Please select Apply Discount On"))
if self.doc.apply_discount_on == "Grand Total" and self.doc.get(
"is_cash_or_non_trade_discount"
):
self.discount_amount_applied = True
return
self.doc.base_discount_amount = flt(
self.doc.discount_amount * self.doc.conversion_rate, self.doc.precision("base_discount_amount")
)

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -38,7 +38,7 @@ def is_search_module_loaded():
out = cache.execute_command("MODULE LIST")
parsed_output = " ".join(
(" ".join([s.decode() for s in o if not isinstance(s, int)]) for o in out)
(" ".join([frappe.as_unicode(s) for s in o if not isinstance(s, int)]) for o in out)
)
return "search" in parsed_output
except Exception:

View File

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

View File

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

View File

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

View File

@@ -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

@@ -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

@@ -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"]},
@@ -454,9 +455,20 @@ after_migrate = ["erpnext.setup.install.update_select_perm_after_install"]
scheduler_events = {
"cron": {
"0/5 * * * *": [
"erpnext.manufacturing.doctype.bom_update_log.bom_update_log.resume_bom_cost_update_jobs",
],
"0/30 * * * *": [
"erpnext.utilities.doctype.video.video.update_youtube_data",
]
],
# Hourly but offset by 30 minutes
"30 * * * *": [
"erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
],
# Daily but offset by 45 minutes
"45 0 * * *": [
"erpnext.stock.reorder_item.reorder_item",
],
},
"all": [
"erpnext.projects.doctype.project.project.project_status_update_reminder",
@@ -468,19 +480,17 @@ scheduler_events = {
"erpnext.hr.doctype.daily_work_summary_group.daily_work_summary_group.trigger_emails",
"erpnext.accounts.doctype.subscription.subscription.process_all",
"erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_settings.schedule_get_order_details",
"erpnext.accounts.doctype.gl_entry.gl_entry.rename_gle_sle_docs",
"erpnext.erpnext_integrations.doctype.plaid_settings.plaid_settings.automatic_synchronization",
"erpnext.projects.doctype.project.project.hourly_reminder",
"erpnext.projects.doctype.project.project.collect_project_status",
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
"erpnext.support.doctype.issue.issue.set_service_level_agreement_variance",
"erpnext.erpnext_integrations.connectors.shopify_connection.sync_old_orders",
],
"hourly_long": [
"erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries"
"erpnext.stock.doctype.repost_item_valuation.repost_item_valuation.repost_entries",
"erpnext.hr.doctype.shift_type.shift_type.process_auto_attendance_for_all_shifts",
],
"daily": [
"erpnext.stock.reorder_item.reorder_item",
"erpnext.support.doctype.issue.issue.auto_close_tickets",
"erpnext.crm.doctype.opportunity.opportunity.auto_close_opportunity",
"erpnext.controllers.accounts_controller.update_invoice_status",
@@ -579,6 +589,7 @@ accounting_dimension_doctypes = [
"Shipping Rule",
"Landed Cost Item",
"Asset Value Adjustment",
"Asset Repair",
"Loyalty Program",
"Fee Schedule",
"Fee Structure",

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

@@ -3,7 +3,15 @@
import frappe
from frappe.tests.utils import FrappeTestCase
from frappe.utils import add_days, get_year_ending, get_year_start, getdate, now_datetime, nowdate
from frappe.utils import (
add_days,
add_months,
get_last_day,
get_year_ending,
get_year_start,
getdate,
nowdate,
)
from erpnext.hr.doctype.attendance.attendance import (
get_month_map,
@@ -35,63 +43,64 @@ class TestAttendance(FrappeTestCase):
self.assertEqual(attendance, fetch_attendance)
def test_unmarked_days(self):
now = now_datetime()
previous_month = now.month - 1
first_day = now.replace(day=1).replace(month=previous_month).date()
first_sunday = get_first_sunday(
self.holiday_list, for_date=get_last_day(add_months(getdate(), -1))
)
attendance_date = add_days(first_sunday, 1)
employee = make_employee(
"test_unmarked_days@example.com", date_of_joining=add_days(first_day, -1)
"test_unmarked_days@example.com", date_of_joining=add_days(attendance_date, -1)
)
frappe.db.delete("Attendance", {"employee": employee})
frappe.db.set_value("Employee", employee, "holiday_list", self.holiday_list)
first_sunday = get_first_sunday(self.holiday_list, for_date=first_day)
mark_attendance(employee, first_day, "Present")
month_name = get_month_name(first_day)
mark_attendance(employee, attendance_date, "Present")
month_name = get_month_name(attendance_date)
unmarked_days = get_unmarked_days(employee, month_name)
unmarked_days = [getdate(date) for date in unmarked_days]
# attendance already marked for the day
self.assertNotIn(first_day, unmarked_days)
self.assertNotIn(attendance_date, unmarked_days)
# attendance unmarked
self.assertIn(getdate(add_days(first_day, 1)), unmarked_days)
self.assertIn(getdate(add_days(attendance_date, 1)), unmarked_days)
# holiday considered in unmarked days
self.assertIn(first_sunday, unmarked_days)
def test_unmarked_days_excluding_holidays(self):
now = now_datetime()
previous_month = now.month - 1
first_day = now.replace(day=1).replace(month=previous_month).date()
first_sunday = get_first_sunday(
self.holiday_list, for_date=get_last_day(add_months(getdate(), -1))
)
attendance_date = add_days(first_sunday, 1)
employee = make_employee(
"test_unmarked_days@example.com", date_of_joining=add_days(first_day, -1)
"test_unmarked_days@example.com", date_of_joining=add_days(attendance_date, -1)
)
frappe.db.delete("Attendance", {"employee": employee})
frappe.db.set_value("Employee", employee, "holiday_list", self.holiday_list)
first_sunday = get_first_sunday(self.holiday_list, for_date=first_day)
mark_attendance(employee, first_day, "Present")
month_name = get_month_name(first_day)
mark_attendance(employee, attendance_date, "Present")
month_name = get_month_name(attendance_date)
unmarked_days = get_unmarked_days(employee, month_name, exclude_holidays=True)
unmarked_days = [getdate(date) for date in unmarked_days]
# attendance already marked for the day
self.assertNotIn(first_day, unmarked_days)
self.assertNotIn(attendance_date, unmarked_days)
# attendance unmarked
self.assertIn(getdate(add_days(first_day, 1)), unmarked_days)
self.assertIn(getdate(add_days(attendance_date, 1)), unmarked_days)
# holidays not considered in unmarked days
self.assertNotIn(first_sunday, unmarked_days)
def test_unmarked_days_as_per_joining_and_relieving_dates(self):
now = now_datetime()
previous_month = now.month - 1
first_day = now.replace(day=1).replace(month=previous_month).date()
first_sunday = get_first_sunday(
self.holiday_list, for_date=get_last_day(add_months(getdate(), -1))
)
date = add_days(first_sunday, 1)
doj = add_days(first_day, 1)
relieving_date = add_days(first_day, 5)
doj = add_days(date, 1)
relieving_date = add_days(date, 5)
employee = make_employee(
"test_unmarked_days_as_per_doj@example.com", date_of_joining=doj, relieving_date=relieving_date
)
@@ -99,9 +108,9 @@ class TestAttendance(FrappeTestCase):
frappe.db.set_value("Employee", employee, "holiday_list", self.holiday_list)
attendance_date = add_days(first_day, 2)
attendance_date = add_days(date, 2)
mark_attendance(employee, attendance_date, "Present")
month_name = get_month_name(first_day)
month_name = get_month_name(attendance_date)
unmarked_days = get_unmarked_days(employee, month_name)
unmarked_days = [getdate(date) for date in unmarked_days]

View File

@@ -813,7 +813,7 @@
"idx": 24,
"image_field": "image",
"links": [],
"modified": "2021-06-17 11:31:37.730760",
"modified": "2022-07-18 20:03:43.188705",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee",

View File

@@ -10,7 +10,7 @@ from frappe.permissions import (
remove_user_permission,
set_user_permission_if_allowed,
)
from frappe.utils import add_years, cstr, getdate, today, validate_email_address
from frappe.utils import add_days, add_years, cstr, getdate, today, validate_email_address
from frappe.utils.nestedset import NestedSet
from erpnext.utilities.transaction_base import delete_events
@@ -64,6 +64,8 @@ class Employee(NestedSet):
if existing_user_id:
remove_user_permission("Employee", self.name, existing_user_id)
self.update_to_date_in_work_history()
def after_rename(self, old, new, merge):
self.db_set("employee", new)
@@ -166,6 +168,18 @@ class Employee(NestedSet):
user.flags.ignore_permissions = True
user.add_roles("Expense Approver")
def update_to_date_in_work_history(self):
if not self.internal_work_history:
return
for idx, row in enumerate(self.internal_work_history):
if not row.from_date or idx == 0:
continue
self.internal_work_history[idx - 1].to_date = add_days(row.from_date, -1)
self.internal_work_history[-1].to_date = None
def validate_date(self):
if self.date_of_birth and getdate(self.date_of_birth) > getdate(today()):
throw(_("Date of Birth cannot be greater than today."))
@@ -349,7 +363,9 @@ def get_employee_email(employee_doc):
def get_holiday_list_for_employee(employee, raise_exception=True):
if employee:
holiday_list, company = frappe.db.get_value("Employee", employee, ["holiday_list", "company"])
holiday_list, company = frappe.get_cached_value(
"Employee", employee, ["holiday_list", "company"]
)
else:
holiday_list = ""
company = frappe.db.get_value("Global Defaults", None, "default_company")

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