Merge branch 'version-11-hotfix' into version-11

This commit is contained in:
Sahil Khan
2019-08-13 14:41:58 +05:30
22 changed files with 174 additions and 119 deletions

View File

@@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '11.1.53'
__version__ = '11.1.54'
def get_default_company(user=None):
'''Get default company for user'''

View File

@@ -121,7 +121,10 @@ frappe.treeview_settings["Account"] = {
},
onrender: function(node) {
if(frappe.boot.user.can_read.indexOf("GL Entry") !== -1){
var dr_or_cr = in_list(["Liability", "Income", "Equity"], node.data.root_type) ? "Cr" : "Dr";
// show Dr if positive since balance is calculated as debit - credit else show Cr
let dr_or_cr = node.data.balance_in_account_currency > 0 ? "Dr": "Cr";
if (node.data && node.data.balance!==undefined) {
$('<span class="balance-area pull-right text-muted small">'
+ (node.data.balance_in_account_currency ?

View File

@@ -167,39 +167,7 @@
"set_only_once": 0,
"translatable": 0,
"unique": 0
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
"columns": 0,
"fieldname": "status",
"fieldtype": "Select",
"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": "Status",
"length": 0,
"no_copy": 0,
"options": "Open\nClosed",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"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,
"translatable": 0,
"unique": 0
},
},
{
"allow_bulk_edit": 0,
"allow_on_submit": 0,
@@ -273,7 +241,7 @@
"issingle": 0,
"istable": 0,
"max_attachments": 0,
"modified": "2018-04-13 19:14:47.593753",
"modified": "2019-08-01 19:14:47.593753",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Accounting Period",

View File

@@ -4,8 +4,10 @@
from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.model.document import Document
from frappe import _
class OverlapError(frappe.ValidationError): pass
class AccountingPeriod(Document):
def validate(self):
@@ -34,12 +36,13 @@ class AccountingPeriod(Document):
}, as_dict=True)
if len(existing_accounting_period) > 0:
frappe.throw(_("Accounting Period overlaps with {0}".format(existing_accounting_period[0].get("name"))))
frappe.throw(_("Accounting Period overlaps with {0}")
.format(existing_accounting_period[0].get("name")), OverlapError)
def get_doctypes_for_closing(self):
docs_for_closing = []
#if not self.closed_documents or len(self.closed_documents) == 0:
doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", "Bank Reconciliation", "Asset", "Purchase Order", "Sales Order", "Leave Application", "Leave Allocation", "Stock Entry"]
doctypes = ["Sales Invoice", "Purchase Invoice", "Journal Entry", "Payroll Entry", "Bank Reconciliation",
"Asset", "Purchase Order", "Sales Order", "Leave Application", "Leave Allocation", "Stock Entry"]
closed_doctypes = [{"document_type": doctype, "closed": 1} for doctype in doctypes]
for closed_doctype in closed_doctypes:
docs_for_closing.append(closed_doctype)
@@ -52,4 +55,4 @@ class AccountingPeriod(Document):
self.append('closed_documents', {
"document_type": doctype_for_closing.document_type,
"closed": doctype_for_closing.closed
})
})

View File

