diff --git a/erpnext/__init__.py b/erpnext/__init__.py index 1d30f866bdf..7c3bf4955c3 100644 --- a/erpnext/__init__.py +++ b/erpnext/__init__.py @@ -5,7 +5,7 @@ import frappe from erpnext.hooks import regional_overrides from frappe.utils import getdate -__version__ = '11.1.36' +__version__ = '11.1.37' def get_default_company(user=None): '''Get default company for user''' diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py index 92342f4d7c8..214cdabe3a7 100644 --- a/erpnext/accounts/doctype/journal_entry/journal_entry.py +++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py @@ -425,8 +425,9 @@ class JournalEntry(AccountsController): pay_to_recd_from = frappe.db.get_value(d.party_type, d.party, "customer_name" if d.party_type=="Customer" else "supplier_name") - party_amount += (d.debit_in_account_currency or d.credit_in_account_currency) - party_account_currency = d.account_currency + if pay_to_recd_from and pay_to_recd_from == d.party: + party_amount += (d.debit_in_account_currency or d.credit_in_account_currency) + party_account_currency = d.account_currency elif frappe.db.get_value("Account", d.account, "account_type") in ["Bank", "Cash"]: bank_amount += (d.debit_in_account_currency or d.credit_in_account_currency) diff --git a/erpnext/accounts/doctype/sales_invoice/regional/india.js b/erpnext/accounts/doctype/sales_invoice/regional/india.js index 5fec3ba6d32..c8305e325f6 100644 --- a/erpnext/accounts/doctype/sales_invoice/regional/india.js +++ b/erpnext/accounts/doctype/sales_invoice/regional/india.js @@ -21,7 +21,7 @@ frappe.ui.form.on("Sales Invoice", { if(frm.doc.docstatus == 1 && !frm.is_dirty() && !frm.doc.is_return && !frm.doc.ewaybill) { - frm.add_custom_button('Generate e-Way Bill JSON', () => { + frm.add_custom_button('e-Way Bill JSON', () => { var w = window.open( frappe.urllib.get_full_url( "/api/method/erpnext.regional.india.utils.generate_ewb_json?" diff --git a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html index d7aa0c0d191..192b6d7be38 100644 --- a/erpnext/accounts/report/accounts_receivable/accounts_receivable.html +++ b/erpnext/accounts/report/accounts_receivable/accounts_receivable.html @@ -46,6 +46,8 @@ var range2 = report.columns[12].label; var range3 = report.columns[13].label; var range4 = report.columns[14].label; + var range5 = report.columns[15].label; + var range6 = report.columns[16].label; %} {% if(balance_row) { %} @@ -56,8 +58,10 @@ - - + + + + @@ -67,16 +71,20 @@ + + - + + + @@ -86,6 +94,8 @@ + + @@ -95,6 +105,8 @@ + + diff --git a/erpnext/accounts/report/financial_statements.html b/erpnext/accounts/report/financial_statements.html index 449fb845d74..cb853fd1dc4 100644 --- a/erpnext/accounts/report/financial_statements.html +++ b/erpnext/accounts/report/financial_statements.html @@ -39,7 +39,7 @@ - {% for(var j=0, k=data.length; j - {% for(var i=0, l=data.length; i {% if(data[i].posting_date) { %} diff --git a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py index e8b19b40249..5d3253a552d 100644 --- a/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py +++ b/erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.py @@ -102,7 +102,9 @@ def get_conditions(filters): ("customer", " and `tabSales Invoice`.customer = %(customer)s"), ("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"), ("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"), - ("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")): + ("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s"), + ("company_gstin", " and `tabSales Invoice`.company_gstin = %(company_gstin)s"), + ("invoice_type", " and `tabSales Invoice`.invoice_type = %(invoice_type)s")): if filters.get(opts[0]): conditions += opts[1] diff --git a/erpnext/healthcare/doctype/lab_test/lab_test.py b/erpnext/healthcare/doctype/lab_test/lab_test.py index b0bd4c6a680..86094896154 100644 --- a/erpnext/healthcare/doctype/lab_test/lab_test.py +++ b/erpnext/healthcare/doctype/lab_test/lab_test.py @@ -300,11 +300,15 @@ def insert_lab_test_to_medical_record(doc): elif doc.special_test_items: item = doc.special_test_items[0] - table_row = item.lab_test_particulars +" "+ item.result_value + + if item.lab_test_particulars and item.result_value: + table_row = item.lab_test_particulars +" "+ item.result_value elif doc.sensitivity_test_items: item = doc.sensitivity_test_items[0] - table_row = item.antibiotic +" "+ item.antibiotic_sensitivity + + if item.antibiotic and item.antibiotic_sensitivity: + table_row = item.antibiotic +" "+ item.antibiotic_sensitivity if table_row: subject += "
"+table_row diff --git a/erpnext/hooks.py b/erpnext/hooks.py index fb24aa93892..9b18e5e1f3a 100644 --- a/erpnext/hooks.py +++ b/erpnext/hooks.py @@ -13,8 +13,6 @@ source_link = "https://github.com/frappe/erpnext" develop_version = '12.x.x-develop' -error_report_email = "support@erpnext.com" - app_include_js = "assets/js/erpnext.min.js" app_include_css = "assets/css/erpnext.css" web_include_js = "assets/js/erpnext-web.min.js" diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py index dd4c77d1452..ffd786836a5 100644 --- a/erpnext/hr/doctype/salary_slip/salary_slip.py +++ b/erpnext/hr/doctype/salary_slip/salary_slip.py @@ -443,7 +443,7 @@ class SalarySlip(TransactionBase): else: component_row.additional_amount = amount - if not overwrite: + if not overwrite and component_row.default_amount: amount += component_row.default_amount component_row.amount = amount diff --git a/erpnext/patches/v11_0/update_total_qty_field.py b/erpnext/patches/v11_0/update_total_qty_field.py index 992454ac7c1..51358e95458 100644 --- a/erpnext/patches/v11_0/update_total_qty_field.py +++ b/erpnext/patches/v11_0/update_total_qty_field.py @@ -40,7 +40,7 @@ def execute(): # This is probably never used anywhere else as of now, but should be values = [] for d in batch_transactions: - values.append("('{}', {})".format(d.parent, d.qty)) + values.append("('{}', {})".format(frappe.db.escape(d.parent), d.qty)) conditions = ",".join(values) frappe.db.sql(""" INSERT INTO `tab{}` (name, total_qty) VALUES {} diff --git a/erpnext/regional/india/utils.py b/erpnext/regional/india/utils.py index 9077b79b78c..015aefb8b35 100644 --- a/erpnext/regional/india/utils.py +++ b/erpnext/regional/india/utils.py @@ -367,6 +367,20 @@ def generate_ewb_json(dt, dn): frappe.local.response.filename = '{0}_e-WayBill_Data_{1}.json'.format(doc_name, frappe.utils.random_string(5)) +@frappe.whitelist() +def get_gstins_for_company(company): + company_gstins =[] + if company: + company_gstins = frappe.db.sql("""select + distinct `tabAddress`.gstin + from + `tabAddress`, `tabDynamic Link` + where + `tabDynamic Link`.parent = `tabAddress`.name and + `tabDynamic Link`.parenttype = 'Address' and + `tabDynamic Link`.link_doctype = 'Company' and + `tabDynamic Link`.link_name = '{0}'""".format(company)) + return company_gstins def get_address_details(data, doc, company_address, billing_address): data.fromPincode = validate_pincode(company_address.pincode, 'Company Address') diff --git a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.js b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.js index 1ece14b713b..3a0f0c966d6 100644 --- a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.js +++ b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.js @@ -3,5 +3,31 @@ /* eslint-disable */ {% include "erpnext/accounts/report/item_wise_sales_register/item_wise_sales_register.js" %} +{% include "erpnext/regional/report/india_gst_common/india_gst_common.js" %} -frappe.query_reports["GST Itemised Sales Register"] = frappe.query_reports["Item-wise Sales Register"] \ No newline at end of file +let filters = frappe.query_reports["Item-wise Sales Register"]["filters"]; + +// Add GSTIN filter +filters = filters.concat({ + "fieldname":"company_gstin", + "label": __("Company GSTIN"), + "fieldtype": "Select", + "placeholder":"Company GSTIN", + "options": [""], + "width": "80" +}, { + "fieldname":"invoice_type", + "label": __("Invoice Type"), + "fieldtype": "Select", + "placeholder":"Invoice Type", + "options": ["", "Regular", "SEZ", "Export", "Deemed Export"] +}); + +// Handle company on change +for (var i = 0; i < filters.length; ++i) { + if (filters[i].fieldname === 'company') { + filters[i].on_change = fetch_gstins; + } +} + +frappe.query_reports["GST Itemised Sales Register"] = { "filters": filters, "onload": fetch_gstins }; diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js index df0ef253158..dcb81cb087e 100644 --- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js +++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.js @@ -2,6 +2,8 @@ // For license information, please see license.txt /* eslint-disable */ +{% include "erpnext/regional/report/india_gst_common/india_gst_common.js" %} + frappe.query_reports["HSN-wise-summary of outward supplies"] = { "filters": [ { @@ -10,7 +12,8 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = { "fieldtype": "Link", "options": "Company", "reqd": 1, - "default": frappe.defaults.get_user_default("Company") + "default": frappe.defaults.get_user_default("Company"), + "on_change": fetch_gstins }, { "fieldname":"gst_hsn_code", @@ -18,6 +21,17 @@ frappe.query_reports["HSN-wise-summary of outward supplies"] = { "fieldtype": "Link", "options": "GST HSN Code", "width": "80" + }, + { + "fieldname":"company_gstin", + "label": __("Company GSTIN"), + "fieldtype": "Select", + "placeholder":"Company GSTIN", + "options": [""], + "width": "80" } - ] -} + ], + onload: (report) => { + fetch_gstins(report); + } +}; diff --git a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py index 165458c4d5a..e938e29c440 100644 --- a/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py +++ b/erpnext/regional/report/hsn_wise_summary_of_outward_supplies/hsn_wise_summary_of_outward_supplies.py @@ -87,7 +87,8 @@ def get_conditions(filters): conditions = "" for opts in (("company", " and company=%(company)s"), - ("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s")): + ("gst_hsn_code", " and gst_hsn_code=%(gst_hsn_code)s"), + ("company_gstin", " and company_gstin=%(company_gstin)s")): if filters.get(opts[0]): conditions += opts[1] @@ -193,7 +194,7 @@ def get_merged_data(columns, data): add_column_index.append(i) for row in data: - if merged_hsn_dict.has_key(row[0]): + if row[0] in merged_hsn_dict: to_add_row = merged_hsn_dict.get(row[0]) # add columns from the add_column_index table diff --git a/erpnext/regional/report/india_gst_common/india_gst_common.js b/erpnext/regional/report/india_gst_common/india_gst_common.js new file mode 100644 index 00000000000..49606013946 --- /dev/null +++ b/erpnext/regional/report/india_gst_common/india_gst_common.js @@ -0,0 +1,21 @@ +function fetch_gstins(report) { + var company_gstins = report.get_filter('company_gstin'); + var company = report.get_filter_value('company'); + if (company) { + frappe.call({ + method:'erpnext.regional.india.utils.get_gstins_for_company', + async: false, + args: { + company: company + }, + callback: function(r) { + r.message.unshift(""); + company_gstins.df.options = r.message; + company_gstins.refresh(); + } + }); + } else { + company_gstins.df.options = [""]; + company_gstins.refresh(); + } +} \ No newline at end of file diff --git a/erpnext/stock/doctype/stock_entry/stock_entry.py b/erpnext/stock/doctype/stock_entry/stock_entry.py index d1cc22aa2a6..3150d2ba87f 100644 --- a/erpnext/stock/doctype/stock_entry/stock_entry.py +++ b/erpnext/stock/doctype/stock_entry/stock_entry.py @@ -652,35 +652,36 @@ class StockEntry(StockController): ret = frappe._dict({ 'uom' : item.stock_uom, - 'stock_uom' : item.stock_uom, + 'stock_uom' : item.stock_uom, 'description' : item.description, - 'image' : item.image, + 'image' : item.image, 'item_name' : item.item_name, - 'expense_account' : args.get("expense_account"), - 'cost_center' : get_default_cost_center(args, item, item_group_defaults), - 'qty' : args.get("qty"), + 'cost_center' : get_default_cost_center(args, item, item_group_defaults, self.company), + 'qty' : args.get("qty"), 'transfer_qty' : args.get('qty'), 'conversion_factor' : 1, - 'batch_no' : '', + 'batch_no' : '', 'actual_qty' : 0, 'basic_rate' : 0, - 'serial_no' : '', + 'serial_no' : '', 'has_serial_no' : item.has_serial_no, 'has_batch_no' : item.has_batch_no, 'sample_quantity' : item.sample_quantity }) - for d in [["Account", "expense_account", "default_expense_account"], - ["Cost Center", "cost_center", "cost_center"]]: - company = frappe.db.get_value(d[0], ret.get(d[1]), "company") - if not ret[d[1]] or (company and self.company != company): - ret[d[1]] = frappe.get_cached_value('Company', self.company, d[2]) if d[2] else None # update uom if args.get("uom") and for_update: ret.update(get_uom_details(args.get('item_code'), args.get('uom'), args.get('qty'))) - if not ret["expense_account"]: - ret["expense_account"] = frappe.get_cached_value('Company', self.company, "stock_adjustment_account") + if self.purpose == 'Material Issue': + ret["expense_account"] = (item.get("expense_account") or + item_group_defaults.get("expense_account") or + frappe.get_cached_value('Company', self.company, "default_expense_account")) + + for company_field, field in {'stock_adjustment_account': 'expense_account', + 'cost_center': 'cost_center'}.items(): + if not ret.get(field): + ret[field] = frappe.get_cached_value('Company', self.company, company_field) args['posting_date'] = self.posting_date args['posting_time'] = self.posting_time @@ -1036,8 +1037,7 @@ class StockEntry(StockController): return item_dict def add_to_stock_entry_detail(self, item_dict, bom_no=None): - expense_account, cost_center = frappe.db.get_values("Company", self.company, \ - ["default_expense_account", "cost_center"])[0] + cost_center = frappe.db.get_value("Company", self.company, 'cost_center') for d in item_dict: stock_uom = item_dict[d].get("stock_uom") or frappe.db.get_value("Item", d, "stock_uom") @@ -1051,7 +1051,7 @@ class StockEntry(StockController): se_child.uom = item_dict[d]["uom"] if item_dict[d].get("uom") else stock_uom se_child.stock_uom = stock_uom se_child.qty = flt(item_dict[d]["qty"], se_child.precision("qty")) - se_child.expense_account = item_dict[d].get("expense_account") or expense_account + se_child.expense_account = item_dict[d].get("expense_account") se_child.cost_center = item_dict[d].get("cost_center") or cost_center se_child.allow_alternative_item = item_dict[d].get("allow_alternative_item", 0) se_child.subcontracted_item = item_dict[d].get("main_item_code") diff --git a/erpnext/stock/get_item_details.py b/erpnext/stock/get_item_details.py index d251e49c0a6..851088be948 100644 --- a/erpnext/stock/get_item_details.py +++ b/erpnext/stock/get_item_details.py @@ -366,7 +366,7 @@ def get_default_deferred_account(args, item, fieldname=None): else: return None -def get_default_cost_center(args, item, item_group): +def get_default_cost_center(args, item, item_group, company=None): cost_center = None if args.get('project'): cost_center = frappe.db.get_value("Project", args.get("project"), "cost_center", cache=True) @@ -377,7 +377,13 @@ def get_default_cost_center(args, item, item_group): else: cost_center = item.get('buying_cost_center') or item_group.get('buying_cost_center') - return cost_center or args.get("cost_center") + cost_center = cost_center or args.get("cost_center") + + if (company and cost_center + and frappe.get_cached_value("Cost Center", cost_center, "company") != company): + return None + + return cost_center def get_default_supplier(args, item, item_group): return (item.get("default_supplier")
{%= __(range2) %} {%= __(range3) %} {%= __(range4) %}{%= __(range5) %}{%= __(range6) %} {%= __("Total") %}
{%= __("Total Outstanding") %}{%= format_currency(balance_row[range1]) %}{%= format_number(balance_row[range1], null, 2) %} {%= format_currency(balance_row[range2]) %} {%= format_currency(balance_row[range3]) %} {%= format_currency(balance_row[range4]) %}{%= format_currency(balance_row[range5]) %}{%= format_currency(balance_row[range6]) %} {%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %} {%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %} {%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
{%= frappe.datetime.str_to_user(data[i].posting_date) %}