Merge branch 'develop' into pr-item-gl-fix
This commit is contained in:
commit
46ae97dfd3
@ -5,7 +5,7 @@ import frappe
|
|||||||
from erpnext.hooks import regional_overrides
|
from erpnext.hooks import regional_overrides
|
||||||
from frappe.utils import getdate
|
from frappe.utils import getdate
|
||||||
|
|
||||||
__version__ = '13.5.0'
|
__version__ = '13.5.1'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -7,6 +7,8 @@ cur_frm.cscript.tax_table = "Advance Taxes and Charges";
|
|||||||
|
|
||||||
frappe.ui.form.on('Payment Entry', {
|
frappe.ui.form.on('Payment Entry', {
|
||||||
onload: function(frm) {
|
onload: function(frm) {
|
||||||
|
frm.ignore_doctypes_on_cancel_all = ['Sales Invoice', 'Purchase Invoice'];
|
||||||
|
|
||||||
if(frm.doc.__islocal) {
|
if(frm.doc.__islocal) {
|
||||||
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
if (!frm.doc.paid_from) frm.set_value("paid_from_account_currency", null);
|
||||||
if (!frm.doc.paid_to) frm.set_value("paid_to_account_currency", null);
|
if (!frm.doc.paid_to) frm.set_value("paid_to_account_currency", null);
|
||||||
|
@ -26,7 +26,7 @@ class PaymentTermsTemplate(Document):
|
|||||||
def check_duplicate_terms(self):
|
def check_duplicate_terms(self):
|
||||||
terms = []
|
terms = []
|
||||||
for term in self.terms:
|
for term in self.terms:
|
||||||
term_info = (term.credit_days, term.credit_months, term.due_date_based_on)
|
term_info = (term.payment_term, term.credit_days, term.credit_months, term.due_date_based_on)
|
||||||
if term_info in terms:
|
if term_info in terms:
|
||||||
frappe.msgprint(
|
frappe.msgprint(
|
||||||
_('The Payment Term at row {0} is possibly a duplicate.').format(term.idx),
|
_('The Payment Term at row {0} is possibly a duplicate.').format(term.idx),
|
||||||
|
@ -317,19 +317,21 @@ def add_items(sq_doc, supplier, items):
|
|||||||
create_rfq_items(sq_doc, supplier, data)
|
create_rfq_items(sq_doc, supplier, data)
|
||||||
|
|
||||||
def create_rfq_items(sq_doc, supplier, data):
|
def create_rfq_items(sq_doc, supplier, data):
|
||||||
sq_doc.append('items', {
|
args = {}
|
||||||
"item_code": data.item_code,
|
|
||||||
"item_name": data.item_name,
|
for field in ['item_code', 'item_name', 'description', 'qty', 'rate', 'conversion_factor',
|
||||||
"description": data.description,
|
'warehouse', 'material_request', 'material_request_item', 'stock_qty']:
|
||||||
"qty": data.qty,
|
args[field] = data.get(field)
|
||||||
"rate": data.rate,
|
|
||||||
"conversion_factor": data.conversion_factor if data.conversion_factor else None,
|
args.update({
|
||||||
"supplier_part_no": frappe.db.get_value("Item Supplier", {'parent': data.item_code, 'supplier': supplier}, "supplier_part_no"),
|
|
||||||
"warehouse": data.warehouse or '',
|
|
||||||
"request_for_quotation_item": data.name,
|
"request_for_quotation_item": data.name,
|
||||||
"request_for_quotation": data.parent
|
"request_for_quotation": data.parent,
|
||||||
|
"supplier_part_no": frappe.db.get_value("Item Supplier",
|
||||||
|
{'parent': data.item_code, 'supplier': supplier}, "supplier_part_no")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
sq_doc.append('items', args)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_pdf(doctype, name, supplier):
|
def get_pdf(doctype, name, supplier):
|
||||||
doc = get_rfq_doc(doctype, name, supplier)
|
doc = get_rfq_doc(doctype, name, supplier)
|
||||||
|
@ -315,7 +315,7 @@ def get_project_name(doctype, txt, searchfield, start, page_len, filters):
|
|||||||
return frappe.db.sql("""select {fields} from `tabProject`
|
return frappe.db.sql("""select {fields} from `tabProject`
|
||||||
where
|
where
|
||||||
`tabProject`.status not in ("Completed", "Cancelled")
|
`tabProject`.status not in ("Completed", "Cancelled")
|
||||||
and {cond} {match_cond} {scond}
|
and {cond} {scond} {match_cond}
|
||||||
order by
|
order by
|
||||||
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
if(locate(%(_txt)s, name), locate(%(_txt)s, name), 99999),
|
||||||
idx desc,
|
idx desc,
|
||||||
|
@ -658,7 +658,13 @@ class calculate_taxes_and_totals(object):
|
|||||||
item.margin_type = None
|
item.margin_type = None
|
||||||
item.margin_rate_or_amount = 0.0
|
item.margin_rate_or_amount = 0.0
|
||||||
|
|
||||||
if item.margin_type and item.margin_rate_or_amount:
|
if not item.pricing_rules and flt(item.rate) > flt(item.price_list_rate):
|
||||||
|
item.margin_type = "Amount"
|
||||||
|
item.margin_rate_or_amount = flt(item.rate - item.price_list_rate,
|
||||||
|
item.precision("margin_rate_or_amount"))
|
||||||
|
item.rate_with_margin = item.rate
|
||||||
|
|
||||||
|
elif item.margin_type and item.margin_rate_or_amount:
|
||||||
margin_value = item.margin_rate_or_amount if item.margin_type == 'Amount' else flt(item.price_list_rate) * flt(item.margin_rate_or_amount) / 100
|
margin_value = item.margin_rate_or_amount if item.margin_type == 'Amount' else flt(item.price_list_rate) * flt(item.margin_rate_or_amount) / 100
|
||||||
rate_with_margin = flt(item.price_list_rate) + flt(margin_value)
|
rate_with_margin = flt(item.price_list_rate) + flt(margin_value)
|
||||||
base_rate_with_margin = flt(rate_with_margin) * flt(self.doc.conversion_rate)
|
base_rate_with_margin = flt(rate_with_margin) * flt(self.doc.conversion_rate)
|
||||||
|
@ -385,13 +385,16 @@ def validate_totals(einvoice):
|
|||||||
if abs(flt(value_details['AssVal']) - total_item_ass_value) > 1:
|
if abs(flt(value_details['AssVal']) - total_item_ass_value) > 1:
|
||||||
frappe.throw(_('Total Taxable Value of the items is not equal to the Invoice Net Total. Please check item taxes / discounts for any correction.'))
|
frappe.throw(_('Total Taxable Value of the items is not equal to the Invoice Net Total. Please check item taxes / discounts for any correction.'))
|
||||||
|
|
||||||
if abs(flt(value_details['TotInvVal']) + flt(value_details['Discount']) - flt(value_details['OthChrg']) - total_item_value) > 1:
|
if abs(
|
||||||
|
flt(value_details['TotInvVal']) + flt(value_details['Discount']) -
|
||||||
|
flt(value_details['OthChrg']) - flt(value_details['RndOffAmt']) -
|
||||||
|
total_item_value) > 1:
|
||||||
frappe.throw(_('Total Value of the items is not equal to the Invoice Grand Total. Please check item taxes / discounts for any correction.'))
|
frappe.throw(_('Total Value of the items is not equal to the Invoice Grand Total. Please check item taxes / discounts for any correction.'))
|
||||||
|
|
||||||
calculated_invoice_value = \
|
calculated_invoice_value = \
|
||||||
flt(value_details['AssVal']) + flt(value_details['CgstVal']) \
|
flt(value_details['AssVal']) + flt(value_details['CgstVal']) \
|
||||||
+ flt(value_details['SgstVal']) + flt(value_details['IgstVal']) \
|
+ flt(value_details['SgstVal']) + flt(value_details['IgstVal']) \
|
||||||
+ flt(value_details['OthChrg']) - flt(value_details['Discount'])
|
+ flt(value_details['OthChrg']) + flt(value_details['RndOffAmt']) - flt(value_details['Discount'])
|
||||||
|
|
||||||
if abs(flt(value_details['TotInvVal']) - calculated_invoice_value) > 1:
|
if abs(flt(value_details['TotInvVal']) - calculated_invoice_value) > 1:
|
||||||
frappe.throw(_('Total Item Value + Taxes - Discount is not equal to the Invoice Grand Total. Please check taxes / discounts for any correction.'))
|
frappe.throw(_('Total Item Value + Taxes - Discount is not equal to the Invoice Grand Total. Please check taxes / discounts for any correction.'))
|
||||||
|
@ -233,7 +233,7 @@ class SalesOrder(SellingController):
|
|||||||
# Checks Sales Invoice
|
# Checks Sales Invoice
|
||||||
submit_rv = frappe.db.sql_list("""select t1.name
|
submit_rv = frappe.db.sql_list("""select t1.name
|
||||||
from `tabSales Invoice` t1,`tabSales Invoice Item` t2
|
from `tabSales Invoice` t1,`tabSales Invoice Item` t2
|
||||||
where t1.name = t2.parent and t2.sales_order = %s and t1.docstatus = 1""",
|
where t1.name = t2.parent and t2.sales_order = %s and t1.docstatus < 2""",
|
||||||
self.name)
|
self.name)
|
||||||
|
|
||||||
if submit_rv:
|
if submit_rv:
|
||||||
|
@ -1217,6 +1217,19 @@ class TestSalesOrder(unittest.TestCase):
|
|||||||
# To test if the SO does NOT have a Blanket Order
|
# To test if the SO does NOT have a Blanket Order
|
||||||
self.assertEqual(so_doc.items[0].blanket_order, None)
|
self.assertEqual(so_doc.items[0].blanket_order, None)
|
||||||
|
|
||||||
|
def test_so_cancellation_when_si_drafted(self):
|
||||||
|
"""
|
||||||
|
Test to check if Sales Order gets cancelled if Sales Invoice is in Draft state
|
||||||
|
Expected result: sales order should not get cancelled
|
||||||
|
"""
|
||||||
|
so = make_sales_order()
|
||||||
|
so.submit()
|
||||||
|
si = make_sales_invoice(so.name)
|
||||||
|
si.save()
|
||||||
|
|
||||||
|
self.assertRaises(frappe.ValidationError, so.cancel)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def make_sales_order(**args):
|
def make_sales_order(**args):
|
||||||
so = frappe.new_doc("Sales Order")
|
so = frappe.new_doc("Sales Order")
|
||||||
|
@ -61,7 +61,8 @@ class ProductQuery:
|
|||||||
],
|
],
|
||||||
or_filters=self.or_filters,
|
or_filters=self.or_filters,
|
||||||
start=start,
|
start=start,
|
||||||
limit=self.page_length
|
limit=self.page_length,
|
||||||
|
order_by="weightage desc"
|
||||||
)
|
)
|
||||||
|
|
||||||
items_dict = {item.name: item for item in items}
|
items_dict = {item.name: item for item in items}
|
||||||
@ -71,7 +72,15 @@ class ProductQuery:
|
|||||||
|
|
||||||
result = [items_dict.get(item) for item in list(set.intersection(*all_items))]
|
result = [items_dict.get(item) for item in list(set.intersection(*all_items))]
|
||||||
else:
|
else:
|
||||||
result = frappe.get_all("Item", fields=self.fields, filters=self.filters, or_filters=self.or_filters, start=start, limit=self.page_length)
|
result = frappe.get_all(
|
||||||
|
"Item",
|
||||||
|
fields=self.fields,
|
||||||
|
filters=self.filters,
|
||||||
|
or_filters=self.or_filters,
|
||||||
|
start=start,
|
||||||
|
limit=self.page_length,
|
||||||
|
order_by="weightage desc"
|
||||||
|
)
|
||||||
|
|
||||||
for item in result:
|
for item in result:
|
||||||
product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info')
|
product_info = get_product_info_for_website(item.item_code, skip_quotation_creation=True).get('product_info')
|
||||||
|
@ -6,8 +6,8 @@ frappe.listview_settings['Delivery Note'] = {
|
|||||||
return [__("Return"), "gray", "is_return,=,Yes"];
|
return [__("Return"), "gray", "is_return,=,Yes"];
|
||||||
} else if (doc.status === "Closed") {
|
} else if (doc.status === "Closed") {
|
||||||
return [__("Closed"), "green", "status,=,Closed"];
|
return [__("Closed"), "green", "status,=,Closed"];
|
||||||
} else if (flt(doc.per_returned, 2) === 100) {
|
} else if (doc.status === "Return Issued") {
|
||||||
return [__("Return Issued"), "grey", "per_returned,=,100"];
|
return [__("Return Issued"), "grey", "status,=,Return Issued"];
|
||||||
} else if (flt(doc.per_billed, 2) < 100) {
|
} else if (flt(doc.per_billed, 2) < 100) {
|
||||||
return [__("To Bill"), "orange", "per_billed,<,100"];
|
return [__("To Bill"), "orange", "per_billed,<,100"];
|
||||||
} else if (flt(doc.per_billed, 2) === 100) {
|
} else if (flt(doc.per_billed, 2) === 100) {
|
||||||
|
@ -101,7 +101,8 @@ frappe.ui.form.on('Material Request', {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (frm.doc.docstatus == 1 && frm.doc.status != 'Stopped') {
|
if (frm.doc.docstatus == 1 && frm.doc.status != 'Stopped') {
|
||||||
if (flt(frm.doc.per_ordered, 2) < 100) {
|
let precision = frappe.defaults.get_default("float_precision");
|
||||||
|
if (flt(frm.doc.per_ordered, precision) < 100) {
|
||||||
let add_create_pick_list_button = () => {
|
let add_create_pick_list_button = () => {
|
||||||
frm.add_custom_button(__('Pick List'),
|
frm.add_custom_button(__('Pick List'),
|
||||||
() => frm.events.create_pick_list(frm), __('Create'));
|
() => frm.events.create_pick_list(frm), __('Create'));
|
||||||
|
@ -13,9 +13,11 @@
|
|||||||
{{ doc.items_preview }}
|
{{ doc.items_preview }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% if doc.get('grand_total') %}
|
||||||
<div class="col-sm-3 text-right bold">
|
<div class="col-sm-3 text-right bold">
|
||||||
{{ doc.get_formatted("grand_total") }}
|
{{ doc.get_formatted("grand_total") }}
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<a class="transaction-item-link" href="/{{ pathname }}/{{ doc.name }}">Link</a>
|
<a class="transaction-item-link" href="/{{ pathname }}/{{ doc.name }}">Link</a>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user