@@ -5,23 +5,42 @@ from __future__ import unicode_literals
import frappe
import unittest
from frappe.utils import nowdate, add_months
from erpnext.accounts.general_ledger import ClosedAccountingPeriod
from erpnext.accounts.doctype.accounting_period.accounting_period import OverlapError
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
# class TestAccountingPeriod(unittest.TestCase):
# def test_overlap(self):
# ap1 = create_accounting_period({"start_date":"2018-04-01", "end_date":"2018-06-30", "company":"Wind Power LLC"})
# ap1.save()
# ap2 = create_accounting_period({"start_date":"2018-06-30", "end_date":"2018-07-10", "company":"Wind Power LLC"})
# self.assertRaises(frappe.OverlapError, accounting_period_2.save())
#
# def tearDown(self):
# pass
#
#
# def create_accounting_period(**args):
# accounting_period = frappe.new_doc("Accounting Period")
# accounting_period.start_date = args.start_date or frappe.utils.datetime.date(2018, 4, 1)
# accounting_period.end_date = args.end_date or frappe.utils.datetime.date(2018, 6, 30)
# accounting_period.company = args.company
# accounting_period.period_name = "_Test_Period_Name_1"
#
# return accounting_period
class TestAccountingPeriod(unittest.TestCase):
def test_overlap(self):
ap1 = create_accounting_period(start_date = "2018-04-01",
end_date = "2018-06-30", company = "Wind Power LLC")
ap1.save()
ap2 = create_accounting_period(start_date = "2018-06-30",
end_date = "2018-07-10", company = "Wind Power LLC", period_name = "Test Accounting Period 1")
self.assertRaises(OverlapError, ap2.save)
def test_accounting_period(self):
ap1 = create_accounting_period(period_name = "Test Accounting Period 2")
ap1.save()
doc = create_sales_invoice(do_not_submit=1, cost_center = "_Test Company - _TC", warehouse = "Stores - _TC")
self.assertRaises(ClosedAccountingPeriod, doc.submit)
def tearDown(self):
for d in frappe.get_all("Accounting Period"):
frappe.delete_doc("Accounting Period", d.name)
def create_accounting_period(**args):
args = frappe._dict(args)
accounting_period = frappe.new_doc("Accounting Period")
accounting_period.start_date = args.start_date or nowdate()
accounting_period.end_date = args.end_date or add_months(nowdate(), 1)
accounting_period.company = args.company or "_Test Company"
accounting_period.period_name =args.period_name or "_Test_Period_Name_1"
accounting_period.append("closed_documents", {
"document_type": 'Sales Invoice', "closed": 1
})
return accounting_period

View File

@@ -50,7 +50,7 @@ class BankTransaction(StatusUpdater):
if paid_amount and allocated_amount:
if flt(allocated_amount[0]["allocated_amount"]) > flt(paid_amount):
frappe.throw(_("The total allocated amount ({0}) is greated than the paid amount ({1}).".format(flt(allocated_amount[0]["allocated_amount"]), flt(paid_amount))))
elif flt(allocated_amount[0]["allocated_amount"]) == flt(paid_amount):
else:
if payment_entry.payment_document in ["Payment Entry", "Journal Entry", "Purchase Invoice", "Expense Claim"]:
self.clear_simple_entry(payment_entry)

View File

@@ -78,6 +78,7 @@ class SalesInvoice(SellingController):
self.so_dn_required()
self.validate_proj_cust()
self.validate_pos_return()
self.validate_with_previous_doc()
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.validate_uom_is_integer("uom", "qty")
@@ -199,6 +200,16 @@ class SalesInvoice(SellingController):
if "Healthcare" in active_domains:
manage_invoice_submit_cancel(self, "on_submit")
def validate_pos_return(self):
if self.is_pos and self.is_return:
total_amount_in_payments = 0
for payment in self.payments:
total_amount_in_payments += payment.amount
if total_amount_in_payments < self.rounded_total:
frappe.throw(_("Total payments amount can't be greater than {}".format(-self.rounded_total)))
def validate_pos_paid_amount(self):
if len(self.payments) == 0 and self.is_pos:
frappe.throw(_("At least one mode of payment is required for POS invoice."))

View File

