Merge branch 'hotfix'
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index fb7c761..1d47f02 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -4,7 +4,7 @@
import frappe
from erpnext.hooks import regional_overrides
-__version__ = '8.8.3'
+__version__ = '8.8.4'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/payment_entry/payment_entry.js b/erpnext/accounts/doctype/payment_entry/payment_entry.js
index 05986a0..92a805f 100644
--- a/erpnext/accounts/doctype/payment_entry/payment_entry.js
+++ b/erpnext/accounts/doctype/payment_entry/payment_entry.js
@@ -499,6 +499,7 @@
var c = frm.add_child("references");
c.reference_doctype = d.voucher_type;
c.reference_name = d.voucher_no;
+ c.due_date = d.due_date
c.total_amount = d.invoice_amount;
c.outstanding_amount = d.outstanding_amount;
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) {
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
index c386450..ef233c6 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.js
@@ -325,23 +325,6 @@
}
this.frm.refresh_fields();
- },
-
- company_address: function() {
- var me = this;
- if(this.frm.doc.company_address) {
- frappe.call({
- method: "frappe.contacts.doctype.address.address.get_address_display",
- args: {"address_dict": this.frm.doc.company_address },
- callback: function(r) {
- if(r.message) {
- me.frm.set_value("company_address_display", r.message)
- }
- }
- })
- } else {
- this.frm.set_value("company_address_display", "");
- }
}
});
diff --git a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
index 9dfacbd..96d617e 100644
--- a/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/sales_invoice.py
@@ -19,6 +19,7 @@
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
from erpnext.stock.doctype.batch.batch import set_batch_nos
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
+from erpnext.setup.doctype.company.company import update_company_current_month_sales
form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
@@ -140,7 +141,7 @@
self.update_time_sheet(self.name)
- frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales', company=self.company)
+ self.update_current_month_sales()
def validate_pos_paid_amount(self):
if len(self.payments) == 0 and self.is_pos:
@@ -178,6 +179,15 @@
self.make_gl_entries_on_cancel()
frappe.db.set(self, 'status', 'Cancelled')
+ self.update_current_month_sales()
+
+ def update_current_month_sales(self):
+ if frappe.flags.in_test:
+ update_company_current_month_sales(self.company)
+ else:
+ frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales',
+ company=self.company)
+
def update_status_updater_args(self):
if cint(self.update_stock):
self.status_updater.extend([{
diff --git a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
index 806b489..e0a453c 100644
--- a/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
+++ b/erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
@@ -1272,6 +1272,17 @@
si.insert()
return si
+ def test_company_monthly_sales(self):
+ existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
+
+ si = create_sales_invoice()
+ current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
+ self.assertEqual(current_month_sales, existing_current_month_sales + si.base_grand_total)
+
+ si.cancel()
+ current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
+ self.assertEqual(current_month_sales, existing_current_month_sales)
+
def create_sales_invoice(**args):
si = frappe.new_doc("Sales Invoice")
args = frappe._dict(args)
diff --git a/erpnext/accounts/doctype/tax_rule/tax_rule.py b/erpnext/accounts/doctype/tax_rule/tax_rule.py
index 36f4221..9e96332 100644
--- a/erpnext/accounts/doctype/tax_rule/tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/tax_rule.py
@@ -8,6 +8,7 @@
from frappe.model.document import Document
from frappe.utils import cstr, cint
from frappe.contacts.doctype.address.address import get_default_address
+from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
class IncorrectCustomerGroup(frappe.ValidationError): pass
class IncorrectSupplierType(frappe.ValidationError): pass
@@ -134,6 +135,9 @@
for key, value in args.iteritems():
if key=="use_for_shopping_cart":
conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
+ if key == 'customer_group' and value:
+ customer_group_condition = get_customer_group_condition(value)
+ conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition))
else:
conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
@@ -157,3 +161,8 @@
return None
return tax_template
+
+def get_customer_group_condition(customer_group):
+ customer_groups = ["'%s'"%(d.name) for d in get_parent_customer_groups(frappe.db.escape(customer_group))]
+ condition = ",".join(['%s'] * len(customer_groups))%(tuple(customer_groups))
+ return condition
\ No newline at end of file
diff --git a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
index a09d81b..383b02b 100644
--- a/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
+++ b/erpnext/accounts/doctype/tax_rule/test_tax_rule.py
@@ -34,6 +34,14 @@
tax_rule2.save()
self.assertTrue(tax_rule2.name)
+ def test_for_parent_customer_group(self):
+ tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
+ sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
+ tax_rule1.save()
+
+ self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial"}),
+ "_Test Sales Taxes and Charges Template")
+
def test_conflict_with_overlapping_dates(self):
tax_rule1 = make_tax_rule(customer= "_Test Customer",
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
diff --git a/erpnext/accounts/party.py b/erpnext/accounts/party.py
index 5cb04c5..ba7ae32 100644
--- a/erpnext/accounts/party.py
+++ b/erpnext/accounts/party.py
@@ -79,7 +79,7 @@
out.shipping_address = get_address_display(out["shipping_address_name"])
out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name))
- if doctype and doctype in ['Sales Invoice']:
+ if doctype and doctype in ['Delivery Note', 'Sales Invoice']:
out.update(get_company_address(company))
if out.company_address:
out.update(get_fetch_values(doctype, 'company_address', out.company_address))
diff --git a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
index 0d1eba1..8f9948e 100644
--- a/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
+++ b/erpnext/accounts/report/item_wise_purchase_register/item_wise_purchase_register.py
@@ -5,6 +5,7 @@
import frappe
from frappe import _
from frappe.utils import flt
+from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
def execute(filters=None):
return _execute(filters)
@@ -12,12 +13,12 @@
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns(additional_table_columns)
- last_col = len(columns)
item_list = get_items(filters, additional_query_columns)
aii_account_map = get_aii_accounts()
if item_list:
- item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
+ itemised_tax, tax_columns = get_tax_accounts(item_list, columns,
+ tax_doctype="Purchase Taxes and Charges")
columns.append({
"fieldname": "currency",
@@ -26,6 +27,7 @@
"width": 80
})
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
+ po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
data = []
for d in item_list:
@@ -33,8 +35,7 @@
if d.purchase_receipt:
purchase_receipt = d.purchase_receipt
elif d.po_detail:
- purchase_receipt = ", ".join(frappe.db.sql_list("""select distinct parent
- from `tabPurchase Receipt Item` where docstatus=1 and purchase_order_item=%s""", d.po_detail))
+ purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
expense_account = d.expense_account or aii_account_map.get(d.company)
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
@@ -46,13 +47,15 @@
row += [
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
- purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount
+ purchase_receipt, expense_account, d.qty, d.stock_uom, d.base_net_rate, d.base_net_amount
]
- for tax in tax_accounts:
- row.append(item_row_tax.get(d.name, {}).get(tax, 0))
+ total_tax = 0
+ for tax in tax_columns:
+ item_tax = itemised_tax.get(d.name, {}).get(tax, {})
+ row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
+ total_tax += flt(item_tax.get("tax_amount"))
- total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
data.append(row)
@@ -76,7 +79,8 @@
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
- _("Qty") + ":Float:120", _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
+ _("Qty") + ":Float:120", _("Stock UOM") + "::100",
+ _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
]
return columns
@@ -106,8 +110,9 @@
pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
- pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
- pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment {0}
+ pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.stock_uom,
+ pi_item.base_net_rate, pi_item.base_net_amount,
+ pi.supplier_name, pi.mode_of_payment {0}
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
order by pi.posting_date desc, pi_item.item_code desc
@@ -116,53 +121,18 @@
def get_aii_accounts():
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
-def get_tax_accounts(item_list, columns):
- import json
- item_row_tax = {}
- tax_accounts = []
- invoice_item_row = {}
- item_row_map = {}
- for d in item_list:
- invoice_item_row.setdefault(d.parent, []).append(d)
- item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
+def get_purchase_receipts_against_purchase_order(item_list):
+ po_pr_map = frappe._dict()
+ po_item_rows = list(set([d.po_detail for d in item_list]))
- tax_details = frappe.db.sql("""
- select
- parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
- from `tabPurchase Taxes and Charges`
- where parenttype = 'Purchase Invoice' and docstatus = 1
- and (account_head is not null and account_head != '')
- and category in ('Total', 'Valuation and Total')
- and parent in (%s)
- """ % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
+ purchase_receipts = frappe.db.sql("""
+ select parent, purchase_order_item
+ from `tabPurchase Receipt Item`
+ where docstatus=1 and purchase_order_item in (%s)
+ group by purchase_order_item, parent
+ """ % (', '.join(['%s']*len(po_item_rows))), tuple(po_item_rows), as_dict=1)
- for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
- if account_head not in tax_accounts:
- tax_accounts.append(account_head)
+ for pr in purchase_receipts:
+ po_pr_map.setdefault(pr.po_detail, []).append(pr.parent)
- if item_wise_tax_detail:
- try:
- item_wise_tax_detail = json.loads(item_wise_tax_detail)
-
- for item_code, tax_amount in item_wise_tax_detail.items():
- tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
-
- item_net_amount = sum([flt(d.base_net_amount)
- for d in item_row_map.get(parent, {}).get(item_code, [])])
-
- for d in item_row_map.get(parent, {}).get(item_code, []):
- item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
- item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
-
- except ValueError:
- continue
- elif charge_type == "Actual" and tax_amount:
- for d in invoice_item_row.get(parent, []):
- item_row_tax.setdefault(d.name, {})[account_head] = \
- flt((tax_amount * d.base_net_amount) / d.base_net_total)
-
- tax_accounts.sort()
- columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
- columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
-
- return item_row_tax, tax_accounts
+ return po_pr_map
\ No newline at end of file
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 7d10b19..30c545f 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
@@ -13,11 +13,10 @@
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
if not filters: filters = {}
columns = get_columns(additional_table_columns)
- last_col = len(columns)
item_list = get_items(filters, additional_query_columns)
if item_list:
- item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
+ itemised_tax, tax_columns = get_tax_accounts(item_list, columns)
columns.append({
"fieldname": "currency",
"label": _("Currency"),
@@ -26,6 +25,7 @@
})
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
+ so_dn_map = get_delivery_notes_against_sales_order(item_list)
data = []
for d in item_list:
@@ -33,8 +33,8 @@
if d.delivery_note:
delivery_note = d.delivery_note
elif d.so_detail:
- delivery_note = ", ".join(frappe.db.sql_list("""select distinct parent
- from `tabDelivery Note Item` where docstatus=1 and so_detail=%s""", d.so_detail))
+ delivery_note = ", ".join(so_dn_map.get(d.so_detail, []))
+
if not delivery_note and d.update_stock:
delivery_note = d.parent
@@ -47,13 +47,16 @@
row += [
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
d.territory, d.project, d.company, d.sales_order,
- delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount
+ delivery_note, d.income_account, d.cost_center, d.qty, d.stock_uom,
+ d.base_net_rate, d.base_net_amount
]
- for tax in tax_accounts:
- row.append(item_row_tax.get(d.name, {}).get(tax, 0))
+ total_tax = 0
+ for tax in tax_columns:
+ item_tax = itemised_tax.get(d.name, {}).get(tax, {})
+ row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
+ total_tax += flt(item_tax.get("tax_amount"))
- total_tax = sum(row[last_col:])
row += [total_tax, d.base_net_amount + total_tax, company_currency]
data.append(row)
@@ -77,7 +80,7 @@
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
- _("Qty") + ":Float:120",
+ _("Qty") + ":Float:120", _("Stock UOM") + "::100",
_("Rate") + ":Currency/currency:120",
_("Amount") + ":Currency/currency:120"
]
@@ -112,62 +115,98 @@
si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
si.customer, si.remarks, si.territory, si.company, si.base_net_total,
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
- si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
- si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
- si.customer_group, si_item.so_detail, si.update_stock {0}
+ si_item.delivery_note, si_item.income_account, si_item.cost_center,
+ si_item.qty, si_item.stock_uom, si_item.base_net_rate, si_item.base_net_amount,
+ si.customer_name, si.customer_group, si_item.so_detail, si.update_stock {0}
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
where si.name = si_item.parent and si.docstatus = 1 %s
order by si.posting_date desc, si_item.item_code desc
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
-def get_tax_accounts(item_list, columns):
+def get_delivery_notes_against_sales_order(item_list):
+ so_dn_map = frappe._dict()
+ so_item_rows = list(set([d.so_detail for d in item_list]))
+
+ delivery_notes = frappe.db.sql("""
+ select parent, so_detail
+ from `tabDelivery Note Item`
+ where docstatus=1 and so_detail in (%s)
+ group by so_detail, parent
+ """ % (', '.join(['%s']*len(so_item_rows))), tuple(so_item_rows), as_dict=1)
+
+ for dn in delivery_notes:
+ so_dn_map.setdefault(dn.so_detail, []).append(dn.parent)
+
+ return so_dn_map
+
+def get_tax_accounts(item_list, columns, tax_doctype="Sales Taxes and Charges"):
import json
- item_row_tax = {}
- tax_accounts = []
- invoice_item_row = {}
item_row_map = {}
+ tax_columns = []
+ invoice_item_row = {}
+ itemised_tax = {}
for d in item_list:
invoice_item_row.setdefault(d.parent, []).append(d)
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
tax_details = frappe.db.sql("""
select
- parent, account_head, item_wise_tax_detail,
+ parent, description, item_wise_tax_detail,
charge_type, base_tax_amount_after_discount_amount
- from `tabSales Taxes and Charges`
+ from `tab%s`
where
parenttype = 'Sales Invoice' and docstatus = 1
- and (account_head is not null and account_head != '')
+ and (description is not null and description != '')
and parent in (%s)
- """ % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
+ order by description
+ """ % (tax_doctype, ', '.join(['%s']*len(invoice_item_row))), tuple(invoice_item_row.keys()))
- for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
- if account_head not in tax_accounts:
- tax_accounts.append(account_head)
+ for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
+ if description not in tax_columns and tax_amount:
+ tax_columns.append(description)
if item_wise_tax_detail:
try:
item_wise_tax_detail = json.loads(item_wise_tax_detail)
- for item_code, tax_amount in item_wise_tax_detail.items():
- tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
+ for item_code, tax_data in item_wise_tax_detail.items():
+ itemised_tax.setdefault(item_code, frappe._dict())
+
+ if isinstance(tax_data, list):
+ tax_rate, tax_amount = tax_data
+ else:
+ tax_rate = tax_data
+ tax_amount = 0
+
+ if charge_type == "Actual" and not tax_rate:
+ tax_rate = "NA"
item_net_amount = sum([flt(d.base_net_amount)
for d in item_row_map.get(parent, {}).get(item_code, [])])
for d in item_row_map.get(parent, {}).get(item_code, []):
- item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
- item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
+ item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
+ if item_net_amount else 0
+ if item_tax_amount:
+ itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
+ "tax_rate": tax_rate,
+ "tax_amount": item_tax_amount
+ })
except ValueError:
continue
elif charge_type == "Actual" and tax_amount:
for d in invoice_item_row.get(parent, []):
- item_row_tax.setdefault(d.name, {})[account_head] = \
- flt((tax_amount * d.base_net_amount) / d.base_net_total)
+ itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
+ "tax_rate": "NA",
+ "tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total)
+ })
- tax_accounts.sort()
- columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
- columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
+ tax_columns.sort()
+ for desc in tax_columns:
+ columns.append(desc + " Rate:Data:80")
+ columns.append(desc + " Amount:Currency/currency:100")
- return item_row_tax, tax_accounts
+ columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"]
+
+ return itemised_tax, tax_columns
diff --git a/erpnext/accounts/utils.py b/erpnext/accounts/utils.py
index 6617802..50530f5 100644
--- a/erpnext/accounts/utils.py
+++ b/erpnext/accounts/utils.py
@@ -580,10 +580,16 @@
dr_or_cr = "credit_in_account_currency - debit_in_account_currency"
payment_dr_or_cr = "payment_gl_entry.debit_in_account_currency - payment_gl_entry.credit_in_account_currency"
+ invoice = 'Sales Invoice' if party_type == 'Customer' else 'Purchase Invoice'
invoice_list = frappe.db.sql("""
select
voucher_no, voucher_type, posting_date, ifnull(sum({dr_or_cr}), 0) as invoice_amount,
(
+ case when (voucher_type = 'Sales Invoice' or voucher_type = 'Purchase Invoice')
+ then (select due_date from `tab{invoice}` where name = voucher_no)
+ else posting_date end
+ ) as due_date,
+ (
select ifnull(sum({payment_dr_or_cr}), 0)
from `tabGL Entry` payment_gl_entry
where payment_gl_entry.against_voucher_type = invoice_gl_entry.voucher_type
@@ -606,6 +612,7 @@
having (invoice_amount - payment_amount) > 0.005
order by posting_date, name""".format(
dr_or_cr = dr_or_cr,
+ invoice = invoice,
payment_dr_or_cr = payment_dr_or_cr,
condition = condition or ""
), {
@@ -618,6 +625,7 @@
outstanding_invoices.append(frappe._dict({
'voucher_no': d.voucher_no,
'voucher_type': d.voucher_type,
+ 'due_date': d.due_date,
'posting_date': d.posting_date,
'invoice_amount': flt(d.invoice_amount),
'payment_amount': flt(d.payment_amount),
diff --git a/erpnext/hr/doctype/salary_slip/salary_slip.py b/erpnext/hr/doctype/salary_slip/salary_slip.py
index 1d17613..356104e 100644
--- a/erpnext/hr/doctype/salary_slip/salary_slip.py
+++ b/erpnext/hr/doctype/salary_slip/salary_slip.py
@@ -231,12 +231,12 @@
holidays = self.get_holidays_for_employee(self.start_date, self.end_date)
working_days = date_diff(self.end_date, self.start_date) + 1
+ actual_lwp = self.calculate_lwp(holidays, working_days)
if not cint(frappe.db.get_value("HR Settings", None, "include_holidays_in_total_working_days")):
working_days -= len(holidays)
if working_days < 0:
frappe.throw(_("There are more holidays than working days this month."))
- actual_lwp = self.calculate_lwp(holidays, working_days)
if not lwp:
lwp = actual_lwp
elif lwp != actual_lwp:
diff --git a/erpnext/patches.txt b/erpnext/patches.txt
index 60caf0f..d781ec7 100644
--- a/erpnext/patches.txt
+++ b/erpnext/patches.txt
@@ -421,7 +421,7 @@
erpnext.patches.v8_1.add_indexes_in_transaction_doctypes
erpnext.patches.v8_3.set_restrict_to_domain_for_module_def
erpnext.patches.v8_1.update_expense_claim_status
-erpnext.patches.v8_3.update_company_total_sales
+erpnext.patches.v8_3.update_company_total_sales #2017-08-16
erpnext.patches.v8_4.make_scorecard_records
erpnext.patches.v8_1.set_delivery_date_in_so_item #2017-07-28
erpnext.patches.v8_5.fix_tax_breakup_for_non_invoice_docs
@@ -431,4 +431,5 @@
erpnext.patches.v8_5.update_customer_group_in_POS_profile
erpnext.patches.v8_6.update_timesheet_company_from_PO
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
-erpnext.patches.v8_5.remove_project_type_property_setter
\ No newline at end of file
+erpnext.patches.v8_5.remove_project_type_property_setter
+erpnext.patches.v8_7.add_more_gst_fields
\ No newline at end of file
diff --git a/erpnext/patches/v8_7/__init__.py b/erpnext/patches/v8_7/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/erpnext/patches/v8_7/__init__.py
diff --git a/erpnext/patches/v8_7/add_more_gst_fields.py b/erpnext/patches/v8_7/add_more_gst_fields.py
new file mode 100644
index 0000000..a1512ed
--- /dev/null
+++ b/erpnext/patches/v8_7/add_more_gst_fields.py
@@ -0,0 +1,9 @@
+import frappe
+from erpnext.regional.india.setup import make_custom_fields
+
+def execute():
+ company = frappe.get_all('Company', filters = {'country': 'India'})
+ if not company:
+ return
+
+ make_custom_fields()
\ No newline at end of file
diff --git a/erpnext/public/js/controllers/buying.js b/erpnext/public/js/controllers/buying.js
index 92ef725..010d4d9 100644
--- a/erpnext/public/js/controllers/buying.js
+++ b/erpnext/public/js/controllers/buying.js
@@ -346,7 +346,21 @@
},
freeze: true,
callback: function(r) {
+ const first_row_is_empty = function(child_table){
+ if($.isArray(child_table) && child_table.length > 0) {
+ return !child_table[0].item_code;
+ }
+ return false;
+ };
+
+ const remove_empty_first_row = function(frm){
+ if (first_row_is_empty(frm.doc.items)){
+ frm.doc.items = frm.doc.items.splice(1);
+ }
+ };
+
if(!r.exc && r.message) {
+ remove_empty_first_row(frm);
for ( var i=0; i< r.message.length; i++ ) {
var d = frm.add_child("items");
var item = r.message[i];
@@ -366,3 +380,4 @@
});
dialog.show();
}
+
diff --git a/erpnext/public/js/controllers/taxes_and_totals.js b/erpnext/public/js/controllers/taxes_and_totals.js
index c653640..d042bb7 100644
--- a/erpnext/public/js/controllers/taxes_and_totals.js
+++ b/erpnext/public/js/controllers/taxes_and_totals.js
@@ -62,7 +62,7 @@
this.frm.doc.conversion_rate = flt(this.frm.doc.conversion_rate, (cur_frm) ? precision("conversion_rate") : 9);
var conversion_rate_label = frappe.meta.get_label(this.frm.doc.doctype, "conversion_rate",
this.frm.doc.name);
- var company_currency = this.frm.doc.currency || this.get_company_currency();
+ var company_currency = this.get_company_currency();
if(!this.frm.doc.conversion_rate) {
if(this.frm.doc.currency == company_currency) {
@@ -419,7 +419,7 @@
this.frm.doc.currency, precision("rounded_total"));
}
if(frappe.meta.get_docfield(this.frm.doc.doctype, "base_rounded_total", this.frm.doc.name)) {
- var company_currency = this.frm.doc.currency || this.get_company_currency();
+ var company_currency = this.get_company_currency();
this.frm.doc.base_rounded_total =
round_based_on_smallest_currency_fraction(this.frm.doc.base_grand_total,
diff --git a/erpnext/regional/india/gst_state_code_data.json b/erpnext/regional/india/gst_state_code_data.json
index 47af9b1..6dab81d 100644
--- a/erpnext/regional/india/gst_state_code_data.json
+++ b/erpnext/regional/india/gst_state_code_data.json
@@ -147,7 +147,7 @@
{
"state_number": "22",
"state_code": "CT",
- "state_name": "Chattisgarh"
+ "state_name": "Chhattisgarh"
},
{
"state_number": "04",
diff --git a/erpnext/regional/india/setup.py b/erpnext/regional/india/setup.py
index 7a7e937..0c59ba0 100644
--- a/erpnext/regional/india/setup.py
+++ b/erpnext/regional/india/setup.py
@@ -81,6 +81,47 @@
def make_custom_fields():
hsn_sac_field = dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Data', options='item_code.gst_hsn_code', insert_after='description', print_hide=1)
+ invoice_gst_fields = [
+ dict(fieldname='gst_section', label='GST Details', fieldtype='Section Break',
+ insert_after='select_print_heading', print_hide=1, collapsible=1),
+ dict(fieldname='invoice_copy', label='Invoice Copy',
+ fieldtype='Select', insert_after='gst_section', print_hide=1, allow_on_submit=1,
+ options='Original for Recipient\nDuplicate for Transporter\nDuplicate for Supplier\nTriplicate for Supplier'),
+ dict(fieldname='reverse_charge', label='Reverse Charge',
+ fieldtype='Select', insert_after='invoice_copy', print_hide=1,
+ options='Y\nN', default='N'),
+ dict(fieldname='gst_col_break', fieldtype='Column Break', insert_after='reverse_charge'),
+ dict(fieldname='invoice_type', label='Invoice Type',
+ fieldtype='Select', insert_after='reverse_charge', print_hide=1,
+ options='Regular\nSEZ\nExport\nDeemed Export', default='Regular'),
+ dict(fieldname='export_type', label='Export Type',
+ fieldtype='Select', insert_after='invoice_type', print_hide=1,
+ depends_on='eval:in_list(["SEZ", "Export", "Deemed Export"], doc.invoice_type)',
+ options='\nWith Payment of Tax\nWithout Payment of Tax'),
+ dict(fieldname='ecommerce_gstin', label='E-commerce GSTIN',
+ fieldtype='Data', insert_after='export_type', print_hide=1)
+ ]
+
+ purchase_invoice_gst_fields = [
+ dict(fieldname='supplier_gstin', label='Supplier GSTIN',
+ fieldtype='Data', insert_after='supplier_address',
+ options='supplier_address.gstin', print_hide=1),
+ dict(fieldname='company_gstin', label='Company GSTIN',
+ fieldtype='Data', insert_after='shipping_address',
+ options='shipping_address.gstin', print_hide=1)
+ ]
+
+ sales_invoice_gst_fields = [
+ dict(fieldname='customer_gstin', label='Customer GSTIN',
+ fieldtype='Data', insert_after='shipping_address',
+ options='shipping_address_name.gstin', print_hide=1),
+ dict(fieldname='place_of_supply', label='Place of Supply',
+ fieldtype='Data', insert_after='customer_gstin', print_hide=1,
+ options='shipping_address_name.gst_state_number', read_only=1),
+ dict(fieldname='company_gstin', label='Company GSTIN',
+ fieldtype='Data', insert_after='company_address',
+ options='company_address.gstin', print_hide=1)
+ ]
custom_fields = {
'Address': [
@@ -91,25 +132,9 @@
dict(fieldname='gst_state_number', label='GST State Number',
fieldtype='Int', insert_after='gst_state', read_only=1),
],
- 'Purchase Invoice': [
- dict(fieldname='supplier_gstin', label='Supplier GSTIN',
- fieldtype='Data', insert_after='supplier_address',
- options='supplier_address.gstin', print_hide=1),
- dict(fieldname='company_gstin', label='Company GSTIN',
- fieldtype='Data', insert_after='shipping_address',
- options='shipping_address.gstin', print_hide=1),
- ],
- 'Sales Invoice': [
- dict(fieldname='customer_gstin', label='Customer GSTIN',
- fieldtype='Data', insert_after='shipping_address',
- options='shipping_address_name.gstin', print_hide=1),
- dict(fieldname='company_gstin', label='Company GSTIN',
- fieldtype='Data', insert_after='company_address',
- options='company_address.gstin', print_hide=1),
- dict(fieldname='invoice_copy', label='Invoice Copy',
- fieldtype='Select', insert_after='select_print_heading', print_hide=1, allow_on_submit=1,
- options='Original for Recipient\nDuplicate for Transporter\nDuplicate for Supplier\nTriplicate for Supplier')
- ],
+ 'Purchase Invoice': purchase_invoice_gst_fields + invoice_gst_fields,
+ 'Sales Invoice': sales_invoice_gst_fields + invoice_gst_fields,
+ "Delivery Note": sales_invoice_gst_fields,
'Item': [
dict(fieldname='gst_hsn_code', label='HSN/SAC',
fieldtype='Link', options='GST HSN Code', insert_after='item_group'),
diff --git a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
index d88febc..1d94c97 100644
--- a/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
+++ b/erpnext/regional/report/gst_itemised_purchase_register/gst_itemised_purchase_register.py
@@ -9,9 +9,17 @@
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Supplier GSTIN', width=120),
dict(fieldtype='Data', label='Company GSTIN', width=120),
+ dict(fieldtype='Data', label='Reverse Charge', width=120),
+ dict(fieldtype='Data', label='Invoice Type', width=120),
+ dict(fieldtype='Data', label='Export Type', width=120),
+ dict(fieldtype='Data', label='E-Commerce GSTIN', width=130),
dict(fieldtype='Data', label='HSN Code', width=120)
], additional_query_columns=[
'supplier_gstin',
'company_gstin',
+ 'reverse_charge',
+ 'invoice_type',
+ 'export_type',
+ 'ecommerce_gstin',
'gst_hsn_code'
])
diff --git a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
index 14ddff3..40bbae8 100644
--- a/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
+++ b/erpnext/regional/report/gst_itemised_sales_register/gst_itemised_sales_register.py
@@ -9,9 +9,19 @@
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Customer GSTIN', width=120),
dict(fieldtype='Data', label='Company GSTIN', width=120),
+ dict(fieldtype='Data', label='Place of Supply', width=120),
+ dict(fieldtype='Data', label='Reverse Charge', width=120),
+ dict(fieldtype='Data', label='Invoice Type', width=120),
+ dict(fieldtype='Data', label='Export Type', width=120),
+ dict(fieldtype='Data', label='E-Commerce GSTIN', width=130),
dict(fieldtype='Data', label='HSN Code', width=120)
], additional_query_columns=[
'customer_gstin',
'company_gstin',
+ 'place_of_supply',
+ 'reverse_charge',
+ 'invoice_type',
+ 'export_type',
+ 'ecommerce_gstin',
'gst_hsn_code'
])
diff --git a/erpnext/regional/report/gst_purchase_register/gst_purchase_register.py b/erpnext/regional/report/gst_purchase_register/gst_purchase_register.py
index 59687d0..8d479a9 100644
--- a/erpnext/regional/report/gst_purchase_register/gst_purchase_register.py
+++ b/erpnext/regional/report/gst_purchase_register/gst_purchase_register.py
@@ -8,9 +8,17 @@
def execute(filters=None):
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Supplier GSTIN', width=120),
- dict(fieldtype='Data', label='Company GSTIN', width=120)
+ dict(fieldtype='Data', label='Company GSTIN', width=120),
+ dict(fieldtype='Data', label='Reverse Charge', width=120),
+ dict(fieldtype='Data', label='Invoice Type', width=120),
+ dict(fieldtype='Data', label='Export Type', width=120),
+ dict(fieldtype='Data', label='E-Commerce GSTIN', width=130)
], additional_query_columns=[
'supplier_gstin',
- 'company_gstin'
+ 'company_gstin',
+ 'reverse_charge',
+ 'invoice_type',
+ 'export_type',
+ 'ecommerce_gstin'
])
diff --git a/erpnext/regional/report/gst_sales_register/gst_sales_register.py b/erpnext/regional/report/gst_sales_register/gst_sales_register.py
index 440594a..7f6f809 100644
--- a/erpnext/regional/report/gst_sales_register/gst_sales_register.py
+++ b/erpnext/regional/report/gst_sales_register/gst_sales_register.py
@@ -8,8 +8,18 @@
def execute(filters=None):
return _execute(filters, additional_table_columns=[
dict(fieldtype='Data', label='Customer GSTIN', width=120),
- dict(fieldtype='Data', label='Company GSTIN', width=120)
+ dict(fieldtype='Data', label='Company GSTIN', width=120),
+ dict(fieldtype='Data', label='Place of Supply', width=120),
+ dict(fieldtype='Data', label='Reverse Charge', width=120),
+ dict(fieldtype='Data', label='Invoice Type', width=120),
+ dict(fieldtype='Data', label='Export Type', width=120),
+ dict(fieldtype='Data', label='E-Commerce GSTIN', width=130)
], additional_query_columns=[
'customer_gstin',
- 'company_gstin'
+ 'company_gstin',
+ 'place_of_supply',
+ 'reverse_charge',
+ 'invoice_type',
+ 'export_type',
+ 'ecommerce_gstin'
])
diff --git a/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py b/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
index f191022..641b783 100644
--- a/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
+++ b/erpnext/schools/report/student_and_guardian_contact_details/student_and_guardian_contact_details.py
@@ -82,7 +82,7 @@
select parent, guardian, guardian_name, relation from `tabStudent Guardian` where parent in (%s)''' %
', '.join(['%s']*len(student_list)), tuple(student_list), as_dict=1)
- guardian_list = list(set([g.guardian for g in guardian_details]))
+ guardian_list = list(set([g.guardian for g in guardian_details])) or ['']
guardian_mobile_no = dict(frappe.db.sql("""select name, mobile_number from `tabGuardian`
where name in (%s)""" % ", ".join(['%s']*len(guardian_list)), tuple(guardian_list)))
diff --git a/erpnext/selling/doctype/sales_order/sales_order.js b/erpnext/selling/doctype/sales_order/sales_order.js
index 80dc4f2..901e236 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.js
+++ b/erpnext/selling/doctype/sales_order/sales_order.js
@@ -179,7 +179,7 @@
doc: this.frm.doc,
method: 'get_production_order_items',
callback: function(r) {
- if(!r.message.every(function(d) { return !!d.bom })) {
+ if(!r.message) {
frappe.msgprint({
title: __('Production Order not created'),
message: __('No Items with Bill of Materials to Manufacture'),
diff --git a/erpnext/selling/doctype/sales_order/sales_order.py b/erpnext/selling/doctype/sales_order/sales_order.py
index c6dbd70..396b1c2 100644
--- a/erpnext/selling/doctype/sales_order/sales_order.py
+++ b/erpnext/selling/doctype/sales_order/sales_order.py
@@ -330,18 +330,19 @@
def get_production_order_items(self):
'''Returns items with BOM that already do not have a linked production order'''
items = []
- for i in self.packed_items or self.items:
- bom = frappe.get_all('BOM', dict(item=i.item_code, is_active=True),
- order_by='is_default desc')
- bom = bom[0].name if bom else None
- stock_qty = i.qty if self.packed_items else i.stock_qty
- items.append(dict(
- item_code= i.item_code,
- bom = bom,
- warehouse = i.warehouse,
- pending_qty= stock_qty - flt(frappe.db.sql('''select sum(qty) from `tabProduction Order`
- where production_item=%s and sales_order=%s''', (i.item_code, self.name))[0][0])
- ))
+
+ for table in [self.items, self.packed_items]:
+ for i in table:
+ bom = get_default_bom_item(i.item_code)
+ if bom:
+ stock_qty = i.qty if i.doctype == 'Packed Item' else i.stock_qty
+ items.append(dict(
+ item_code= i.item_code,
+ bom = bom,
+ warehouse = i.warehouse,
+ pending_qty= stock_qty - flt(frappe.db.sql('''select sum(qty) from `tabProduction Order`
+ where production_item=%s and sales_order=%s''', (i.item_code, self.name))[0][0])
+ ))
return items
@@ -465,6 +466,11 @@
target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("calculate_taxes_and_totals")
+
+ # set company address
+ target.update(get_company_address(target.company))
+ if target.company_address:
+ target.update(get_fetch_values("Delivery Note", 'company_address', target.company_address))
def update_item(source, target, source_parent):
target.base_amount = (flt(source.qty) - flt(source.delivered_qty)) * flt(source.base_rate)
@@ -774,3 +780,10 @@
def update_status(status, name):
so = frappe.get_doc("Sales Order", name)
so.update_status(status)
+
+def get_default_bom_item(item_code):
+ bom = frappe.get_all('BOM', dict(item=item_code, is_active=True),
+ order_by='is_default desc')
+ bom = bom[0].name if bom else None
+
+ return bom
diff --git a/erpnext/selling/sales_common.js b/erpnext/selling/sales_common.js
index 6a84d0e..e9671c8 100644
--- a/erpnext/selling/sales_common.js
+++ b/erpnext/selling/sales_common.js
@@ -326,6 +326,23 @@
this.calculate_taxes_and_totals();
cur_frm.refresh_fields();
}
+ },
+
+ company_address: function() {
+ var me = this;
+ if(this.frm.doc.company_address) {
+ frappe.call({
+ method: "frappe.contacts.doctype.address.address.get_address_display",
+ args: {"address_dict": this.frm.doc.company_address },
+ callback: function(r) {
+ if(r.message) {
+ me.frm.set_value("company_address_display", r.message)
+ }
+ }
+ })
+ } else {
+ this.frm.set_value("company_address_display", "");
+ }
}
});
diff --git a/erpnext/setup/doctype/company/company.py b/erpnext/setup/doctype/company/company.py
index 29630ee..b945ee4 100644
--- a/erpnext/setup/doctype/company/company.py
+++ b/erpnext/setup/doctype/company/company.py
@@ -5,7 +5,7 @@
import frappe, os
from frappe import _
-from frappe.utils import cint
+from frappe.utils import cint, today, formatdate
import frappe.defaults
@@ -312,39 +312,35 @@
return " - ".join(parts)
def update_company_current_month_sales(company):
- from frappe.utils import today, formatdate
current_month_year = formatdate(today(), "MM-yyyy")
- results = frappe.db.sql(('''
+ results = frappe.db.sql('''
select
sum(base_grand_total) as total, date_format(posting_date, '%m-%Y') as month_year
from
`tabSales Invoice`
where
- date_format(posting_date, '%m-%Y')="{0}" and
- company = "{1}"
+ date_format(posting_date, '%m-%Y')="{0}"
+ and docstatus = 1
+ and company = "{1}"
group by
- month_year;
- ''').format(current_month_year, frappe.db.escape(company)), as_dict = True)
+ month_year
+ '''.format(current_month_year, frappe.db.escape(company)), as_dict = True)
monthly_total = results[0]['total'] if len(results) > 0 else 0
- frappe.db.sql(('''
- update tabCompany set total_monthly_sales = %s where name=%s
- '''), (monthly_total, frappe.db.escape(company)))
+ frappe.db.set_value("Company", company, "total_monthly_sales", monthly_total)
frappe.db.commit()
-
def update_company_monthly_sales(company):
'''Cache past year monthly sales of every company based on sales invoices'''
from frappe.utils.goal import get_monthly_results
import json
- filter_str = "company = '{0}' and status != 'Draft'".format(frappe.db.escape(company))
- month_to_value_dict = get_monthly_results("Sales Invoice", "base_grand_total", "posting_date", filter_str, "sum")
+ filter_str = "company = '{0}' and status != 'Draft' and docstatus=1".format(frappe.db.escape(company))
+ month_to_value_dict = get_monthly_results("Sales Invoice", "base_grand_total",
+ "posting_date", filter_str, "sum")
- frappe.db.sql(('''
- update tabCompany set sales_monthly_history = %s where name=%s
- '''), (json.dumps(month_to_value_dict), frappe.db.escape(company)))
+ frappe.db.set_value("Company", company, "sales_monthly_history", json.dumps(month_to_value_dict))
frappe.db.commit()
def cache_companies_monthly_sales_history():
diff --git a/erpnext/setup/doctype/company/delete_company_transactions.py b/erpnext/setup/doctype/company/delete_company_transactions.py
index f1fb0cf..d975a9e 100644
--- a/erpnext/setup/doctype/company/delete_company_transactions.py
+++ b/erpnext/setup/doctype/company/delete_company_transactions.py
@@ -27,6 +27,10 @@
"Purchase Taxes and Charges Template", "POS Profile", 'BOM'):
delete_for_doctype(doctype, company_name)
+ # reset company values
+ doc.total_monthly_sales = 0
+ doc.sales_monthly_history = None
+ doc.save()
# Clear notification counts
clear_notifications()
diff --git a/erpnext/setup/doctype/customer_group/customer_group.py b/erpnext/setup/doctype/customer_group/customer_group.py
index b25095b..0f1ee81 100644
--- a/erpnext/setup/doctype/customer_group/customer_group.py
+++ b/erpnext/setup/doctype/customer_group/customer_group.py
@@ -18,3 +18,10 @@
def validate_name_with_customer(self):
if frappe.db.exists("Customer", self.name):
frappe.msgprint(_("An Customer exists with same name"), raise_exception=1)
+
+def get_parent_customer_groups(customer_group):
+ lft, rgt = frappe.db.get_value("Customer Group", customer_group, ['lft', 'rgt'])
+
+ return frappe.db.sql("""select name from `tabCustomer Group`
+ where lft <= %s and rgt >= %s
+ order by lft asc""", (lft, rgt), as_dict=True)
\ No newline at end of file
diff --git a/erpnext/stock/doctype/delivery_note/delivery_note.json b/erpnext/stock/doctype/delivery_note/delivery_note.json
index 345750f..4477c1d 100644
--- a/erpnext/stock/doctype/delivery_note/delivery_note.json
+++ b/erpnext/stock/doctype/delivery_note/delivery_note.json
@@ -860,22 +860,22 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "",
- "fieldname": "customer_group",
+ "fieldname": "company_address",
"fieldtype": "Link",
- "hidden": 1,
+ "hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Customer Group",
+ "label": "Company Address Name",
"length": 0,
"no_copy": 0,
- "options": "Customer Group",
+ "options": "Address",
"permlevel": 0,
- "print_hide": 1,
+ "precision": "",
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -891,9 +891,8 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
- "description": "",
- "fieldname": "territory",
- "fieldtype": "Link",
+ "fieldname": "company_address_display",
+ "fieldtype": "Small Text",
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
@@ -901,12 +900,12 @@
"in_global_search": 0,
"in_list_view": 0,
"in_standard_filter": 0,
- "label": "Territory",
+ "label": "Company Address",
"length": 0,
"no_copy": 0,
- "options": "Territory",
"permlevel": 0,
- "print_hide": 1,
+ "precision": "",
+ "print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
"remember_last_selected_value": 0,
@@ -2761,6 +2760,68 @@
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "customer_group",
+ "fieldtype": "Link",
+ "hidden": 1,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Customer Group",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Customer Group",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
+ "collapsible": 0,
+ "columns": 0,
+ "description": "",
+ "fieldname": "territory",
+ "fieldtype": "Link",
+ "hidden": 0,
+ "ignore_user_permissions": 0,
+ "ignore_xss_filter": 0,
+ "in_filter": 0,
+ "in_global_search": 0,
+ "in_list_view": 0,
+ "in_standard_filter": 0,
+ "label": "Territory",
+ "length": 0,
+ "no_copy": 0,
+ "options": "Territory",
+ "permlevel": 0,
+ "print_hide": 1,
+ "print_hide_if_no_value": 0,
+ "read_only": 0,
+ "remember_last_selected_value": 0,
+ "report_hide": 0,
+ "reqd": 0,
+ "search_index": 0,
+ "set_only_once": 0,
+ "unique": 0
+ },
+ {
+ "allow_bulk_edit": 0,
+ "allow_on_submit": 0,
+ "bold": 0,
"collapsible": 1,
"columns": 0,
"fieldname": "printing_details",
@@ -3426,7 +3487,7 @@
"istable": 0,
"max_attachments": 0,
"menu_index": 0,
- "modified": "2017-07-19 13:48:09.630820",
+ "modified": "2017-08-09 15:44:14.253457",
"modified_by": "Administrator",
"module": "Stock",
"name": "Delivery Note",
diff --git a/erpnext/stock/report/stock_ledger/stock_ledger.py b/erpnext/stock/report/stock_ledger/stock_ledger.py
index ec55cec..4a8868a 100644
--- a/erpnext/stock/report/stock_ledger/stock_ledger.py
+++ b/erpnext/stock/report/stock_ledger/stock_ledger.py
@@ -73,7 +73,9 @@
conditions.append("""item_code in (select name from tabItem
{item_conditions})""".format(item_conditions=item_conditions))
if filters.get("warehouse"):
- conditions.append(get_warehouse_condition(filters.get("warehouse")))
+ warehouse_condition = get_warehouse_condition(filters.get("warehouse"))
+ if warehouse_condition:
+ conditions.append(warehouse_condition)
if filters.get("voucher_no"):
conditions.append("voucher_no=%(voucher_no)s")
if filters.get("batch_no"):