Merge branch 'hotfix'
This commit is contained in:
commit
95e13ea629
@ -4,7 +4,7 @@ import inspect
|
|||||||
import frappe
|
import frappe
|
||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
|
|
||||||
__version__ = '8.9.1'
|
__version__ = '8.9.2'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -569,7 +569,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
})
|
})
|
||||||
|
|
||||||
var allocated_negative_outstanding = 0;
|
var allocated_negative_outstanding = 0;
|
||||||
if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
|
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
|
||||||
if(total_positive_outstanding_including_order > paid_amount) {
|
if(total_positive_outstanding_including_order > paid_amount) {
|
||||||
@ -579,7 +579,7 @@ frappe.ui.form.on('Payment Entry', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
||||||
} else {
|
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||||
if(paid_amount > total_negative_outstanding) {
|
if(paid_amount > total_negative_outstanding) {
|
||||||
if(total_negative_outstanding == 0) {
|
if(total_negative_outstanding == 0) {
|
||||||
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
|
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
|
||||||
@ -14,10 +14,12 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
columns = get_columns(additional_table_columns)
|
columns = get_columns(additional_table_columns)
|
||||||
|
|
||||||
|
company_currency = erpnext.get_company_currency(filters.company)
|
||||||
|
|
||||||
item_list = get_items(filters, additional_query_columns)
|
item_list = get_items(filters, additional_query_columns)
|
||||||
aii_account_map = get_aii_accounts()
|
aii_account_map = get_aii_accounts()
|
||||||
if item_list:
|
if item_list:
|
||||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns,
|
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
|
||||||
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
|
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
|
||||||
|
|
||||||
columns.append({
|
columns.append({
|
||||||
@ -26,7 +28,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"width": 80
|
"width": 80
|
||||||
})
|
})
|
||||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
|
||||||
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
|
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
@ -2,9 +2,10 @@
|
|||||||
# License: GNU General Public License v3. See license.txt
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe, erpnext
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import flt
|
from frappe.utils import flt
|
||||||
|
from frappe.model.meta import get_field_precision
|
||||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
@ -14,16 +15,17 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
|||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
columns = get_columns(additional_table_columns)
|
columns = get_columns(additional_table_columns)
|
||||||
|
|
||||||
|
company_currency = erpnext.get_company_currency(filters.company)
|
||||||
|
|
||||||
item_list = get_items(filters, additional_query_columns)
|
item_list = get_items(filters, additional_query_columns)
|
||||||
if item_list:
|
if item_list:
|
||||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns)
|
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
|
||||||
columns.append({
|
columns.append({
|
||||||
"fieldname": "currency",
|
"fieldname": "currency",
|
||||||
"label": _("Currency"),
|
"label": _("Currency"),
|
||||||
"fieldtype": "Data",
|
"fieldtype": "Data",
|
||||||
"width": 80
|
"width": 80
|
||||||
})
|
})
|
||||||
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]))
|
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)
|
so_dn_map = get_delivery_notes_against_sales_order(item_list)
|
||||||
|
|
||||||
@ -140,16 +142,25 @@ def get_delivery_notes_against_sales_order(item_list):
|
|||||||
|
|
||||||
return so_dn_map
|
return so_dn_map
|
||||||
|
|
||||||
def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
def get_tax_accounts(item_list, columns, company_currency,
|
||||||
|
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||||
import json
|
import json
|
||||||
item_row_map = {}
|
item_row_map = {}
|
||||||
tax_columns = []
|
tax_columns = []
|
||||||
invoice_item_row = {}
|
invoice_item_row = {}
|
||||||
itemised_tax = {}
|
itemised_tax = {}
|
||||||
|
|
||||||
|
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
|
||||||
|
currency=company_currency) or 2
|
||||||
|
|
||||||
for d in item_list:
|
for d in item_list:
|
||||||
invoice_item_row.setdefault(d.parent, []).append(d)
|
invoice_item_row.setdefault(d.parent, []).append(d)
|
||||||
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
||||||
|
|
||||||
|
conditions = ""
|
||||||
|
if doctype == "Purchase Invoice":
|
||||||
|
conditions = " and category in ('Total', 'Valuation and Total')"
|
||||||
|
|
||||||
tax_details = frappe.db.sql("""
|
tax_details = frappe.db.sql("""
|
||||||
select
|
select
|
||||||
parent, description, item_wise_tax_detail,
|
parent, description, item_wise_tax_detail,
|
||||||
@ -159,8 +170,9 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
|||||||
parenttype = %s and docstatus = 1
|
parenttype = %s and docstatus = 1
|
||||||
and (description is not null and description != '')
|
and (description is not null and description != '')
|
||||||
and parent in (%s)
|
and parent in (%s)
|
||||||
|
%s
|
||||||
order by description
|
order by description
|
||||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row))),
|
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||||
tuple([doctype] + invoice_item_row.keys()))
|
tuple([doctype] + invoice_item_row.keys()))
|
||||||
|
|
||||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||||
@ -192,7 +204,7 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
|||||||
if item_tax_amount:
|
if item_tax_amount:
|
||||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||||
"tax_rate": tax_rate,
|
"tax_rate": tax_rate,
|
||||||
"tax_amount": item_tax_amount
|
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||||
})
|
})
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@ -201,7 +213,8 @@ def get_tax_accounts(item_list, columns, doctype="Sales Invoice", tax_doctype="S
|
|||||||
for d in invoice_item_row.get(parent, []):
|
for d in invoice_item_row.get(parent, []):
|
||||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||||
"tax_rate": "NA",
|
"tax_rate": "NA",
|
||||||
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total)
|
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
|
||||||
|
tax_amount_precision)
|
||||||
})
|
})
|
||||||
|
|
||||||
tax_columns.sort()
|
tax_columns.sort()
|
||||||
|
@ -232,7 +232,7 @@ def get_delivery_notes_to_be_billed(doctype, txt, searchfield, start, page_len,
|
|||||||
select `tabDelivery Note`.name, `tabDelivery Note`.customer, `tabDelivery Note`.posting_date
|
select `tabDelivery Note`.name, `tabDelivery Note`.customer, `tabDelivery Note`.posting_date
|
||||||
from `tabDelivery Note`
|
from `tabDelivery Note`
|
||||||
where `tabDelivery Note`.`%(key)s` like %(txt)s and
|
where `tabDelivery Note`.`%(key)s` like %(txt)s and
|
||||||
`tabDelivery Note`.docstatus = 1 and `tabDelivery Note`.is_return = 0
|
`tabDelivery Note`.docstatus = 1 and `tabDelivery Note`.is_return = 0
|
||||||
and status not in ("Stopped", "Closed") %(fcond)s
|
and status not in ("Stopped", "Closed") %(fcond)s
|
||||||
and (`tabDelivery Note`.per_billed < 100 or `tabDelivery Note`.grand_total = 0)
|
and (`tabDelivery Note`.per_billed < 100 or `tabDelivery Note`.grand_total = 0)
|
||||||
%(mcond)s order by `tabDelivery Note`.`%(key)s` asc
|
%(mcond)s order by `tabDelivery Note`.`%(key)s` asc
|
||||||
@ -367,31 +367,30 @@ def warehouse_query(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
|
sub_query = """ select round(`tabBin`.actual_qty, 2) from `tabBin`
|
||||||
where `tabBin`.warehouse = `tabWarehouse`.name
|
where `tabBin`.warehouse = `tabWarehouse`.name
|
||||||
{bin_conditions} """.format(
|
{bin_conditions} """.format(
|
||||||
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),
|
bin_conditions=get_filters_cond(doctype, filter_dict.get("Bin"),
|
||||||
bin_conditions, ignore_permissions=True))
|
bin_conditions, ignore_permissions=True))
|
||||||
|
|
||||||
response = frappe.db.sql("""select `tabWarehouse`.name,
|
query = """select `tabWarehouse`.name,
|
||||||
CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty
|
CONCAT_WS(" : ", "Actual Qty", ifnull( ({sub_query}), 0) ) as actual_qty
|
||||||
from `tabWarehouse`
|
from `tabWarehouse`
|
||||||
where
|
where
|
||||||
`tabWarehouse`.`{key}` like %(txt)s
|
`tabWarehouse`.`{key}` like '{txt}'
|
||||||
{fcond} {mcond}
|
{fcond} {mcond}
|
||||||
order by
|
order by
|
||||||
`tabWarehouse`.name desc
|
`tabWarehouse`.name desc
|
||||||
limit
|
limit
|
||||||
%(start)s, %(page_len)s
|
{start}, {page_len}
|
||||||
""".format(
|
""".format(
|
||||||
sub_query=sub_query,
|
sub_query=sub_query,
|
||||||
key=frappe.db.escape(searchfield),
|
key=frappe.db.escape(searchfield),
|
||||||
fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
|
fcond=get_filters_cond(doctype, filter_dict.get("Warehouse"), conditions),
|
||||||
mcond=get_match_cond(doctype)
|
mcond=get_match_cond(doctype),
|
||||||
),
|
start=start,
|
||||||
{
|
page_len=page_len,
|
||||||
"txt": "%%%s%%" % frappe.db.escape(txt),
|
txt=frappe.db.escape('%{0}%'.format(txt))
|
||||||
"start": start,
|
)
|
||||||
"page_len": page_len
|
|
||||||
})
|
return frappe.db.sql(query)
|
||||||
return response
|
|
||||||
|
|
||||||
|
|
||||||
def get_doctype_wise_filters(filters):
|
def get_doctype_wise_filters(filters):
|
||||||
|
@ -270,7 +270,7 @@ class calculate_taxes_and_totals(object):
|
|||||||
if tax.item_wise_tax_detail.get(key):
|
if tax.item_wise_tax_detail.get(key):
|
||||||
item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
|
item_wise_tax_amount += tax.item_wise_tax_detail[key][1]
|
||||||
|
|
||||||
tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount, tax.precision("base_tax_amount"))]
|
tax.item_wise_tax_detail[key] = [tax_rate,flt(item_wise_tax_amount)]
|
||||||
|
|
||||||
def round_off_totals(self, tax):
|
def round_off_totals(self, tax):
|
||||||
tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount"))
|
tax.tax_amount = flt(tax.tax_amount, tax.precision("tax_amount"))
|
||||||
@ -521,12 +521,20 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
frappe.flags.company = doc.company
|
frappe.flags.company = doc.company
|
||||||
|
|
||||||
# get headers
|
# get headers
|
||||||
tax_accounts = list(set([d.description for d in doc.taxes]))
|
tax_accounts = []
|
||||||
|
for tax in doc.taxes:
|
||||||
|
if getattr(tax, "category", None) and tax.category=="Valuation":
|
||||||
|
continue
|
||||||
|
if tax.description not in tax_accounts:
|
||||||
|
tax_accounts.append(tax.description)
|
||||||
|
|
||||||
headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
|
headers = get_itemised_tax_breakup_header(doc.doctype + " Item", tax_accounts)
|
||||||
|
|
||||||
# get tax breakup data
|
# get tax breakup data
|
||||||
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc)
|
itemised_tax, itemised_taxable_amount = get_itemised_tax_breakup_data(doc)
|
||||||
|
|
||||||
|
get_rounded_tax_amount(itemised_tax, doc.precision("tax_amount", "taxes"))
|
||||||
|
|
||||||
frappe.flags.company = None
|
frappe.flags.company = None
|
||||||
|
|
||||||
return frappe.render_template(
|
return frappe.render_template(
|
||||||
@ -554,6 +562,9 @@ def get_itemised_tax_breakup_data(doc):
|
|||||||
def get_itemised_tax(taxes):
|
def get_itemised_tax(taxes):
|
||||||
itemised_tax = {}
|
itemised_tax = {}
|
||||||
for tax in taxes:
|
for tax in taxes:
|
||||||
|
if getattr(tax, "category", None) and tax.category=="Valuation":
|
||||||
|
continue
|
||||||
|
|
||||||
tax_amount_precision = tax.precision("tax_amount")
|
tax_amount_precision = tax.precision("tax_amount")
|
||||||
tax_rate_precision = tax.precision("rate")
|
tax_rate_precision = tax.precision("rate")
|
||||||
|
|
||||||
@ -562,16 +573,16 @@ def get_itemised_tax(taxes):
|
|||||||
for item_code, tax_data in item_tax_map.items():
|
for item_code, tax_data in item_tax_map.items():
|
||||||
itemised_tax.setdefault(item_code, frappe._dict())
|
itemised_tax.setdefault(item_code, frappe._dict())
|
||||||
|
|
||||||
if isinstance(tax_data, list) and tax_data[0]:
|
if isinstance(tax_data, list):
|
||||||
precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision
|
precision = tax_amount_precision if tax.charge_type == "Actual" else tax_rate_precision
|
||||||
|
|
||||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||||
tax_rate=flt(tax_data[0], precision),
|
tax_rate=flt(tax_data[0]),
|
||||||
tax_amount=flt(tax_data[1], tax_amount_precision)
|
tax_amount=flt(tax_data[1])
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
itemised_tax[item_code][tax.description] = frappe._dict(dict(
|
||||||
tax_rate=flt(tax_data, tax_rate_precision),
|
tax_rate=flt(tax_data),
|
||||||
tax_amount=0.0
|
tax_amount=0.0
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -584,4 +595,10 @@ def get_itemised_taxable_amount(items):
|
|||||||
itemised_taxable_amount.setdefault(item_code, 0)
|
itemised_taxable_amount.setdefault(item_code, 0)
|
||||||
itemised_taxable_amount[item_code] += item.net_amount
|
itemised_taxable_amount[item_code] += item.net_amount
|
||||||
|
|
||||||
return itemised_taxable_amount
|
return itemised_taxable_amount
|
||||||
|
|
||||||
|
def get_rounded_tax_amount(itemised_tax, precision):
|
||||||
|
# Rounding based on tax_amount precision
|
||||||
|
for taxes in itemised_tax.values():
|
||||||
|
for tax_account in taxes:
|
||||||
|
taxes[tax_account]["tax_amount"] = flt(taxes[tax_account]["tax_amount"], precision)
|
@ -432,4 +432,5 @@ erpnext.patches.v8_5.update_customer_group_in_POS_profile
|
|||||||
erpnext.patches.v8_6.update_timesheet_company_from_PO
|
erpnext.patches.v8_6.update_timesheet_company_from_PO
|
||||||
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
|
erpnext.patches.v8_6.set_write_permission_for_quotation_for_sales_manager
|
||||||
erpnext.patches.v8_5.remove_project_type_property_setter
|
erpnext.patches.v8_5.remove_project_type_property_setter
|
||||||
erpnext.patches.v8_7.add_more_gst_fields
|
erpnext.patches.v8_7.add_more_gst_fields
|
||||||
|
erpnext.patches.v8_7.fix_purchase_receipt_status
|
12
erpnext/patches/v8_7/fix_purchase_receipt_status.py
Normal file
12
erpnext/patches/v8_7/fix_purchase_receipt_status.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
# there is no more status called "Submitted", there was an old issue that used
|
||||||
|
# to set it as Submitted, fixed in this commit
|
||||||
|
frappe.db.sql("""
|
||||||
|
update
|
||||||
|
`tabPurchase Receipt`
|
||||||
|
set
|
||||||
|
status = 'To Bill'
|
||||||
|
where
|
||||||
|
status = 'Submitted'""")
|
@ -115,9 +115,6 @@ class PurchaseReceipt(BuyingController):
|
|||||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||||
self.company, self.base_grand_total)
|
self.company, self.base_grand_total)
|
||||||
|
|
||||||
# Set status as Submitted
|
|
||||||
frappe.db.set(self, 'status', 'Submitted')
|
|
||||||
|
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
if self.per_billed < 100:
|
if self.per_billed < 100:
|
||||||
self.update_billing_status()
|
self.update_billing_status()
|
||||||
@ -152,8 +149,6 @@ class PurchaseReceipt(BuyingController):
|
|||||||
if submitted:
|
if submitted:
|
||||||
frappe.throw(_("Purchase Invoice {0} is already submitted").format(submitted[0][0]))
|
frappe.throw(_("Purchase Invoice {0} is already submitted").format(submitted[0][0]))
|
||||||
|
|
||||||
frappe.db.set(self,'status','Cancelled')
|
|
||||||
|
|
||||||
self.update_prevdoc_status()
|
self.update_prevdoc_status()
|
||||||
self.update_billing_status()
|
self.update_billing_status()
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
{% set tax_details = taxes.get(tax_account) %}
|
{% set tax_details = taxes.get(tax_account) %}
|
||||||
{% if tax_details %}
|
{% if tax_details %}
|
||||||
<td class='text-right'>
|
<td class='text-right'>
|
||||||
({{ tax_details.tax_rate }})
|
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
||||||
|
({{ tax_details.tax_rate }})
|
||||||
|
{% endif %}
|
||||||
{{ frappe.utils.fmt_money(tax_details.tax_amount, None, company_currency) }}
|
{{ frappe.utils.fmt_money(tax_details.tax_amount, None, company_currency) }}
|
||||||
</td>
|
</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user