@@ -9,11 +9,13 @@ from frappe.model.meta import get_field_precision
from erpnext.accounts.doctype.budget.budget import validate_expense_against_budget
class ClosedAccountingPeriod(frappe.ValidationError): pass
class StockAccountInvalidTransaction(frappe.ValidationError): pass
def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, update_outstanding='Yes', from_repost=False):
if gl_map:
if not cancel:
validate_accounting_period(gl_map)
gl_map = process_gl_map(gl_map, merge_entries)
if gl_map and len(gl_map) > 1:
save_entries(gl_map, adv_adj, update_outstanding, from_repost)
@@ -22,6 +24,27 @@ def make_gl_entries(gl_map, cancel=False, adv_adj=False, merge_entries=True, upd
else:
delete_gl_entries(gl_map, adv_adj=adv_adj, update_outstanding=update_outstanding)
def validate_accounting_period(gl_map):
accounting_periods = frappe.db.sql(""" SELECT
ap.name as name
FROM
`tabAccounting Period` ap, `tabClosed Document` cd
WHERE
ap.name = cd.parent
AND ap.company = %(company)s
AND cd.closed = 1
AND cd.document_type = %(voucher_type)s
AND %(date)s between ap.start_date and ap.end_date
""", {
'date': gl_map[0].posting_date,
'company': gl_map[0].company,
'voucher_type': gl_map[0].voucher_type
}, as_dict=1)
if accounting_periods:
frappe.throw(_("You can't create accounting entries in the closed accounting period {0}")
.format(accounting_periods[0].name), ClosedAccountingPeriod)
def process_gl_map(gl_map, merge_entries=True):
if merge_entries:
gl_map = merge_similar_entries(gl_map)

View File

@@ -4,7 +4,7 @@
{%- macro render_currency(df, doc) -%}
<div class="row {% if df.bold %}important{% endif %} data-field">
<div class="col-xs-{{ "9" if df.fieldtype=="Check" else "5" }}
{%- if doc._align_labels_right %} text-right{%- endif -%}">
{%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _(df.label) }}</label>
</div>
<div class="col-xs-{{ "3" if df.fieldtype=="Check" else "7" }} value">
@@ -23,7 +23,7 @@
{%- for charge in data -%}
{%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
<div class="row">
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ charge.get_formatted("description") }}</label></div>
<div class="col-xs-7 text-right">
{{ frappe.utils.fmt_money((charge.tax_amount)|int|abs, currency=doc.currency) }}
@@ -103,8 +103,8 @@
{% for section in page %}
<div class="row section-break">
{% if section.columns.fields %}
{%- if doc._line_breaks and loop.index != 1 -%}<hr>{%- endif -%}
{%- if doc._show_section_headings and section.label and section.has_data -%}
{%- if doc.print_line_breaks and loop.index != 1 -%}<hr>{%- endif -%}
{%- if doc.print_section_headings and section.label and section.has_data -%}
<h4 class='col-sm-12'>{{ _(section.label) }}</h4>
{% endif %}
{%- endif -%}

View File

@@ -472,7 +472,7 @@ def make_rm_stock_entry(purchase_order, rm_items):
'from_warehouse': rm_item_data["warehouse"],
'stock_uom': rm_item_data["stock_uom"],
'main_item_code': rm_item_data["item_code"],
'allow_alternative_item': item_wh[rm_item_code].get('allow_alternative_item')
'allow_alternative_item': item_wh.get(rm_item_code, {}).get('allow_alternative_item')
}
}
stock_entry.add_to_stock_entry_detail(items_dict)

View File

@@ -717,7 +717,7 @@ def get_items_from_bom(item_code, bom, exploded_item=1):
where
t2.parent = t1.name and t1.item = %s
and t1.docstatus = 1 and t1.is_active = 1 and t1.name = %s
and t2.item_code = t3.name and t3.is_stock_item = 1""".format(doctype),
and t2.item_code = t3.name""".format(doctype),
(item_code, bom), as_dict=1)
if not bom_items:

View File

