Merge branch 'develop'

This commit is contained in:
Nabin Hait
2015-06-12 18:06:21 +05:30
14 changed files with 86 additions and 45 deletions

View File

@@ -1,2 +1,2 @@
from __future__ import unicode_literals from __future__ import unicode_literals
__version__ = '5.0.21' __version__ = '5.0.22'

View File

@@ -4,6 +4,13 @@
"docstatus": 0, "docstatus": 0,
"doctype": "DocType", "doctype": "DocType",
"fields": [ "fields": [
{
"fieldname": "check_supplier_invoice_uniqueness",
"fieldtype": "Check",
"label": "Check Supplier Invoice Number Uniqueness",
"permlevel": 0,
"precision": ""
},
{ {
"default": "1", "default": "1",
"description": "If enabled, the system will post accounting entries for inventory automatically.", "description": "If enabled, the system will post accounting entries for inventory automatically.",
@@ -43,7 +50,7 @@
"icon": "icon-cog", "icon": "icon-cog",
"idx": 1, "idx": 1,
"issingle": 1, "issingle": 1,
"modified": "2015-02-05 05:11:34.163902", "modified": "2015-06-11 06:06:34.047890",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Accounts", "module": "Accounts",
"name": "Accounts Settings", "name": "Accounts Settings",

View File

@@ -54,7 +54,7 @@ class CForm(Document):
frappe.throw(_("Please enter atleast 1 invoice in the table")) frappe.throw(_("Please enter atleast 1 invoice in the table"))
def set_total_invoiced_amount(self): def set_total_invoiced_amount(self):
total = sum([flt(d.base_grand_total) for d in self.get('invoices')]) total = sum([flt(d.grand_total) for d in self.get('invoices')])
frappe.db.set(self, 'total_invoiced_amount', total) frappe.db.set(self, 'total_invoiced_amount', total)
def get_invoice_details(self, invoice_no): def get_invoice_details(self, invoice_no):

View File

@@ -39,6 +39,7 @@ class PurchaseInvoice(BuyingController):
self.po_required() self.po_required()
self.pr_required() self.pr_required()
self.validate_supplier_invoice()
self.check_active_purchase_items() self.check_active_purchase_items()
self.check_conversion_rate() self.check_conversion_rate()
self.validate_credit_to_acc() self.validate_credit_to_acc()
@@ -386,6 +387,16 @@ class PurchaseInvoice(BuyingController):
project.save() project.save()
project_list.append(d.project_name) project_list.append(d.project_name)
def validate_supplier_invoice(self):
if self.bill_date:
if self.bill_date > self.posting_date:
frappe.throw("Supplier Invoice Date cannot be greater than Posting Date")
if self.bill_no:
if cint(frappe.db.get_single_value("Accounts Settings", "check_supplier_invoice_uniqueness")):
pi = frappe.db.exists("Purchase Invoice", {"bill_no": self.bill_no, "fiscal_year": self.fiscal_year})
if pi:
frappe.throw("Supplier Invoice No exists in Purchase Invoice {0}".format(pi))
@frappe.whitelist() @frappe.whitelist()
def get_expense_account(doctype, txt, searchfield, start, page_len, filters): def get_expense_account(doctype, txt, searchfield, start, page_len, filters):
from erpnext.controllers.queries import get_match_cond from erpnext.controllers.queries import get_match_cond

View File

@@ -5,7 +5,7 @@ app_publisher = "Frappe Technologies Pvt. Ltd. and Contributors"
app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations" app_description = "Open Source Enterprise Resource Planning for Small and Midsized Organizations"
app_icon = "icon-th" app_icon = "icon-th"
app_color = "#e74c3c" app_color = "#e74c3c"
app_version = "5.0.21" app_version = "5.0.22"
error_report_email = "support@erpnext.com" error_report_email = "support@erpnext.com"

View File

@@ -309,10 +309,9 @@ class ProductionOrder(Document):
self.actual_end_date = None self.actual_end_date = None
def validate_delivery_date(self): def validate_delivery_date(self):
if self.docstatus==1: if self.planned_start_date and self.expected_delivery_date \
if self.planned_end_date and self.expected_delivery_date \ and getdate(self.expected_delivery_date) < getdate(self.planned_start_date):
and getdate(self.expected_delivery_date) < getdate(self.planned_end_date): frappe.throw(_("Expected Delivery Date must be greater than Planned Start Date."))
frappe.msgprint(_("Production might not be able to finish by the Expected Delivery Date."))
def delete_time_logs(self): def delete_time_logs(self):
for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}): for time_log in frappe.get_all("Time Log", ["name"], {"production_order": self.name}):

View File

@@ -0,0 +1 @@
cur_frm.add_fetch('employee', 'employee_name', 'employee_name');

View File

@@ -2,7 +2,7 @@
"allow_copy": 0, "allow_copy": 0,
"allow_import": 1, "allow_import": 1,
"allow_rename": 1, "allow_rename": 1,
"autoname": "Activity Cost - .#", "autoname": "AC-.#####",
"creation": "2015-03-23 02:00:21.861546", "creation": "2015-03-23 02:00:21.861546",
"custom": 0, "custom": 0,
"docstatus": 0, "docstatus": 0,
@@ -31,11 +31,12 @@
}, },
{ {
"fieldname": "employee_name", "fieldname": "employee_name",
"fieldtype": "Read Only", "fieldtype": "Data",
"label": "Employee Name", "label": "Employee Name",
"options": "employee.employee_name", "options": "",
"permlevel": 0, "permlevel": 0,
"precision": "" "precision": "",
"read_only": 1
}, },
{ {
"fieldname": "column_break_2", "fieldname": "column_break_2",
@@ -135,7 +136,7 @@
"is_submittable": 0, "is_submittable": 0,
"issingle": 0, "issingle": 0,
"istable": 0, "istable": 0,
"modified": "2015-04-14 02:08:33.690406", "modified": "2015-06-11 06:50:47.999788",
"modified_by": "Administrator", "modified_by": "Administrator",
"module": "Projects", "module": "Projects",
"name": "Activity Cost", "name": "Activity Cost",

View File

@@ -15,6 +15,8 @@ class ActivityCost(Document):
self.check_unique() self.check_unique()
def set_title(self): def set_title(self):
if not self.employee_name:
self.employee_name = frappe.db.get_value("Employee", self.employee, "employee_name")
self.title = _("{0} for {1}").format(self.employee_name, self.activity_type) self.title = _("{0} for {1}").format(self.employee_name, self.activity_type)
def check_unique(self): def check_unique(self):

View File

@@ -13,18 +13,24 @@ class Project(Document):
def get_feed(self): def get_feed(self):
return '{0}: {1}'.format(_(self.status), self.project_name) return '{0}: {1}'.format(_(self.status), self.project_name)
def __setup__(self): def onload(self):
"""Load project tasks for quick view""" """Load project tasks for quick view"""
self.tasks = [] if not self.get("tasks"):
for task in frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc"): for task in self.get_tasks():
self.append("tasks", { self.append("tasks", {
"title": task.subject, "title": task.subject,
"status": task.status, "status": task.status,
"start_date": task.exp_start_date, "start_date": task.exp_start_date,
"end_date": task.exp_end_date, "end_date": task.exp_end_date,
"description": task.description, "description": task.description,
"task_id": task.name "task_id": task.name
}) })
def __setup__(self):
self.onload()
def get_tasks(self):
return frappe.get_all("Task", "*", {"project": self.name}, order_by="exp_start_date asc")
def validate(self): def validate(self):
self.validate_dates() self.validate_dates()

View File

@@ -8,6 +8,13 @@ frappe.query_reports["Customers Not Buying Since Long Time"] = {
"label": __("Days Since Last Order"), "label": __("Days Since Last Order"),
"fieldtype": "Int", "fieldtype": "Int",
"default": 60 "default": 60
},
{
"fieldname":"doctype",
"label": __("Doctype"),
"fieldtype": "Select",
"default": "Sales Order",
"options": "Sales Order\nSales Invoice"
} }
] ]
} }

