From 3c55463b4b86e9715e194d8c8268ee6190a5d30c Mon Sep 17 00:00:00 2001 From: pateljannat Date: Thu, 7 Jan 2021 12:41:44 +0530 Subject: [PATCH 01/14] fix: validation for ldc against supplier and section code --- .../lower_deduction_certificate.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py index e8a8ed87505..d4e7c123624 100644 --- a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py +++ b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py @@ -5,12 +5,16 @@ from __future__ import unicode_literals import frappe from frappe import _ -from frappe.utils import getdate +from frappe.utils import getdate, get_link_to_form from frappe.model.document import Document from erpnext.accounts.utils import get_fiscal_year class LowerDeductionCertificate(Document): def validate(self): + self.validate_dates() + self.validate_supplier_against_section_code() + + def validate_dates(self): if getdate(self.valid_upto) < getdate(self.valid_from): frappe.throw(_("Valid Upto date cannot be before Valid From date")) @@ -24,3 +28,10 @@ class LowerDeductionCertificate(Document): <= fiscal_year.year_end_date): frappe.throw(_("Valid Upto date not in Fiscal Year {0}").format(frappe.bold(self.fiscal_year))) + def validate_supplier_against_section_code(self): + duplicate_certificate = frappe.db.get_value('Lower Deduction Certificate', {'supplier': self.supplier, 'section_code': self.section_code}, ['name']) + if duplicate_certificate: + certificate_link = get_link_to_form('Lower Deduction Certificate', duplicate_certificate) + frappe.throw(_("There is already a Lower Deduction Certificate {0} for Supplier {1} against Section Code {2}") + .format(certificate_link, frappe.bold(self.supplier), frappe.bold(self.section_code))) + From f1107598976d5584beaa3011654e78159b09b618 Mon Sep 17 00:00:00 2001 From: pateljannat Date: Wed, 20 Jan 2021 18:12:48 +0530 Subject: [PATCH 02/14] fix: date validation --- .../lower_deduction_certificate.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py index d4e7c123624..b0a656af306 100644 --- a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py +++ b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py @@ -29,9 +29,19 @@ class LowerDeductionCertificate(Document): frappe.throw(_("Valid Upto date not in Fiscal Year {0}").format(frappe.bold(self.fiscal_year))) def validate_supplier_against_section_code(self): - duplicate_certificate = frappe.db.get_value('Lower Deduction Certificate', {'supplier': self.supplier, 'section_code': self.section_code}, ['name']) - if duplicate_certificate: - certificate_link = get_link_to_form('Lower Deduction Certificate', duplicate_certificate) - frappe.throw(_("There is already a Lower Deduction Certificate {0} for Supplier {1} against Section Code {2}") + duplicate_certificate = frappe.db.get_value('Lower Deduction Certificate', {'supplier': self.supplier, 'section_code': self.section_code}, ['name', 'valid_from', 'valid_upto'], as_dict=True) + if duplicate_certificate and self.are_dates_overlapping(duplicate_certificate): + certificate_link = get_link_to_form('Lower Deduction Certificate', duplicate_certificate.name) + frappe.throw(_("There is already a valid Lower Deduction Certificate {0} for Supplier {1} against Section Code {2} for this time period.") .format(certificate_link, frappe.bold(self.supplier), frappe.bold(self.section_code))) + def are_dates_overlapping(self,duplicate_certificate): + valid_from = duplicate_certificate.valid_from + valid_upto = duplicate_certificate.valid_upto + if valid_from <= getdate(self.valid_from) and getdate(self.valid_from) <= valid_upto: + return True + elif valid_from <= getdate(self.valid_upto) and getdate(self.valid_upto) <= valid_upto: + return True + elif getdate(self.valid_from) <= valid_from and valid_upto <= getdate(self.valid_upto): + return True + return False \ No newline at end of file From 1ab95413beacf98f7f7627ee2f8b6a3a2b0930ce Mon Sep 17 00:00:00 2001 From: pateljannat Date: Tue, 9 Feb 2021 17:35:17 +0530 Subject: [PATCH 03/14] fix: conditions simplified --- .../lower_deduction_certificate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py index b0a656af306..ad60db05595 100644 --- a/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py +++ b/erpnext/regional/doctype/lower_deduction_certificate/lower_deduction_certificate.py @@ -38,9 +38,9 @@ class LowerDeductionCertificate(Document): def are_dates_overlapping(self,duplicate_certificate): valid_from = duplicate_certificate.valid_from valid_upto = duplicate_certificate.valid_upto - if valid_from <= getdate(self.valid_from) and getdate(self.valid_from) <= valid_upto: + if valid_from <= getdate(self.valid_from) <= valid_upto: return True - elif valid_from <= getdate(self.valid_upto) and getdate(self.valid_upto) <= valid_upto: + elif valid_from <= getdate(self.valid_upto) <= valid_upto: return True elif getdate(self.valid_from) <= valid_from and valid_upto <= getdate(self.valid_upto): return True From ad1f2b41f47bc0016d4abe7915f0f88af6cbc197 Mon Sep 17 00:00:00 2001 From: Rucha Mahabal Date: Fri, 12 Feb 2021 11:29:24 +0530 Subject: [PATCH 04/14] fix: Issues with packing items --- erpnext/public/js/utils/serial_no_batch_selector.js | 9 ++++++--- erpnext/selling/doctype/sales_order/sales_order.js | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/erpnext/public/js/utils/serial_no_batch_selector.js b/erpnext/public/js/utils/serial_no_batch_selector.js index 2623c3c1a73..d49a8138fb5 100644 --- a/erpnext/public/js/utils/serial_no_batch_selector.js +++ b/erpnext/public/js/utils/serial_no_batch_selector.js @@ -140,6 +140,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ () => me.update_batch_serial_no_items(), () => { refresh_field("items"); + refresh_field("packed_items"); if (me.callback) { return me.callback(me.item); } @@ -154,7 +155,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ if (this.item.serial_no) { this.dialog.fields_dict.serial_no.set_value(this.item.serial_no); } - + if (this.has_batch && !this.has_serial_no && d.batch_no) { this.frm.doc.items.forEach(data => { if(data.item_code == d.item_code) { @@ -231,7 +232,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ this.map_row_values(row, batch, 'batch_no', 'selected_qty', this.values.warehouse); }); - } + } }, update_serial_no_item() { @@ -250,7 +251,7 @@ erpnext.SerialNoBatchSelector = Class.extend({ filters: { 'name': ["in", selected_serial_nos]}, fields: ["batch_no", "name"] }).then((data) => { - // data = [{batch_no: 'batch-1', name: "SR-001"}, + // data = [{batch_no: 'batch-1', name: "SR-001"}, // {batch_no: 'batch-2', name: "SR-003"}, {batch_no: 'batch-2', name: "SR-004"}] const batch_serial_map = data.reduce((acc, d) => { if (!acc[d['batch_no']]) acc[d['batch_no']] = []; @@ -298,6 +299,8 @@ erpnext.SerialNoBatchSelector = Class.extend({ } else { row.warehouse = values.warehouse || warehouse; } + + this.frm.dirty(); }, update_total_qty: function() { diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js index e4923773859..e3b41e66fbc 100644 --- a/erpnext/selling/doctype/sales_order/sales_order.js +++ b/erpnext/selling/doctype/sales_order/sales_order.js @@ -514,7 +514,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend( make_delivery_note: function() { frappe.model.open_mapped_doc({ method: "erpnext.selling.doctype.sales_order.sales_order.make_delivery_note", - frm: me.frm + frm: this.frm }) }, From fd4e7bdbb11793bf9b809edd2097c9386a0ec8d1 Mon Sep 17 00:00:00 2001 From: Richard Case <64409021+casesolved-co-uk@users.noreply.github.com> Date: Mon, 15 Feb 2021 06:28:27 +0000 Subject: [PATCH 05/14] fix: plaid client version to support latest API (#24531) --- .../doctype/plaid_settings/plaid_connector.py | 4 ++-- requirements.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py index 66d0e5f77db..5f990cdd034 100644 --- a/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py +++ b/erpnext/erpnext_integrations/doctype/plaid_settings/plaid_connector.py @@ -20,7 +20,7 @@ class PlaidConnector(): client_id=self.settings.plaid_client_id, secret=self.settings.get_password("plaid_secret"), environment=self.settings.plaid_env, - api_version="2019-05-29" + api_version="2020-09-14" ) def get_access_token(self, public_token): @@ -29,7 +29,7 @@ class PlaidConnector(): response = self.client.Item.public_token.exchange(public_token) access_token = response["access_token"] return access_token - + def get_token_request(self, update_mode=False): country_codes = ["US", "CA", "FR", "IE", "NL", "ES", "GB"] if self.settings.enable_european_access else ["US", "CA"] args = { diff --git a/requirements.txt b/requirements.txt index 4511aa54d8d..5a352364b6e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ frappe gocardless-pro==1.11.0 googlemaps==3.1.1 pandas>=1.0.5 -plaid-python==6.0.0 +plaid-python>=7.0.0 pycountry==19.8.18 PyGithub==1.44.1 python-stdnum==1.12 @@ -12,4 +12,4 @@ taxjar==1.9.0 tweepy==3.8.0 Unidecode==1.1.1 WooCommerce==2.1.1 -pycryptodome==3.9.8 \ No newline at end of file +pycryptodome==3.9.8 From 57c3d373a7197ce8da94c9337a63cebf5002845a Mon Sep 17 00:00:00 2001 From: Ankush Menat Date: Mon, 15 Feb 2021 14:16:00 +0530 Subject: [PATCH 06/14] fix(India): Add GST state code for Ladakh --- erpnext/patches.txt | 1 + .../patches/v12_0/add_state_code_for_ladakh.py | 16 ++++++++++++++++ erpnext/regional/india/__init__.py | 4 +++- erpnext/regional/india/gst_state_code_data.json | 5 +++++ 4 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 erpnext/patches/v12_0/add_state_code_for_ladakh.py diff --git a/erpnext/patches.txt b/erpnext/patches.txt index 3b7c6ab48eb..e1f7250dec9 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -752,3 +752,4 @@ erpnext.patches.v13_0.set_company_in_leave_ledger_entry erpnext.patches.v13_0.convert_qi_parameter_to_link_field erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021 +erpnext.patches.v12_0.add_state_code_for_ladakh diff --git a/erpnext/patches/v12_0/add_state_code_for_ladakh.py b/erpnext/patches/v12_0/add_state_code_for_ladakh.py new file mode 100644 index 00000000000..d41101cc46a --- /dev/null +++ b/erpnext/patches/v12_0/add_state_code_for_ladakh.py @@ -0,0 +1,16 @@ +import frappe +from erpnext.regional.india import states + +def execute(): + + company = frappe.get_all('Company', filters = {'country': 'India'}) + if not company: + return + + custom_fields = ['Address-gst_state', 'Tax Category-gst_state'] + + # Update options in gst_state custom fields + for field in custom_fields: + gst_state_field = frappe.get_doc('Custom Field', field) + gst_state_field.options = '\n'.join(states) + gst_state_field.save() diff --git a/erpnext/regional/india/__init__.py b/erpnext/regional/india/__init__.py index d6221a80aa2..378b735e078 100644 --- a/erpnext/regional/india/__init__.py +++ b/erpnext/regional/india/__init__.py @@ -20,6 +20,7 @@ states = [ 'Jharkhand', 'Karnataka', 'Kerala', + 'Ladakh', 'Lakshadweep Islands', 'Madhya Pradesh', 'Maharashtra', @@ -59,6 +60,7 @@ state_numbers = { "Jharkhand": "20", "Karnataka": "29", "Kerala": "32", + "Ladakh": "38", "Lakshadweep Islands": "31", "Madhya Pradesh": "23", "Maharashtra": "27", @@ -80,4 +82,4 @@ state_numbers = { "West Bengal": "19", } -number_state_mapping = {v: k for k, v in iteritems(state_numbers)} \ No newline at end of file +number_state_mapping = {v: k for k, v in iteritems(state_numbers)} diff --git a/erpnext/regional/india/gst_state_code_data.json b/erpnext/regional/india/gst_state_code_data.json index ff88e0f9d6c..8481c279728 100644 --- a/erpnext/regional/india/gst_state_code_data.json +++ b/erpnext/regional/india/gst_state_code_data.json @@ -168,5 +168,10 @@ "state_number": "37", "state_code": "AD", "state_name": "Andhra Pradesh (New)" + }, + { + "state_number": "38", + "state_code": "LA", + "state_name": "Ladakh" } ] From b0735732f960cd3235416568c9227938c9c5388e Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Mon, 15 Feb 2021 17:38:40 +0530 Subject: [PATCH 07/14] fix(minor): add erpnext-logo.png --- erpnext/public/images/erpnext-log.png | Bin 0 -> 2360 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 erpnext/public/images/erpnext-log.png diff --git a/erpnext/public/images/erpnext-log.png b/erpnext/public/images/erpnext-log.png new file mode 100644 index 0000000000000000000000000000000000000000..3090727d8ff5f95e49d25278b24b10bf13747f4a GIT binary patch literal 2360 zcmeAS@N?(olHy`uVBq!ia0y~yU;;9k7&zE~)R&4Yzkn2Hfk$L90|U1(2s1Lwnj--e zWGoJHcVbv~PUa<$!;&U>cv7h@-A}a#}$5~Go$B+ufw>K9Sh9*k5UVLwOJ(!Va zX^Y;A2EGdl@_l>`i7y#^RP^{9(=r-dj@~ty==pE<-Z0VXbCzc-@3S*_R2nik^f53r zC@?ZGI09YN!~(R06KJv!1A~AH1A~GG1B1haQ3b;&94?q`*kP{E&iDFPT7oB2!_&XD z_5~5k&og@$F%HG3-qv`ucCQqJ+>Ok0zwHd6fknm8%iOovDvb93JGL=j-W!Kx!3@l;vG@68ZvEfg_;k**J@1(rmh2d Date: Mon, 15 Feb 2021 17:40:50 +0530 Subject: [PATCH 08/14] fix(typo): erpnext-logo.png --- .../images/{erpnext-log.png => erpnext-logo.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename erpnext/public/images/{erpnext-log.png => erpnext-logo.png} (100%) diff --git a/erpnext/public/images/erpnext-log.png b/erpnext/public/images/erpnext-logo.png similarity index 100% rename from erpnext/public/images/erpnext-log.png rename to erpnext/public/images/erpnext-logo.png From 243661b37b1a79763e71d46aaa80148bbd6578a0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Mon, 15 Feb 2021 19:27:49 +0530 Subject: [PATCH 09/14] fix: formatting query args (#24627) --- erpnext/stock/stock_ledger.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 95f8c438b34..8c9c172ebd1 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -194,6 +194,8 @@ class update_entries_after(object): self.process_sle(sle) def get_sle_against_current_voucher(self): + self.args['time_format'] = '%H:%i:%s' + return frappe.db.sql(""" select *, timestamp(posting_date, posting_time) as "timestamp" @@ -202,7 +204,7 @@ class update_entries_after(object): where item_code = %(item_code)s and warehouse = %(warehouse)s - and timestamp(posting_date, time_format(posting_time, '%H:%i:%s')) = timestamp(%(posting_date)s, time_format(%(posting_time)s, '%H:%i:%s')) + and timestamp(posting_date, time_format(posting_time, %(time_format)s)) = timestamp(%(posting_date)s, time_format(%(posting_time)s, %(time_format)s)) order by creation ASC for update From d60ff83b6fc42cddea27c85099a322764dd8b115 Mon Sep 17 00:00:00 2001 From: rohitwaghchaure Date: Tue, 16 Feb 2021 09:12:27 +0530 Subject: [PATCH 10/14] fix: added patch to fix incorrect stock qty and account value (#24628) --- erpnext/accounts/utils.py | 13 ++++++--- erpnext/patches.txt | 1 + .../item_reposting_for_incorrect_sl_and_gl.py | 27 +++++++++++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) create mode 100644 erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 67c7fd2d22a..80319056dda 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -82,7 +82,7 @@ def get_fiscal_years(transaction_date=None, fiscal_year=None, label="Date", verb error_msg = _("""{0} {1} is not in any active Fiscal Year""").format(label, formatdate(transaction_date)) if company: error_msg = _("""{0} for {1}""").format(error_msg, frappe.bold(company)) - + if verbose==1: frappe.msgprint(error_msg) raise FiscalYearError(error_msg) @@ -895,7 +895,8 @@ def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for if not warehouse_account: warehouse_account = get_warehouse_account_map(company) - future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items) + future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, + for_warehouses, for_items, company) gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date) for voucher_type, voucher_no in future_stock_vouchers: @@ -909,7 +910,7 @@ def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for else: _delete_gl_entries(voucher_type, voucher_no) -def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, for_items=None): +def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, for_items=None, company=None): future_stock_vouchers = [] values = [] @@ -922,6 +923,10 @@ def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, f condition += " and warehouse in ({})".format(", ".join(["%s"] * len(for_warehouses))) values += for_warehouses + if company: + condition += " and company = %s " + values.append(company) + for d in frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no from `tabStock Ledger Entry` sle where @@ -982,7 +987,7 @@ def check_if_stock_and_account_balance_synced(posting_date, company, voucher_typ error_reason = _("Stock Value ({0}) and Account Balance ({1}) are out of sync for account {2} and it's linked warehouses as on {3}.").format( stock_bal, account_bal, frappe.bold(account), posting_date) error_resolution = _("Please create an adjustment Journal Entry for amount {0} on {1}")\ - .format(frappe.bold(diff), frappe.bold(posting_date)) + .format(frappe.bold(diff), frappe.bold(posting_date)) frappe.msgprint( msg="""{0}

{1}

""".format(error_reason, error_resolution), diff --git a/erpnext/patches.txt b/erpnext/patches.txt index e1f7250dec9..e5ee551c118 100644 --- a/erpnext/patches.txt +++ b/erpnext/patches.txt @@ -753,3 +753,4 @@ erpnext.patches.v13_0.convert_qi_parameter_to_link_field erpnext.patches.v13_0.setup_patient_history_settings_for_standard_doctypes erpnext.patches.v13_0.add_naming_series_to_old_projects # 1-02-2021 erpnext.patches.v12_0.add_state_code_for_ladakh +erpnext.patches.v13_0.item_reposting_for_incorrect_sl_and_gl diff --git a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py new file mode 100644 index 00000000000..7c4835a8132 --- /dev/null +++ b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py @@ -0,0 +1,27 @@ +import frappe +from frappe import _ +from erpnext.stock.stock_ledger import update_entries_after +from erpnext.accounts.utils import update_gl_entries_after + + +data = frappe.db.sql(''' SELECT name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time + from `tabStock Ledger Entry` where creation > '2020-12-26 12:58:55.903836' and is_cancelled = 0 + order by timestamp(posting_date, posting_time) asc, creation asc''', as_dict=1) + +for index, d in enumerate(data): + update_entries_after({ + "item_code": d.item_code, + "warehouse": d.warehouse, + "posting_date": d.posting_date, + "posting_time": d.posting_time, + "voucher_type": d.voucher_type, + "voucher_no": d.voucher_no, + "sle_id": d.name + }, allow_negative_stock=True) + +frappe.db.auto_commit_on_many_writes = 1 + +for row in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}): + update_gl_entries_after('2020-12-25', '01:58:55', company=row.name) + +frappe.db.auto_commit_on_many_writes = 0 \ No newline at end of file From 9a40c1b2e1af132b860452c54aa74f83adc24357 Mon Sep 17 00:00:00 2001 From: Rohit Waghchaure Date: Tue, 16 Feb 2021 10:35:10 +0530 Subject: [PATCH 11/14] fix: patch --- .../item_reposting_for_incorrect_sl_and_gl.py | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py index 7c4835a8132..eff0ae4694c 100644 --- a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py +++ b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py @@ -4,24 +4,25 @@ from erpnext.stock.stock_ledger import update_entries_after from erpnext.accounts.utils import update_gl_entries_after -data = frappe.db.sql(''' SELECT name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time - from `tabStock Ledger Entry` where creation > '2020-12-26 12:58:55.903836' and is_cancelled = 0 - order by timestamp(posting_date, posting_time) asc, creation asc''', as_dict=1) +def execute(): + data = frappe.db.sql(''' SELECT name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time + from `tabStock Ledger Entry` where creation > '2020-12-26 12:58:55.903836' and is_cancelled = 0 + order by timestamp(posting_date, posting_time) asc, creation asc''', as_dict=1) -for index, d in enumerate(data): - update_entries_after({ - "item_code": d.item_code, - "warehouse": d.warehouse, - "posting_date": d.posting_date, - "posting_time": d.posting_time, - "voucher_type": d.voucher_type, - "voucher_no": d.voucher_no, - "sle_id": d.name - }, allow_negative_stock=True) + for index, d in enumerate(data): + update_entries_after({ + "item_code": d.item_code, + "warehouse": d.warehouse, + "posting_date": d.posting_date, + "posting_time": d.posting_time, + "voucher_type": d.voucher_type, + "voucher_no": d.voucher_no, + "sle_id": d.name + }, allow_negative_stock=True) -frappe.db.auto_commit_on_many_writes = 1 + frappe.db.auto_commit_on_many_writes = 1 -for row in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}): - update_gl_entries_after('2020-12-25', '01:58:55', company=row.name) + for row in frappe.get_all('Company', filters= {'enable_perpetual_inventory': 1}): + update_gl_entries_after('2020-12-25', '01:58:55', company=row.name) -frappe.db.auto_commit_on_many_writes = 0 \ No newline at end of file + frappe.db.auto_commit_on_many_writes = 0 \ No newline at end of file From 7e8113c7e8b77f62d9af334abe3a2a8c683dbe59 Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 16 Feb 2021 11:59:12 +0530 Subject: [PATCH 12/14] fix: broken image style --- erpnext/public/less/hub.less | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less index 8cb7a9c1ce5..c08121f7043 100644 --- a/erpnext/public/less/hub.less +++ b/erpnext/public/less/hub.less @@ -32,7 +32,13 @@ body[data-route*="marketplace"] { } .hub-image-loading, .hub-image-broken { - .img-background(); + content: " "; + display: block; + position: absolute; + left: 0; + height: 100%; + width: 100%; + background-color: var(--bg-light-gray); display: flex; align-items: center; justify-content: center; From 9b178bcd10689cfea8d7ad0a850a09e6f03630e0 Mon Sep 17 00:00:00 2001 From: Nabin Hait Date: Tue, 16 Feb 2021 14:57:00 +0530 Subject: [PATCH 13/14] fix: stock and account balance syncing (#24644) * fix: stock and account balance syncing * fix: stock and account balance syncing * fix: stock and account balance syncing * fix: minor fix --- erpnext/accounts/utils.py | 14 +++++++++----- erpnext/controllers/stock_controller.py | 3 +-- .../clinical_procedure/clinical_procedure.py | 1 + .../clinical_procedure/test_clinical_procedure.py | 5 +++-- .../item_reposting_for_incorrect_sl_and_gl.py | 1 - erpnext/stock/__init__.py | 2 +- erpnext/stock/doctype/batch/test_batch.py | 6 +++--- .../test_landed_cost_voucher.py | 5 ++++- .../repost_item_valuation/repost_item_valuation.py | 2 +- erpnext/stock/doctype/shipment/test_shipment.py | 1 + erpnext/stock/stock_ledger.py | 3 ++- 11 files changed, 26 insertions(+), 17 deletions(-) diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py index 80319056dda..60d1e20feaf 100644 --- a/erpnext/accounts/utils.py +++ b/erpnext/accounts/utils.py @@ -888,18 +888,22 @@ def get_coa(doctype, parent, is_root, chart=None): def update_gl_entries_after(posting_date, posting_time, for_warehouses=None, for_items=None, warehouse_account=None, company=None): + stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, for_warehouses, for_items, company) + repost_gle_for_stock_vouchers(stock_vouchers, posting_date, company, warehouse_account) + + +def repost_gle_for_stock_vouchers(stock_vouchers, posting_date, company=None, warehouse_account=None): 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)) + if not warehouse_account: warehouse_account = get_warehouse_account_map(company) - future_stock_vouchers = get_future_stock_vouchers(posting_date, posting_time, - for_warehouses, for_items, company) - gle = get_voucherwise_gl_entries(future_stock_vouchers, posting_date) + gle = get_voucherwise_gl_entries(stock_vouchers, posting_date) - for voucher_type, voucher_no in future_stock_vouchers: + for voucher_type, voucher_no in stock_vouchers: 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) @@ -924,7 +928,7 @@ def get_future_stock_vouchers(posting_date, posting_time, for_warehouses=None, f values += for_warehouses if company: - condition += " and company = %s " + condition += " and company = %s" values.append(company) for d in frappe.db.sql("""select distinct sle.voucher_type, sle.voucher_no diff --git a/erpnext/controllers/stock_controller.py b/erpnext/controllers/stock_controller.py index 70e8d8cc785..ea9659ce017 100644 --- a/erpnext/controllers/stock_controller.py +++ b/erpnext/controllers/stock_controller.py @@ -488,13 +488,12 @@ class StockController(AccountsController): "voucher_no": self.name, "company": self.company }) - if check_if_future_sle_exists(args): create_repost_item_valuation_entry(args) elif not is_reposting_pending(): check_if_stock_and_account_balance_synced(self.posting_date, self.company, self.doctype, self.name) - + def is_reposting_pending(): return frappe.db.exists("Repost Item Valuation", {'docstatus': 1, 'status': ['in', ['Queued','In Progress']]}) diff --git a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py index c3242284674..325c2094fbf 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py +++ b/erpnext/healthcare/doctype/clinical_procedure/clinical_procedure.py @@ -121,6 +121,7 @@ class ClinicalProcedure(Document): stock_entry.stock_entry_type = 'Material Receipt' stock_entry.to_warehouse = self.warehouse + stock_entry.company = self.company expense_account = get_account(None, 'expense_account', 'Healthcare Settings', self.company) for item in self.items: if item.qty > item.actual_qty: diff --git a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py index 4ee5f6bad39..fb72073a07f 100644 --- a/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py +++ b/erpnext/healthcare/doctype/clinical_procedure/test_clinical_procedure.py @@ -1,4 +1,4 @@ -# -*- coding: utf-8 -*- + # -*- coding: utf-8 -*- # Copyright (c) 2017, ESS LLP and Contributors # See license.txt from __future__ import unicode_literals @@ -60,6 +60,7 @@ def create_procedure(procedure_template, patient, practitioner): procedure.practitioner = practitioner procedure.consume_stock = procedure_template.allow_stock_consumption procedure.items = procedure_template.items - procedure.warehouse = frappe.db.get_single_value('Stock Settings', 'default_warehouse') + procedure.company = "_Test Company" + procedure.warehouse = "_Test Warehouse - _TC" procedure.submit() return procedure \ No newline at end of file diff --git a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py index eff0ae4694c..f60e0d3036c 100644 --- a/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py +++ b/erpnext/patches/v13_0/item_reposting_for_incorrect_sl_and_gl.py @@ -3,7 +3,6 @@ from frappe import _ from erpnext.stock.stock_ledger import update_entries_after from erpnext.accounts.utils import update_gl_entries_after - def execute(): data = frappe.db.sql(''' SELECT name, item_code, warehouse, voucher_type, voucher_no, posting_date, posting_time from `tabStock Ledger Entry` where creation > '2020-12-26 12:58:55.903836' and is_cancelled = 0 diff --git a/erpnext/stock/__init__.py b/erpnext/stock/__init__.py index 8d64efe41dd..b3ae804b1c2 100644 --- a/erpnext/stock/__init__.py +++ b/erpnext/stock/__init__.py @@ -64,7 +64,7 @@ def get_warehouse_account(warehouse, warehouse_account=None): if not account and warehouse.company: account = get_company_default_inventory_account(warehouse.company) - if not account and warehouse.company: + if not account and warehouse.company and not warehouse.is_group: frappe.throw(_("Please set Account in Warehouse {0} or Default Inventory Account in Company {1}") .format(warehouse.name, warehouse.company)) return account diff --git a/erpnext/stock/doctype/batch/test_batch.py b/erpnext/stock/doctype/batch/test_batch.py index 97f85bafd95..cbd272df4b8 100644 --- a/erpnext/stock/doctype/batch/test_batch.py +++ b/erpnext/stock/doctype/batch/test_batch.py @@ -298,9 +298,9 @@ class TestBatch(unittest.TestCase): self.assertEqual(details.get('price_list_rate'), 400) def create_batch(item_code, rate, create_item_price_for_batch): - pi = make_purchase_invoice(company="_Test Company with perpetual inventory", - warehouse= "Stores - TCP1", cost_center = "Main - TCP1", update_stock=1, - expense_account ="_Test Account Cost for Goods Sold - TCP1", item_code=item_code) + pi = make_purchase_invoice(company="_Test Company", + warehouse= "Stores - _TC", cost_center = "Main - _TC", update_stock=1, + expense_account ="_Test Account Cost for Goods Sold - _TC", item_code=item_code) batch = frappe.db.get_value('Batch', {'item': item_code, 'reference_name': pi.name}) diff --git a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py index 144101c67d7..984ae46c66c 100644 --- a/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py +++ b/erpnext/stock/doctype/landed_cost_voucher/test_landed_cost_voucher.py @@ -148,7 +148,6 @@ class TestLandedCostVoucher(unittest.TestCase): def test_landed_cost_voucher_for_odd_numbers (self): - pr = make_purchase_receipt(company="_Test Company with perpetual inventory", warehouse = "Stores - TCP1", supplier_warehouse = "Work in Progress - TCP1", do_not_save=True) pr.items[0].cost_center = "Main - TCP1" for x in range(2): @@ -208,6 +207,10 @@ class TestLandedCostVoucher(unittest.TestCase): self.assertEqual(pr.items[1].landed_cost_voucher_amount, 100) def test_multi_currency_lcv(self): + from erpnext.setup.doctype.currency_exchange.test_currency_exchange import test_records, save_new_records + + save_new_records(test_records) + ## Create USD Shipping charges_account usd_shipping = create_account(account_name="Shipping Charges USD", parent_account="Duties and Taxes - TCP1", company="_Test Company with perpetual inventory", diff --git a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py index ba2c2c6f446..f22c6018d41 100644 --- a/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py +++ b/erpnext/stock/doctype/repost_item_valuation/repost_item_valuation.py @@ -64,7 +64,7 @@ def repost(doc): message += "
" + "Traceback:
" + traceback frappe.db.set_value(doc.doctype, doc.name, 'error_log', message) - notify_error_to_stock_managers(doc) + notify_error_to_stock_managers(doc, message) doc.set_status('Failed') raise finally: diff --git a/erpnext/stock/doctype/shipment/test_shipment.py b/erpnext/stock/doctype/shipment/test_shipment.py index e1fa207a216..9c3e22f0231 100644 --- a/erpnext/stock/doctype/shipment/test_shipment.py +++ b/erpnext/stock/doctype/shipment/test_shipment.py @@ -190,6 +190,7 @@ def create_shipment_company(company_name, abbr): company.abbr = abbr company.default_currency = 'EUR' company.country = 'Germany' + company.enable_perpetual_inventory = 0 company.insert() return company diff --git a/erpnext/stock/stock_ledger.py b/erpnext/stock/stock_ledger.py index 8c9c172ebd1..21860b6863f 100644 --- a/erpnext/stock/stock_ledger.py +++ b/erpnext/stock/stock_ledger.py @@ -204,7 +204,8 @@ class update_entries_after(object): where item_code = %(item_code)s and warehouse = %(warehouse)s - and timestamp(posting_date, time_format(posting_time, %(time_format)s)) = timestamp(%(posting_date)s, time_format(%(posting_time)s, %(time_format)s)) + and voucher_type = %(voucher_type)s + and voucher_no = %(voucher_no)s order by creation ASC for update From 7166b6740ff9541d66f0e1abd59e16aa340556c7 Mon Sep 17 00:00:00 2001 From: prssanna Date: Tue, 16 Feb 2021 16:17:17 +0530 Subject: [PATCH 14/14] fix: duplicate css property --- erpnext/public/less/hub.less | 1 - 1 file changed, 1 deletion(-) diff --git a/erpnext/public/less/hub.less b/erpnext/public/less/hub.less index c08121f7043..29deada8a41 100644 --- a/erpnext/public/less/hub.less +++ b/erpnext/public/less/hub.less @@ -33,7 +33,6 @@ body[data-route*="marketplace"] { .hub-image-loading, .hub-image-broken { content: " "; - display: block; position: absolute; left: 0; height: 100%;