@@ -21,42 +21,45 @@ def get_list_context(context=None):
def get_transaction_list(doctype, txt=None, filters=None, limit_start=0, limit_page_length=20, order_by="modified"):
user = frappe.session.user
key = None
ignore_permissions = False
if not filters: filters = []
if doctype == 'Supplier Quotation':
filters.append((doctype, "docstatus", "<", 2))
filters.append((doctype, 'docstatus', '<', 2))
else:
filters.append((doctype, "docstatus", "=", 1))
filters.append((doctype, 'docstatus', '=', 1))
if (user != "Guest" and is_website_user()) or doctype == 'Request for Quotation':
if (user != 'Guest' and is_website_user()) or doctype == 'Request for Quotation':
parties_doctype = 'Request for Quotation Supplier' if doctype == 'Request for Quotation' else doctype
# find party for this contact
customers, suppliers = get_customers_suppliers(parties_doctype, user)
if not customers and not suppliers: return []
key, parties = get_party_details(customers, suppliers)
if doctype == 'Request for Quotation':
return rfq_transaction_list(parties_doctype, doctype, parties, limit_start, limit_page_length)
filters.append((doctype, key, "in", parties))
if key:
return post_process(doctype, get_list_for_transactions(doctype, txt,
filters=filters, fields="name",limit_start=limit_start,
limit_page_length=limit_page_length,ignore_permissions=True,
order_by="modified desc"))
if customers:
if doctype == 'Quotation':
filters.append(('quotation_to', '=', 'Customer'))
filters.append(('party_name', 'in', customers))
else:
filters.append(('customer', 'in', customers))
elif suppliers:
filters.append(('supplier', 'in', suppliers))
else:
return []
return post_process(doctype, get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length,
fields="name", order_by="modified desc"))
if doctype == 'Request for Quotation':
parties = customers or suppliers
return rfq_transaction_list(parties_doctype, doctype, parties, limit_start, limit_page_length)
# Since customers and supplier do not have direct access to internal doctypes
ignore_permissions = True
transactions = get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length,
fields='name', ignore_permissions=ignore_permissions, order_by='modified desc')
return post_process(doctype, transactions)
def get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_length=20,
ignore_permissions=False,fields=None, order_by=None):
ignore_permissions=False, fields=None, order_by=None):
""" Get List of transactions like Invoices, Orders """
from frappe.www.list import get_list
meta = frappe.get_meta(doctype)
@@ -83,16 +86,6 @@ def get_list_for_transactions(doctype, txt, filters, limit_start, limit_page_len
return data
def get_party_details(customers, suppliers):
if customers:
key, parties = "customer", customers
elif suppliers:
key, parties = "supplier", suppliers
else:
key, parties = "customer", []
return key, parties
def rfq_transaction_list(parties_doctype, doctype, parties, limit_start, limit_page_length):
data = frappe.db.sql("""select distinct parent as name, supplier from `tab{doctype}`
where supplier = '{supplier}' and docstatus=1 order by modified desc limit {start}, {len}""".
@@ -159,7 +152,7 @@ def has_website_permission(doc, ptype, user, verbose=False):
doctype = doc.doctype
customers, suppliers = get_customers_suppliers(doctype, user)
if customers:
return frappe.db.exists(doctype, filters=get_customer_filter(doc, customers))
return frappe.db.exists(doctype, get_customer_filter(doc, customers))
elif suppliers:
fieldname = 'suppliers' if doctype == 'Request for Quotation' else 'supplier'
return frappe.db.exists(doctype, filters={
@@ -175,7 +168,7 @@ def get_customer_filter(doc, customers):
filters.name = doc.name
filters[get_customer_field_name(doctype)] = ['in', customers]
if doctype == 'Quotation':
filters.party_type = 'Customer'
filters.quotation_to = 'Customer'
return filters
def get_customer_field_name(doctype):

View File

@@ -1460,7 +1460,7 @@
"has_web_view": 0,
"hide_heading": 0,
"hide_toolbar": 0,
"icon": "fa fa-info-sign",
"icon": "fa fa-info-circle",
"idx": 195,
"image_view": 0,
"in_create": 0,

View File

@@ -20,6 +20,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "status",
"fieldtype": "Select",
"hidden": 1,
@@ -54,6 +55,7 @@
"collapsible": 1,
"collapsible_depends_on": "eval:doc.client_id && doc.client_secret && doc.redirect_url",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "application_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -87,6 +89,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "client_id",
"fieldtype": "Data",
"hidden": 0,
@@ -120,6 +123,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "redirect_url",
"fieldtype": "Data",
"hidden": 0,
@@ -153,6 +157,7 @@
"collapsible": 0,
"columns": 0,
"default": "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer",
"fetch_if_empty": 0,
"fieldname": "token_endpoint",
"fieldtype": "Data",
"hidden": 0,
@@ -185,6 +190,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "application_column_break",
"fieldtype": "Column Break",
"hidden": 0,
@@ -217,6 +223,7 @@
"collapsible": 0,
"columns": 0,
"default": "",
"fetch_if_empty": 0,
"fieldname": "client_secret",
"fieldtype": "Data",
"hidden": 0,
@@ -250,6 +257,7 @@
"collapsible": 0,
"columns": 0,
"default": "com.intuit.quickbooks.accounting",
"fetch_if_empty": 0,
"fieldname": "scope",
"fieldtype": "Data",
"hidden": 0,
@@ -284,6 +292,7 @@
"collapsible": 0,
"columns": 0,
"default": "https://quickbooks.api.intuit.com/v3",
"fetch_if_empty": 0,
"fieldname": "api_endpoint",
"fieldtype": "Data",
"hidden": 0,
@@ -316,6 +325,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "authorization_settings",
"fieldtype": "Section Break",
"hidden": 0,
@@ -349,6 +359,7 @@
"collapsible": 0,
"columns": 0,
"default": "https://appcenter.intuit.com/connect/oauth2",
"fetch_if_empty": 0,
"fieldname": "authorization_endpoint",
"fieldtype": "Data",
"hidden": 0,
@@ -381,6 +392,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "refresh_token",
"fieldtype": "Small Text",
"hidden": 1,
@@ -413,6 +425,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "code",
"fieldtype": "Data",
"hidden": 1,
@@ -445,6 +458,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "authorization_column_break",
"fieldtype": "Column Break",
"hidden": 0,
@@ -476,6 +490,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "authorization_url",
"fieldtype": "Data",
"hidden": 0,
@@ -508,6 +523,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "access_token",
"fieldtype": "Small Text",
"hidden": 1,
@@ -540,6 +556,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "quickbooks_company_id",
"fieldtype": "Data",
"hidden": 1,
@@ -572,6 +589,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "company_settings",
"fieldtype": "Section Break",
"hidden": 1,
@@ -604,6 +622,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "company",
"fieldtype": "Link",
"hidden": 0,
@@ -637,6 +656,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "default_shipping_account",
"fieldtype": "Link",
"hidden": 1,
@@ -670,6 +690,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "default_warehouse",
"fieldtype": "Link",
"hidden": 1,
@@ -703,6 +724,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "company_column_break",
"fieldtype": "Column Break",
"hidden": 0,
@@ -734,6 +756,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "default_cost_center",
"fieldtype": "Link",
"hidden": 1,
@@ -767,6 +790,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "undeposited_funds_account",
"fieldtype": "Link",
"hidden": 1,
@@ -804,7 +828,7 @@
"issingle": 1,
"istable": 0,
"max_attachments": 0,
"modified": "2018-10-17 03:12:53.506229",
"modified": "2019-08-07 05:53:00.920316",
"modified_by": "Administrator",
"module": "ERPNext Integrations",
"name": "QuickBooks Migrator",
@@ -834,7 +858,7 @@
"quick_entry": 1,
"read_only": 0,
"read_only_onload": 0,
"show_name_in_global_search": 1,
"show_name_in_global_search": 0,
"sort_field": "modified",
"sort_order": "DESC",
"track_changes": 0,

View File

@@ -188,8 +188,7 @@ frappe.ui.form.on("Expense Claim", {
frappe.set_route("query-report", "General Ledger");
}, __("View"));
}
if (frm.doc.docstatus===1 && !cint(frm.doc.is_paid) && cint(frm.doc.grand_total) > 0
if (frm.doc.docstatus===1 && !cint(frm.doc.is_paid)
&& (cint(frm.doc.total_amount_reimbursed) < cint(frm.doc.total_sanctioned_amount))
&& frappe.model.can_create("Payment Entry")) {
frm.add_custom_button(__('Payment'),

View File

@@ -391,7 +391,8 @@ erpnext.buying.get_items_from_product_bundle = function(frm) {
company: frm.doc.company,
is_subcontracted: frm.doc.is_subcontracted,
transaction_date: frm.doc.transaction_date || frm.doc.posting_date,
ignore_pricing_rule: frm.doc.ignore_pricing_rule
ignore_pricing_rule: frm.doc.ignore_pricing_rule,
doctype: frm.doc.doctype
}
},
freeze: true,

View File

@@ -129,6 +129,8 @@ def download_zip(files, output_filename):
def get_invoice_summary(items, taxes):
summary_data = frappe._dict()
applied_tax_row_ids = []
for tax in taxes:
#Include only VAT charges.
if tax.charge_type == "Actual":
@@ -153,7 +155,9 @@ def get_invoice_summary(items, taxes):
net_amount=reference_row.tax_amount,
taxable_amount=reference_row.tax_amount,
item_tax_rate={tax.account_head: tax.rate},
charges=True
charges=True,
type="Actual",
tax_row_name=tax.name
)
)
@@ -165,13 +169,21 @@ def get_invoice_summary(items, taxes):
item_tax_rate = json.loads(item.item_tax_rate)
if item_tax_rate and tax.account_head in item_tax_rate:
if (item.get("tax_row_name")
and item.get("tax_row_name") in applied_tax_row_ids):
continue
key = cstr(item_tax_rate[tax.account_head])
if key not in summary_data:
summary_data.setdefault(key, {"tax_amount": 0.0, "taxable_amount": 0.0,
"tax_exemption_reason": "", "tax_exemption_law": ""})
if item.get("type") and item.get("type") == "Actual":
applied_tax_row_ids.append(item.get("tax_row_name"))
summary_data[key]["tax_amount"] += item.tax_amount
summary_data[key]["taxable_amount"] += item.net_amount
if key == "0.0":
summary_data[key]["tax_exemption_reason"] = tax.tax_exemption_reason
summary_data[key]["tax_exemption_law"] = tax.tax_exemption_law

View File

@@ -3,7 +3,6 @@
from __future__ import unicode_literals
import frappe
import urllib
import copy
from frappe.utils import nowdate, cint, cstr
from frappe.utils.nestedset import NestedSet
@@ -12,6 +11,7 @@ from frappe.website.render import clear_cache
from frappe.website.doctype.website_slideshow.website_slideshow import get_slideshow
from erpnext.shopping_cart.product_info import set_product_info_for_website
from erpnext.utilities.product import get_qty_in_stock
from six.moves.urllib.parse import quote
class ItemGroup(NestedSet, WebsiteGenerator):
nsm_parent_field = 'parent_item_group'
@@ -166,7 +166,7 @@ def get_item_for_list_in_html(context):
# add missing absolute link in files
# user may forget it during upload
if (context.get("website_image") or "").startswith("files/"):
context["website_image"] = "/" + urllib.quote(context["website_image"])
context["website_image"] = "/" + quote(context["website_image"])
context["show_availability_status"] = cint(frappe.db.get_single_value('Products Settings',
'show_availability_status'))
@@ -216,4 +216,4 @@ def get_item_group_defaults(item, company):
row.pop("name")
return row
return frappe._dict()
return frappe._dict()

View File

@@ -171,7 +171,7 @@ erpnext.stock.DeliveryNoteController = erpnext.selling.SellingController.extend(
});
if(!from_sales_invoice) {
this.frm.add_custom_button(__('Invoice'), function() { me.make_sales_invoice() },
this.frm.add_custom_button(__('Sales Invoice'), function() { me.make_sales_invoice() },
__("Make"));
}
}

View File

@@ -5,8 +5,7 @@ from __future__ import unicode_literals
import frappe
from frappe import _
from frappe.utils import formatdate
from erpnext.controllers.website_list_for_contact import (get_customers_suppliers,
get_party_details)
from erpnext.controllers.website_list_for_contact import get_customers_suppliers
def get_context(context):
context.no_cache = 1
@@ -23,8 +22,8 @@ def get_supplier():
doctype = frappe.form_dict.doctype
parties_doctype = 'Request for Quotation Supplier' if doctype == 'Request for Quotation' else doctype
customers, suppliers = get_customers_suppliers(parties_doctype, frappe.session.user)
key, parties = get_party_details(customers, suppliers)
return parties[0] if key == 'supplier' else ''
return suppliers[0] if suppliers else ''
def check_supplier_has_docname_access(supplier):
status = True

View File

@@ -1,7 +1,7 @@
{%- macro render_discount_amount(doc) -%}
{%- if doc.discount_amount -%}
<div class="row">
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _(doc.meta.get_label('discount_amount')) }}</label></div>
<div class="col-xs-7 text-right">
- {{ doc.get_formatted("discount_amount", doc) }}
@@ -19,7 +19,7 @@
{%- for charge in data -%}
{%- if (charge.tax_amount or doc.flags.print_taxes_with_zero_amount) and (not charge.included_in_print_rate or doc.flags.show_inclusive_tax_in_print) -%}
<div class="row">
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ charge.get_formatted("description") }}</label></div>
<div class="col-xs-7 text-right">
{{ frappe.format_value(frappe.utils.flt(charge.tax_amount),

View File

@@ -1,12 +1,12 @@
<div class="row">
{% if doc.flags.show_inclusive_tax_in_print %}
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _("Total (Without Tax)") }}</label></div>
<div class="col-xs-7 text-right">
{{ doc.get_formatted("net_total", doc) }}
</div>
{% else %}
<div class="col-xs-5 {%- if doc._align_labels_right %} text-right{%- endif -%}">
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ _(doc.meta.get_label('total')) }}</label></div>
<div class="col-xs-7 text-right">
{{ doc.get_formatted("total", doc) }}