mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-18 12:39:18 +00:00
Merge branch 'develop' into contacts-ref
This commit is contained in:
@@ -206,9 +206,9 @@ class SalesInvoice(SellingController):
|
|||||||
total_amount_in_payments = 0
|
total_amount_in_payments = 0
|
||||||
for payment in self.payments:
|
for payment in self.payments:
|
||||||
total_amount_in_payments += payment.amount
|
total_amount_in_payments += payment.amount
|
||||||
|
invoice_total = self.rounded_total or self.grand_total
|
||||||
if total_amount_in_payments < self.rounded_total:
|
if total_amount_in_payments < invoice_total:
|
||||||
frappe.throw(_("Total payments amount can't be greater than {}".format(-self.rounded_total)))
|
frappe.throw(_("Total payments amount can't be greater than {}".format(-invoice_total)))
|
||||||
|
|
||||||
def validate_pos_paid_amount(self):
|
def validate_pos_paid_amount(self):
|
||||||
if len(self.payments) == 0 and self.is_pos:
|
if len(self.payments) == 0 and self.is_pos:
|
||||||
@@ -1510,4 +1510,4 @@ def create_invoice_discounting(source_name, target_doc=None):
|
|||||||
"outstanding_amount": invoice.outstanding_amount
|
"outstanding_amount": invoice.outstanding_amount
|
||||||
})
|
})
|
||||||
|
|
||||||
return invoice_discounting
|
return invoice_discounting
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class SellingController(StockController):
|
|||||||
self.set_gross_profit()
|
self.set_gross_profit()
|
||||||
set_default_income_account_for_item(self)
|
set_default_income_account_for_item(self)
|
||||||
self.set_customer_address()
|
self.set_customer_address()
|
||||||
|
self.validate_for_duplicate_items()
|
||||||
|
|
||||||
def set_missing_values(self, for_validate=False):
|
def set_missing_values(self, for_validate=False):
|
||||||
|
|
||||||
@@ -381,6 +382,34 @@ class SellingController(StockController):
|
|||||||
if self.get(address_field):
|
if self.get(address_field):
|
||||||
self.set(address_display_field, get_address_display(self.get(address_field)))
|
self.set(address_display_field, get_address_display(self.get(address_field)))
|
||||||
|
|
||||||
|
def validate_for_duplicate_items(self):
|
||||||
|
check_list, chk_dupl_itm = [], []
|
||||||
|
if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
||||||
|
return
|
||||||
|
|
||||||
|
for d in self.get('items'):
|
||||||
|
if self.doctype == "Sales Invoice":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.sales_order or d.delivery_note, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description, d.sales_order or d.delivery_note]
|
||||||
|
elif self.doctype == "Delivery Note":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
|
||||||
|
elif self.doctype == "Sales Order":
|
||||||
|
e = [d.item_code, d.description, d.warehouse, d.batch_no or '']
|
||||||
|
f = [d.item_code, d.description]
|
||||||
|
|
||||||
|
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
|
||||||
|
if e in check_list:
|
||||||
|
frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
|
||||||
|
else:
|
||||||
|
check_list.append(e)
|
||||||
|
else:
|
||||||
|
if f in chk_dupl_itm:
|
||||||
|
frappe.throw(_("Note: Item {0} entered multiple times").format(d.item_code))
|
||||||
|
else:
|
||||||
|
chk_dupl_itm.append(f)
|
||||||
|
|
||||||
|
|
||||||
def validate_items(self):
|
def validate_items(self):
|
||||||
# validate items to see if they have is_sales_item enabled
|
# validate items to see if they have is_sales_item enabled
|
||||||
from erpnext.controllers.buying_controller import validate_item_type
|
from erpnext.controllers.buying_controller import validate_item_type
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ frappe.listview_settings['Leave Application'] = {
|
|||||||
return [__("Approved"), "green", "status,=,Approved"];
|
return [__("Approved"), "green", "status,=,Approved"];
|
||||||
} else if (doc.status === "Rejected") {
|
} else if (doc.status === "Rejected") {
|
||||||
return [__("Rejected"), "red", "status,=,Rejected"];
|
return [__("Rejected"), "red", "status,=,Rejected"];
|
||||||
|
} else {
|
||||||
|
return [__("Open"), "red", "status,=,Open"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,8 @@ def get_columns():
|
|||||||
_("Model") + ":data:50", _("Location") + ":data:100",
|
_("Model") + ":data:50", _("Location") + ":data:100",
|
||||||
_("Log") + ":Link/Vehicle Log:100", _("Odometer") + ":Int:80",
|
_("Log") + ":Link/Vehicle Log:100", _("Odometer") + ":Int:80",
|
||||||
_("Date") + ":Date:100", _("Fuel Qty") + ":Float:80",
|
_("Date") + ":Date:100", _("Fuel Qty") + ":Float:80",
|
||||||
_("Fuel Price") + ":Float:100",_("Service Expense") + ":Float:100"
|
_("Fuel Price") + ":Float:100",_("Fuel Expense") + ":Float:100",
|
||||||
|
_("Service Expense") + ":Float:100"
|
||||||
]
|
]
|
||||||
return columns
|
return columns
|
||||||
|
|
||||||
@@ -32,7 +33,8 @@ def get_log_data(filters):
|
|||||||
data = frappe.db.sql("""select
|
data = frappe.db.sql("""select
|
||||||
vhcl.license_plate as "License", vhcl.make as "Make", vhcl.model as "Model",
|
vhcl.license_plate as "License", vhcl.make as "Make", vhcl.model as "Model",
|
||||||
vhcl.location as "Location", log.name as "Log", log.odometer as "Odometer",
|
vhcl.location as "Location", log.name as "Log", log.odometer as "Odometer",
|
||||||
log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price"
|
log.date as "Date", log.fuel_qty as "Fuel Qty", log.price as "Fuel Price",
|
||||||
|
log.fuel_qty * log.price as "Fuel Expense"
|
||||||
from
|
from
|
||||||
`tabVehicle` vhcl,`tabVehicle Log` log
|
`tabVehicle` vhcl,`tabVehicle Log` log
|
||||||
where
|
where
|
||||||
@@ -58,7 +60,7 @@ def get_chart_data(data,period_list):
|
|||||||
total_ser_exp=0
|
total_ser_exp=0
|
||||||
for row in data:
|
for row in data:
|
||||||
if row["Date"] <= period.to_date and row["Date"] >= period.from_date:
|
if row["Date"] <= period.to_date and row["Date"] >= period.from_date:
|
||||||
total_fuel_exp+=flt(row["Fuel Price"])
|
total_fuel_exp+=flt(row["Fuel Expense"])
|
||||||
total_ser_exp+=flt(row["Service Expense"])
|
total_ser_exp+=flt(row["Service Expense"])
|
||||||
fueldata.append([period.key,total_fuel_exp])
|
fueldata.append([period.key,total_fuel_exp])
|
||||||
servicedata.append([period.key,total_ser_exp])
|
servicedata.append([period.key,total_ser_exp])
|
||||||
@@ -84,4 +86,4 @@ def get_chart_data(data,period_list):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
chart["type"] = "line"
|
chart["type"] = "line"
|
||||||
return chart
|
return chart
|
||||||
|
|||||||
@@ -72,9 +72,7 @@ class SalesOrder(SellingController):
|
|||||||
frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
|
frappe.msgprint(_("Warning: Sales Order {0} already exists against Customer's Purchase Order {1}").format(so[0][0], self.po_no))
|
||||||
|
|
||||||
def validate_for_items(self):
|
def validate_for_items(self):
|
||||||
check_list = []
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
check_list.append(cstr(d.item_code))
|
|
||||||
|
|
||||||
# used for production plan
|
# used for production plan
|
||||||
d.transaction_date = self.transaction_date
|
d.transaction_date = self.transaction_date
|
||||||
@@ -83,13 +81,6 @@ class SalesOrder(SellingController):
|
|||||||
where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
|
where item_code = %s and warehouse = %s", (d.item_code, d.warehouse))
|
||||||
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
d.projected_qty = tot_avail_qty and flt(tot_avail_qty[0][0]) or 0
|
||||||
|
|
||||||
# check for same entry multiple times
|
|
||||||
unique_chk_list = set(check_list)
|
|
||||||
if len(unique_chk_list) != len(check_list) and \
|
|
||||||
not cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
|
||||||
frappe.msgprint(_("Same item has been entered multiple times"),
|
|
||||||
title=_("Warning"), indicator='orange')
|
|
||||||
|
|
||||||
def product_bundle_has_stock_item(self, product_bundle):
|
def product_bundle_has_stock_item(self, product_bundle):
|
||||||
"""Returns true if product bundle has stock item"""
|
"""Returns true if product bundle has stock item"""
|
||||||
ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
|
ret = len(frappe.db.sql("""select i.name from tabItem i, `tabProduct Bundle Item` pbi
|
||||||
|
|||||||
@@ -166,24 +166,7 @@ class DeliveryNote(SellingController):
|
|||||||
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
|
frappe.throw(_("Customer {0} does not belong to project {1}").format(self.customer, self.project))
|
||||||
|
|
||||||
def validate_for_items(self):
|
def validate_for_items(self):
|
||||||
check_list, chk_dupl_itm = [], []
|
|
||||||
if cint(frappe.db.get_single_value("Selling Settings", "allow_multiple_items")):
|
|
||||||
return
|
|
||||||
|
|
||||||
for d in self.get('items'):
|
for d in self.get('items'):
|
||||||
e = [d.item_code, d.description, d.warehouse, d.against_sales_order or d.against_sales_invoice, d.batch_no or '']
|
|
||||||
f = [d.item_code, d.description, d.against_sales_order or d.against_sales_invoice]
|
|
||||||
|
|
||||||
if frappe.db.get_value("Item", d.item_code, "is_stock_item") == 1:
|
|
||||||
if e in check_list:
|
|
||||||
frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
|
|
||||||
else:
|
|
||||||
check_list.append(e)
|
|
||||||
else:
|
|
||||||
if f in chk_dupl_itm:
|
|
||||||
frappe.msgprint(_("Note: Item {0} entered multiple times").format(d.item_code))
|
|
||||||
else:
|
|
||||||
chk_dupl_itm.append(f)
|
|
||||||
#Customer Provided parts will have zero valuation rate
|
#Customer Provided parts will have zero valuation rate
|
||||||
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
if frappe.db.get_value('Item', d.item_code, 'is_customer_provided_item'):
|
||||||
d.allow_zero_valuation_rate = 1
|
d.allow_zero_valuation_rate = 1
|
||||||
|
|||||||
Reference in New Issue
Block a user