Merge branch 'develop' into payment-terms
This commit is contained in:
commit
10fc880b06
@ -55,4 +55,7 @@ script:
|
||||
- set -e
|
||||
- bench run-tests
|
||||
- sleep 5
|
||||
- bench reinstall --yes
|
||||
- bench execute erpnext.setup.setup_wizard.utils.complete
|
||||
- bench execute erpnext.setup.utils.enable_all_roles_and_domains
|
||||
- bench run-ui-tests --app erpnext
|
||||
|
@ -4,7 +4,7 @@ import inspect
|
||||
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'''
|
||||
|
@ -499,6 +499,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
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)) {
|
||||
|
@ -325,23 +325,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
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", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@ from erpnext.accounts.doctype.asset.depreciation \
|
||||
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 @@ class SalesInvoice(SellingController):
|
||||
|
||||
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 @@ class SalesInvoice(SellingController):
|
||||
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([{
|
||||
|
@ -1304,6 +1304,17 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEquals(getdate(expected_gl_entries[i][3]), getdate(gle.due_date))
|
||||
|
||||
|
||||
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)
|
||||
|
@ -8,6 +8,7 @@ from frappe import _
|
||||
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 @@ def get_tax_template(posting_date, args):
|
||||
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 @@ def get_tax_template(posting_date, args):
|
||||
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
|
@ -34,6 +34,14 @@ class TestTaxRule(unittest.TestCase):
|
||||
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")
|
||||
|
@ -6,11 +6,11 @@ QUnit.test("test:POS Profile", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make("POS Profile", [
|
||||
{naming_series: "SINV"},
|
||||
{company: "_Test Company"},
|
||||
{company: "Test Company"},
|
||||
{country: "India"},
|
||||
{currency: "INR"},
|
||||
{write_off_account: "Write Off - _TC"},
|
||||
{write_off_cost_center: "Main - _TC"},
|
||||
{write_off_account: "Write Off - TC"},
|
||||
{write_off_cost_center: "Main - TC"},
|
||||
{payments: [
|
||||
[
|
||||
{"default": 1},
|
||||
@ -35,15 +35,16 @@ QUnit.test("test:Sales Invoice", function(assert) {
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make("Sales Invoice", [
|
||||
{customer: "_Test Customer 2"},
|
||||
{company: "_Test Company"},
|
||||
{customer: "Test Customer 2"},
|
||||
{company: "Test Company"},
|
||||
{is_pos: 1},
|
||||
{posting_date: frappe.datetime.get_today()},
|
||||
{due_date: frappe.datetime.get_today()},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": "_Test Item"},
|
||||
{"qty": 5}
|
||||
{"item_code": "Test Product 1"},
|
||||
{"qty": 5},
|
||||
{"warehouse":'Stores - TC'}
|
||||
]]
|
||||
}
|
||||
]);
|
||||
|
@ -79,7 +79,7 @@ def set_address_details(out, party, party_type, doctype=None, company=None):
|
||||
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))
|
||||
|
@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
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):
|
||||
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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
"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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
|
||||
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 @@ def get_columns(additional_table_columns):
|
||||
_("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 @@ def get_items(filters, additional_query_columns):
|
||||
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_items(filters, additional_query_columns):
|
||||
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
|
@ -13,11 +13,10 @@ def execute(filters=None):
|
||||
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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
})
|
||||
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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
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 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
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 @@ def get_columns(additional_table_columns):
|
||||
_("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 @@ def get_items(filters, additional_query_columns):
|
||||
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
|
||||
|
@ -580,9 +580,15 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
||||
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, due_date,
|
||||
(
|
||||
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
|
||||
@ -607,6 +613,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
||||
having (invoice_amount - payment_amount) > 0.005
|
||||
order by posting_date, name, due_date""".format(
|
||||
dr_or_cr = dr_or_cr,
|
||||
invoice = invoice,
|
||||
payment_dr_or_cr = payment_dr_or_cr,
|
||||
condition = condition or ""
|
||||
), {
|
||||
@ -621,6 +628,7 @@ def get_outstanding_invoices(party_type, party, account, condition=None):
|
||||
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),
|
||||
|
@ -8,10 +8,8 @@ QUnit.test("test: purchase order", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
@ -20,7 +18,7 @@ QUnit.test("test: purchase order", function(assert) {
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 100},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order with get items", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
@ -18,7 +17,7 @@ QUnit.test("test: purchase order with get items", function(assert) {
|
||||
{"qty": 5},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
@ -46,9 +45,9 @@ QUnit.test("test: purchase order with get items", function(assert) {
|
||||
assert.ok(cur_frm.doc.items[3].item_name == 'Keyboard', "Product bundle item 3 correct");
|
||||
},
|
||||
|
||||
() => cur_frm.doc.items[1].warehouse = 'Stores - WP',
|
||||
() => cur_frm.doc.items[2].warehouse = 'Stores - WP',
|
||||
() => cur_frm.doc.items[3].warehouse = 'Stores - WP',
|
||||
() => cur_frm.doc.items[1].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
() => cur_frm.doc.items[2].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
() => cur_frm.doc.items[3].warehouse = 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company")),
|
||||
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order receipt", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
@ -20,7 +19,7 @@ QUnit.test("test: purchase order receipt", function(assert) {
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 100},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
]);
|
||||
@ -69,9 +68,9 @@ QUnit.test("test: purchase order receipt", function(assert) {
|
||||
() => {
|
||||
assert.ok($('div.slick-cell.l2.r2 > a').text().includes('Test Product 1')
|
||||
&& $('div.slick-cell.l9.r9 > div').text().includes(5)
|
||||
&& $('div.slick-cell.l12.r12 > div').text().includes(100), "Stock ledger entry correct");
|
||||
&& $('div.slick-cell.l12.r12 > div').text().includes(433.29), "Stock ledger entry correct",$('div.slick-cell.l12.r12 > div').text());
|
||||
},
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order with discount on grand total", function(assert)
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-EUR'},
|
||||
{currency: 'EUR'},
|
||||
@ -20,7 +19,7 @@ QUnit.test("test: purchase order with discount on grand total", function(assert)
|
||||
{"rate": 500 },
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
{apply_discount_on: 'Grand Total'},
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order with item wise discount", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-EUR'},
|
||||
{currency: 'EUR'},
|
||||
@ -19,7 +18,7 @@ QUnit.test("test: purchase order with item wise discount", function(assert) {
|
||||
{"uom": 'Unit'},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - WP'},
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))},
|
||||
{"discount_percentage": 20}
|
||||
]
|
||||
]}
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order with multi UOM", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{items: [
|
||||
[
|
||||
@ -18,7 +17,7 @@ QUnit.test("test: purchase order with multi UOM", function(assert) {
|
||||
{"rate": 100},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]}
|
||||
]);
|
||||
|
@ -8,7 +8,6 @@ QUnit.test("test: purchase order with taxes and charges", function(assert) {
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Order', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{company: 'Wind Power LLC'},
|
||||
{is_subcontracted: 'No'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
@ -20,7 +19,7 @@ QUnit.test("test: purchase order with taxes and charges", function(assert) {
|
||||
{"rate": 500 },
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(), 1)},
|
||||
{"expected_delivery_date": frappe.datetime.add_days(frappe.datetime.now_date(), 5)},
|
||||
{"warehouse": 'Stores - WP'}
|
||||
{"warehouse": 'Stores - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
|
||||
|
@ -196,6 +196,7 @@ def get_list_context(context=None):
|
||||
from erpnext.controllers.website_list_for_contact import get_list_context
|
||||
list_context = get_list_context(context)
|
||||
list_context["show_sidebar"] = True
|
||||
list_context["title"] = "Request for Quotation"
|
||||
return list_context
|
||||
|
||||
def get_supplier_contacts(doctype, txt, searchfield, start, page_len, filters):
|
||||
|
@ -9,7 +9,6 @@ QUnit.test("test: request_for_quotation", function(assert) {
|
||||
date = frappe.datetime.add_days(frappe.datetime.now_date(), 10);
|
||||
return frappe.tests.make('Request for Quotation', [
|
||||
{transaction_date: date},
|
||||
{company: 'Wind Power LLC'},
|
||||
{suppliers: [
|
||||
[
|
||||
{"supplier": 'Test Supplier'},
|
||||
@ -21,7 +20,7 @@ QUnit.test("test: request_for_quotation", function(assert) {
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"schedule_date": frappe.datetime.add_days(frappe.datetime.now_date(),20)},
|
||||
{"warehouse": 'All Warehouses - WP'}
|
||||
{"warehouse": 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
{message_for_supplier: 'Please supply the specified items at the best possible rates'},
|
||||
@ -30,12 +29,12 @@ QUnit.test("test: request_for_quotation", function(assert) {
|
||||
},
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.transaction_date == date, "Date correct");
|
||||
assert.ok(cur_frm.doc.company == 'Wind Power LLC', "Company correct");
|
||||
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].supplier_name == 'Test Supplier', "Supplier name correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].contact == 'Contact 3-Test Supplier', "Contact correct");
|
||||
assert.ok(cur_frm.doc.suppliers[0].email_id == 'test@supplier.com', "Email id correct");
|
||||
assert.ok(cur_frm.doc.items[0].item_name == 'Test Product 4', "Item Name correct");
|
||||
assert.ok(cur_frm.doc.items[0].warehouse == 'All Warehouses - WP', "Warehouse correct");
|
||||
assert.ok(cur_frm.doc.items[0].warehouse == 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company")), "Warehouse correct");
|
||||
assert.ok(cur_frm.doc.message_for_supplier == 'Please supply the specified items at the best possible rates', "Reply correct");
|
||||
assert.ok(cur_frm.doc.tc_name == 'Test Term 1', "Term name correct");
|
||||
},
|
||||
|
@ -8,9 +8,8 @@ QUnit.test("test: supplier", function(assert) {
|
||||
return frappe.tests.make('Supplier', [
|
||||
{supplier_name: 'Test Supplier'},
|
||||
{supplier_type: 'Hardware'},
|
||||
{country: 'United States'},
|
||||
{default_currency: 'USD'},
|
||||
{default_price_list: 'Test-Buying-USD'},
|
||||
{country: 'India'},
|
||||
{default_currency: 'INR'},
|
||||
{credit_days_based_on: 'Fixed Days'},
|
||||
{accounts: [
|
||||
[
|
||||
@ -68,7 +67,7 @@ QUnit.test("test: supplier", function(assert) {
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.supplier_name == 'Test Supplier', "Name correct");
|
||||
assert.ok(cur_frm.doc.supplier_type == 'Hardware', "Type correct");
|
||||
assert.ok(cur_frm.doc.default_currency == 'USD', "Currency correct");
|
||||
assert.ok(cur_frm.doc.default_currency == 'INR', "Currency correct");
|
||||
assert.ok(cur_frm.doc.accounts[0].account == 'Creditors - '+frappe.get_abbr('Test Company'), " Account Head abbr correct");
|
||||
assert.ok($('.address-box:nth-child(3) p').text().includes('Shipping City 3'), "Address correct");
|
||||
assert.ok($('.col-sm-6+ .col-sm-6 .h6').text().includes('Contact 3'), "Contact correct");
|
||||
|
@ -11,16 +11,14 @@ QUnit.test("test: supplier quotation", function(assert) {
|
||||
return frappe.tests.make('Supplier Quotation', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{transaction_date: date},
|
||||
{company: 'Wind Power LLC'},
|
||||
{buying_price_list: 'Test-Buying-USD'},
|
||||
{currency: 'USD'},
|
||||
{currency: 'INR'},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": 'Test Product 4'},
|
||||
{"qty": 5},
|
||||
{"uom": 'Unit'},
|
||||
{"rate": 200},
|
||||
{"warehouse": 'All Warehouses - WP'}
|
||||
{"warehouse": 'All Warehouses - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]
|
||||
]},
|
||||
{apply_discount_on: 'Grand Total'},
|
||||
@ -32,7 +30,7 @@ QUnit.test("test: supplier quotation", function(assert) {
|
||||
() => {
|
||||
// Get Supplier details
|
||||
assert.ok(cur_frm.doc.supplier == 'Test Supplier', "Supplier correct");
|
||||
assert.ok(cur_frm.doc.company == 'Wind Power LLC', "Company correct");
|
||||
assert.ok(cur_frm.doc.company == cur_frm.doc.company, "Company correct");
|
||||
// Get Contact details
|
||||
assert.ok(cur_frm.doc.contact_display == 'Contact 3', "Conatct correct");
|
||||
assert.ok(cur_frm.doc.contact_email == 'test@supplier.com', "Email correct");
|
||||
|
BIN
erpnext/docs/assets/img/setup/print/print-style.png
Normal file
BIN
erpnext/docs/assets/img/setup/print/print-style.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 189 KiB |
@ -1,5 +1,6 @@
|
||||
print-settings
|
||||
print-format-builder
|
||||
print-style
|
||||
print-headings
|
||||
letter-head
|
||||
address-template
|
||||
|
15
erpnext/docs/user/manual/en/setting-up/print/print-style.md
Normal file
15
erpnext/docs/user/manual/en/setting-up/print/print-style.md
Normal file
@ -0,0 +1,15 @@
|
||||
# Print Style
|
||||
|
||||
Frappe/ERPNext comes with pre-set styles for your printed documents. You can also create new styles using CSS that can be applied to all your print formats.
|
||||
|
||||
To create a new **Print Style** go to **Setup > Printing and Branding > Print Style**, or just type "print style" in the search bar.
|
||||
|
||||
Here you can define the CSS rules for your print formats. These apply to both standard and custom print formats. To find out the various classes available, you can make a standard print format, open in a new page and see the source.
|
||||
|
||||
To set a default style, you can go to [Print Settings](/docs/setup/print/print-settings)
|
||||
|
||||
All Print Format styles are based on Bootstrap (Version 3) CSS Framework.
|
||||
|
||||
<img class="screenshot" alt="Print Style" src="/docs/assets/img/setup/print/print-style.png">
|
||||
|
||||
{next}
|
@ -231,12 +231,12 @@ class SalarySlip(TransactionBase):
|
||||
|
||||
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:
|
||||
|
@ -46,7 +46,7 @@ QUnit.test("test Salary Structure", function(assert) {
|
||||
{ payment_account: 'CASH - TC'},
|
||||
]);
|
||||
},
|
||||
() => frappe.timeout(9),
|
||||
() => frappe.timeout(10),
|
||||
() => cur_dialog.set_value('value','Test Salary Structure'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.click_button('Create'),
|
||||
@ -75,7 +75,7 @@ QUnit.test("test Salary Structure", function(assert) {
|
||||
};
|
||||
frappe.run_serially([
|
||||
() => salary_structure('Test Employee 1','Test Employee 3'),
|
||||
() => frappe.timeout(14),
|
||||
() => frappe.timeout(16),
|
||||
() => done()
|
||||
]);
|
||||
});
|
@ -112,11 +112,11 @@ QUnit.test("test: production order", function (assert) {
|
||||
() => click_make(),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.total_incoming_value, "105700",
|
||||
"Incoming cost is correct"); // Price of each item x5, values are in USD
|
||||
"Incoming cost is correct "+cur_frm.doc.total_incoming_value); // Price of each item x5, values are in INR
|
||||
assert.equal(cur_frm.doc.total_outgoing_value, "99000",
|
||||
"Outgoing cost is correct"); // Price of each item x5, values are in USD
|
||||
"Outgoing cost is correct"); // Price of each item x5, values are in INR
|
||||
assert.equal(cur_frm.doc.total_incoming_value - cur_frm.doc.total_outgoing_value, cur_frm.doc.value_difference,
|
||||
"Value difference is correct"); // Price of each item x5, values are in USD
|
||||
"Value difference is correct"); // Price of each item x5, values are in INR
|
||||
},
|
||||
() => frappe.click_button("Save"),
|
||||
() => frappe.timeout(1),
|
||||
@ -135,4 +135,4 @@ QUnit.test("test: production order", function (assert) {
|
||||
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -421,7 +421,7 @@ erpnext.patches.v8_1.removed_report_support_hours
|
||||
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
|
||||
@ -432,3 +432,4 @@ 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
|
||||
erpnext.patches.v8_7.add_more_gst_fields
|
0
erpnext/patches/v8_7/__init__.py
Normal file
0
erpnext/patches/v8_7/__init__.py
Normal file
9
erpnext/patches/v8_7/add_more_gst_fields.py
Normal file
9
erpnext/patches/v8_7/add_more_gst_fields.py
Normal file
@ -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()
|
@ -346,7 +346,21 @@ erpnext.buying.get_items_from_product_bundle = function(frm) {
|
||||
},
|
||||
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 @@ erpnext.buying.get_items_from_product_bundle = function(frm) {
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,7 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
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 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
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,
|
||||
|
@ -147,7 +147,7 @@
|
||||
{
|
||||
"state_number": "22",
|
||||
"state_code": "CT",
|
||||
"state_name": "Chattisgarh"
|
||||
"state_name": "Chhattisgarh"
|
||||
},
|
||||
{
|
||||
"state_number": "04",
|
||||
|
@ -81,6 +81,47 @@ def add_print_formats():
|
||||
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 @@ def make_custom_fields():
|
||||
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'),
|
||||
|
@ -9,9 +9,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='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'
|
||||
])
|
||||
|
@ -9,9 +9,19 @@ 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='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'
|
||||
])
|
||||
|
@ -8,9 +8,17 @@ from erpnext.accounts.report.purchase_register.purchase_register import _execute
|
||||
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'
|
||||
])
|
||||
|
||||
|
@ -8,8 +8,18 @@ from erpnext.accounts.report.sales_register.sales_register import _execute
|
||||
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'
|
||||
])
|
||||
|
@ -15,6 +15,7 @@ QUnit.test('test student applicant', function(assert){
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => {
|
||||
testing_status = $('span.indicator.orange').text();
|
||||
assert.ok(testing_status.indexOf('Submit this document to confirm') == -1); // checking if submit has been successfull
|
||||
|
@ -82,7 +82,7 @@ def get_guardian_map(student_list):
|
||||
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)))
|
||||
|
@ -179,7 +179,7 @@ erpnext.selling.SalesOrderController = erpnext.selling.SellingController.extend(
|
||||
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'),
|
||||
|
@ -330,18 +330,19 @@ class SalesOrder(SellingController):
|
||||
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 @@ def make_delivery_note(source_name, target_doc=None):
|
||||
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 make_production_orders(items, sales_order, company, project=None):
|
||||
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
|
||||
|
@ -326,6 +326,23 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
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", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -5,7 +5,7 @@ from __future__ import unicode_literals
|
||||
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 @@ def get_name_with_abbr(name, company):
|
||||
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():
|
||||
|
@ -27,6 +27,10 @@ def delete_company_transactions(company_name):
|
||||
"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()
|
||||
|
||||
|
@ -10,7 +10,7 @@ QUnit.test("Test: Company", function (assert) {
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value("company_name", "Razer Blade"),
|
||||
() => cur_frm.set_value("abbr", "RB"),
|
||||
() => cur_frm.set_value("default_currency", "USD"),
|
||||
() => cur_frm.set_value("default_currency", "INR"),
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
|
@ -18,3 +18,10 @@ class CustomerGroup(NestedSet):
|
||||
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)
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"add_sample_data": 1,
|
||||
"bank_account": "HDFC",
|
||||
"company_abbr": "GT",
|
||||
"company_abbr": "FT",
|
||||
"company_name": "For Testing",
|
||||
"company_tagline": "Just for GST",
|
||||
"country": "India",
|
||||
|
@ -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,
|
||||
@ -2757,6 +2756,68 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"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,
|
||||
@ -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",
|
||||
|
@ -89,7 +89,9 @@ def get_sle_conditions(filters):
|
||||
conditions.append("""sle.item_code in (select item.name from tabItem item
|
||||
{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"):
|
||||
|
@ -60,32 +60,12 @@ erpnext/stock/doctype/material_request/tests/test_material_request_type_manufact
|
||||
erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_issue.js
|
||||
erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_receipt.js
|
||||
erpnext/stock/doctype/stock_entry/tests/test_stock_entry_for_material_transfer.js
|
||||
erpnext/schools/doctype/grading_scale/test_grading_scale.js
|
||||
erpnext/schools/doctype/assessment_criteria_group/test_assessment_criteria_group.js
|
||||
erpnext/schools/doctype/assessment_criteria/test_assessment_criteria.js
|
||||
erpnext/schools/doctype/course/test_course.js
|
||||
erpnext/schools/doctype/program/test_program.js
|
||||
erpnext/hr/doctype/salary_structure/test_salary_structure.js
|
||||
erpnext/hr/doctype/salary_slip/test_salary_slip.js
|
||||
erpnext/hr/doctype/process_payroll/test_process_payroll.js
|
||||
erpnext/hr/doctype/job_opening/test_job_opening.js
|
||||
erpnext/hr/doctype/job_applicant/test_job_applicant.js
|
||||
erpnext/hr/doctype/offer_letter/test_offer_letter.js
|
||||
erpnext/schools/doctype/guardian/test_guardian.js
|
||||
erpnext/schools/doctype/student_admission/test_student_admission.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
|
||||
erpnext/schools/doctype/student_log/test_student_log.js
|
||||
erpnext/schools/doctype/student_group/test_student_group.js
|
||||
erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js
|
||||
erpnext/schools/doctype/student_leave_application/test_student_leave_application.js
|
||||
erpnext/schools/doctype/student_attendance_tool/test_student_attendance_tool.js
|
||||
erpnext/schools/doctype/student_attendance/test_student_attendance.js
|
||||
erpnext/schools/doctype/assessment_group/test_assessment_group.js
|
||||
erpnext/schools/doctype/assessment_plan/test_assessment_plan.js
|
||||
erpnext/schools/doctype/assessment_result/test_assessment_result.js
|
||||
erpnext/schools/doctype/assessment_result_tool/test_assessment_result_tool.js
|
||||
erpnext/buying/doctype/supplier/test_supplier.js
|
||||
erpnext/buying/doctype/request_for_quotation/tests/test_request_for_quotation.js
|
||||
erpnext/buying/doctype/supplier_quotation/tests/test_supplier_quotation.js
|
||||
@ -101,4 +81,24 @@ erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_item_wise_d
|
||||
erpnext/buying/doctype/purchase_order/tests/test_purchase_order_with_taxes_and_charges.js
|
||||
erpnext/buying/doctype/purchase_order/tests/test_purchase_order_receipt.js
|
||||
erpnext/stock/doctype/purchase_receipt/test_purchase_receipt.js
|
||||
erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.js
|
||||
erpnext/schools/doctype/grading_scale/test_grading_scale.js
|
||||
erpnext/schools/doctype/assessment_criteria_group/test_assessment_criteria_group.js
|
||||
erpnext/schools/doctype/assessment_criteria/test_assessment_criteria.js
|
||||
erpnext/schools/doctype/course/test_course.js
|
||||
erpnext/schools/doctype/program/test_program.js
|
||||
erpnext/schools/doctype/guardian/test_guardian.js
|
||||
erpnext/schools/doctype/student_admission/test_student_admission.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant_dummy_data.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant.js
|
||||
erpnext/schools/doctype/student_applicant/tests/test_student_applicant_options.js
|
||||
erpnext/schools/doctype/student_log/test_student_log.js
|
||||
erpnext/schools/doctype/student_group/test_student_group.js
|
||||
erpnext/schools/doctype/student_group_creation_tool/test_student_group_creation_tool.js
|
||||
erpnext/schools/doctype/student_leave_application/test_student_leave_application.js
|
||||
erpnext/schools/doctype/student_attendance_tool/test_student_attendance_tool.js
|
||||
erpnext/schools/doctype/student_attendance/test_student_attendance.js
|
||||
erpnext/schools/doctype/assessment_group/test_assessment_group.js
|
||||
erpnext/schools/doctype/assessment_plan/test_assessment_plan.js
|
||||
erpnext/schools/doctype/assessment_result/test_assessment_result.js
|
||||
erpnext/schools/doctype/assessment_result_tool/test_assessment_result_tool.js
|
||||
erpnext/stock/doctype/stock_reconciliation/test_stock_reconciliation.js
|
||||
|
Loading…
x
Reference in New Issue
Block a user