View File

@@ -10,41 +10,51 @@ def execute(filters=None):
if not filters: filters ={} if not filters: filters ={}
days_since_last_order = filters.get("days_since_last_order") days_since_last_order = filters.get("days_since_last_order")
doctype = filters.get("doctype")
if cint(days_since_last_order) <= 0: if cint(days_since_last_order) <= 0:
frappe.throw(_("'Days Since Last Order' must be greater than or equal to zero")) frappe.throw(_("'Days Since Last Order' must be greater than or equal to zero"))
columns = get_columns() columns = get_columns()
customers = get_so_details() customers = get_sales_details(doctype)
data = [] data = []
for cust in customers: for cust in customers:
if cint(cust[8]) >= cint(days_since_last_order): if cint(cust[8]) >= cint(days_since_last_order):
cust.insert(7,get_last_so_amt(cust[0])) cust.insert(7,get_last_sales_amt(cust[0], doctype))
data.append(cust) data.append(cust)
return columns, data return columns, data
def get_so_details(): def get_sales_details(doctype):
cond = """sum(so.base_net_total) as 'total_order_considered',
max(so.posting_date) as 'last_order_date',
DATEDIFF(CURDATE(), max(so.posting_date)) as 'days_since_last_order' """
if doctype == "Sales Order":
cond = """sum(if(so.status = "Stopped",
so.base_net_total * so.per_delivered/100,
so.base_net_total)) as 'total_order_considered',
max(so.transaction_date) as 'last_order_date',
DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order'"""
return frappe.db.sql("""select return frappe.db.sql("""select
cust.name, cust.name,
cust.customer_name, cust.customer_name,
cust.territory, cust.territory,
cust.customer_group, cust.customer_group,
count(distinct(so.name)) as 'num_of_order', count(distinct(so.name)) as 'num_of_order',
sum(base_net_total) as 'total_order_value', sum(base_net_total) as 'total_order_value', {0}
sum(if(so.status = "Stopped", from `tabCustomer` cust, `tab{1}` so
so.base_net_total * so.per_delivered/100,
so.base_net_total)) as 'total_order_considered',
max(so.transaction_date) as 'last_sales_order_date',
DATEDIFF(CURDATE(), max(so.transaction_date)) as 'days_since_last_order'
from `tabCustomer` cust, `tabSales Order` so
where cust.name = so.customer and so.docstatus = 1 where cust.name = so.customer and so.docstatus = 1
group by cust.name group by cust.name
order by 'days_since_last_order' desc """,as_list=1) order by 'days_since_last_order' desc """.format(cond, doctype), as_list=1)
def get_last_so_amt(customer): def get_last_sales_amt(customer, doctype):
res = frappe.db.sql("""select base_net_total from `tabSales Order` cond = "posting_date"
where customer = %s and docstatus = 1 order by transaction_date desc if doctype =="Sales Order":
limit 1""", customer) cond = "transaction_date"
res = frappe.db.sql("""select base_net_total from `tab{0}`
where customer = %s and docstatus = 1 order by {1} desc
limit 1""".format(doctype, cond), customer)
return res and res[0][0] or 0 return res and res[0][0] or 0
@@ -58,6 +68,6 @@ def get_columns():
_("Total Order Value") + ":Currency:120", _("Total Order Value") + ":Currency:120",
_("Total Order Considered") + ":Currency:160", _("Total Order Considered") + ":Currency:160",
_("Last Order Amount") + ":Currency:160", _("Last Order Amount") + ":Currency:160",
_("Last Sales Order Date") + ":Date:160", _("Last Order Date") + ":Date:160",
_("Days Since Last Order") + "::160" _("Days Since Last Order") + "::160"
] ]

View File

@@ -185,9 +185,6 @@ class StockEntry(StockController):
def validate_production_order(self): def validate_production_order(self):
if self.purpose in ("Manufacture", "Material Transfer for Manufacture"): if self.purpose in ("Manufacture", "Material Transfer for Manufacture"):
if not self.bom_no:
frappe.throw(_("BOM No is mandatory"))
# check if production order is entered # check if production order is entered
if not self.production_order: if not self.production_order:
frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture")) frappe.throw(_("Production order number is mandatory for stock entry purpose manufacture"))

View File

@@ -1,6 +1,6 @@
from setuptools import setup, find_packages from setuptools import setup, find_packages
version = "5.0.21" version = "5.0.22"
with open("requirements.txt", "r") as f: with open("requirements.txt", "r") as f:
install_requires = f.readlines() install_requires = f.readlines()