Merge remote-tracking branch 'frappe/develop' into enlarge-item-image-website
diff --git a/erpnext/__init__.py b/erpnext/__init__.py
index 5b26c08..c6a8ea1 100644
--- a/erpnext/__init__.py
+++ b/erpnext/__init__.py
@@ -2,7 +2,7 @@
from __future__ import unicode_literals
import frappe
-__version__ = '7.2.3'
+__version__ = '7.2.6'
def get_default_company(user=None):
'''Get default company for user'''
diff --git a/erpnext/accounts/doctype/budget_account/budget_account.json b/erpnext/accounts/doctype/budget_account/budget_account.json
index 58bb90e..172e092 100644
--- a/erpnext/accounts/doctype/budget_account/budget_account.json
+++ b/erpnext/accounts/doctype/budget_account/budget_account.json
@@ -9,11 +9,13 @@
"doctype": "DocType",
"document_type": "",
"editable_grid": 1,
+ "engine": "InnoDB",
"fields": [
{
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "account",
"fieldtype": "Link",
"hidden": 0,
@@ -30,6 +32,7 @@
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -40,6 +43,7 @@
"allow_on_submit": 0,
"bold": 0,
"collapsible": 0,
+ "columns": 0,
"fieldname": "budget_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -50,11 +54,13 @@
"label": "Budget Amount",
"length": 0,
"no_copy": 0,
+ "options": "Company:company:default_currency",
"permlevel": 0,
"precision": "",
"print_hide": 0,
"print_hide_if_no_value": 0,
"read_only": 0,
+ "remember_last_selected_value": 0,
"report_hide": 0,
"reqd": 1,
"search_index": 0,
@@ -72,7 +78,7 @@
"issingle": 0,
"istable": 1,
"max_attachments": 0,
- "modified": "2016-07-11 03:27:58.705376",
+ "modified": "2017-01-02 17:02:53.339420",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Budget Account",
diff --git a/erpnext/accounts/doctype/journal_entry/journal_entry.py b/erpnext/accounts/doctype/journal_entry/journal_entry.py
index cd79363..b31a304 100644
--- a/erpnext/accounts/doctype/journal_entry/journal_entry.py
+++ b/erpnext/accounts/doctype/journal_entry/journal_entry.py
@@ -326,10 +326,12 @@
if d.account_currency == self.company_currency:
d.exchange_rate = 1
elif not d.exchange_rate or d.exchange_rate == 1 or \
- (d.reference_type in ("Sales Invoice", "Purchase Invoice") and d.reference_name and d.posting_date):
+ (d.reference_type in ("Sales Invoice", "Purchase Invoice")
+ and d.reference_name and self.posting_date):
+
# Modified to include the posting date for which to retreive the exchange rate
- d.exchange_rate = get_exchange_rate(self.posting_date, d.account, d.account_currency, self.company,
- d.reference_type, d.reference_name, d.debit, d.credit, d.exchange_rate)
+ d.exchange_rate = get_exchange_rate(self.posting_date, d.account, d.account_currency,
+ self.company, d.reference_type, d.reference_name, d.debit, d.credit, d.exchange_rate)
if not d.exchange_rate:
frappe.throw(_("Row {0}: Exchange Rate is mandatory").format(d.idx))
@@ -651,7 +653,8 @@
if args.get("party_account"):
# Modified to include the posting date for which the exchange rate is required.
# Assumed to be the posting date in the reference document
- exchange_rate = get_exchange_rate(ref_doc.posting_date, args.get("party_account"), args.get("party_account_currency"),
+ exchange_rate = get_exchange_rate(ref_doc.get("posting_date") or ref_doc.get("transaction_date"),
+ args.get("party_account"), args.get("party_account_currency"),
ref_doc.company, ref_doc.doctype, ref_doc.name)
je = frappe.new_doc("Journal Entry")
@@ -686,7 +689,8 @@
bank_row.update(bank_account)
# Modified to include the posting date for which the exchange rate is required.
# Assumed to be the posting date of the reference date
- bank_row.exchange_rate = get_exchange_rate(ref_doc.posting_date, bank_account["account"],
+ bank_row.exchange_rate = get_exchange_rate(ref_doc.get("posting_date")
+ or ref_doc.get("transaction_date"), bank_account["account"],
bank_account["account_currency"], ref_doc.company)
bank_row.cost_center = cost_center
diff --git a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
index 9928227..3c62297 100644
--- a/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
+++ b/erpnext/accounts/doctype/pricing_rule/pricing_rule.py
@@ -109,12 +109,16 @@
item_list = args.get("items")
args.pop("items")
+
+ set_serial_nos_based_on_fifo = frappe.db.get_single_value("Stock Settings",
+ "automatically_set_serial_nos_based_on_fifo")
for item in item_list:
args_copy = copy.deepcopy(args)
args_copy.update(item)
out.append(get_pricing_rule_for_item(args_copy))
- out.append(get_serial_no_for_item(args_copy))
+ if set_serial_nos_based_on_fifo:
+ out.append(get_serial_no_for_item(args_copy))
return out
def get_serial_no_for_item(args):
diff --git a/erpnext/hr/doctype/leave_application/leave_application.py b/erpnext/hr/doctype/leave_application/leave_application.py
index 5c836df..fbf86e1 100755
--- a/erpnext/hr/doctype/leave_application/leave_application.py
+++ b/erpnext/hr/doctype/leave_application/leave_application.py
@@ -217,7 +217,7 @@
def validate_attendance(self):
attendance = frappe.db.sql("""select name from `tabAttendance` where employee = %s and (att_date between %s and %s)
- and docstatus = 1""",
+ and status = "Present" and docstatus = 1""",
(self.employee, self.from_date, self.to_date))
if attendance:
frappe.throw(_("Attendance for employee {0} is already marked for this day").format(self.employee),
diff --git a/erpnext/hr/doctype/process_payroll/process_payroll.py b/erpnext/hr/doctype/process_payroll/process_payroll.py
index 45030cb..e2f7ca2 100644
--- a/erpnext/hr/doctype/process_payroll/process_payroll.py
+++ b/erpnext/hr/doctype/process_payroll/process_payroll.py
@@ -3,7 +3,7 @@
from __future__ import unicode_literals
import frappe
-from frappe.utils import cint, flt, nowdate, add_days, getdate
+from frappe.utils import cint, flt, nowdate, add_days, getdate, fmt_money
from frappe import _
from erpnext.accounts.utils import get_fiscal_year
@@ -103,17 +103,23 @@
"posting_date": self.posting_date
})
ss.insert()
- ss_list.append(ss.name)
+ ss_dict = {}
+ ss_dict["Employee Name"] = ss.employee_name
+ ss_dict["Total Pay"] = fmt_money(ss.rounded_total,currency = frappe.defaults.get_global_default("currency"))
+ ss_dict["Salary Slip"] = self.format_as_links(ss.name)[0]
+ ss_list.append(ss_dict)
return self.create_log(ss_list)
def create_log(self, ss_list):
- log = "<p>" + _("No employee for the above selected criteria OR salary slip already created") + "</p>"
- if ss_list:
- log = "<b>" + _("Salary Slip Created") + "</b>\
- <br><br>%s" % '<br>'.join(self.format_as_links(ss_list))
- return log
-
+ if not ss_list:
+ log = "<p>" + _("No employee for the above selected criteria OR salary slip already created") + "</p>"
+ else:
+ log = frappe.render_template("templates/includes/salary_slip_log.html",
+ dict(ss_list=ss_list,
+ keys=sorted(ss_list[0].keys()),
+ title=_('Created Salary Slips')))
+ return log
def get_sal_slip_list(self, ss_status, as_dict=False):
"""
@@ -136,44 +142,50 @@
self.check_permission('write')
ss_list = self.get_sal_slip_list(ss_status=0)
+ submitted_ss = []
not_submitted_ss = []
for ss in ss_list:
ss_obj = frappe.get_doc("Salary Slip",ss[0])
+ ss_dict = {}
+ ss_dict["Employee Name"] = ss_obj.employee_name
+ ss_dict["Total Pay"] = fmt_money(ss_obj.rounded_total,currency = frappe.defaults.get_global_default("currency"))
+ ss_dict["Salary Slip"] = self.format_as_links(ss_obj.name)[0]
if ss_obj.net_pay<0:
- not_submitted_ss.append(ss[0])
+ not_submitted_ss.append(ss_dict)
else:
try:
ss_obj.submit()
+ submitted_ss.append(ss_dict)
except frappe.ValidationError:
- not_submitted_ss.append(ss[0])
+ not_submitted_ss.append(ss_dict)
- return self.create_submit_log(ss_list, not_submitted_ss)
+ return self.create_submit_log(submitted_ss, not_submitted_ss)
- def create_submit_log(self, all_ss, not_submitted_ss):
+ def create_submit_log(self, submitted_ss, not_submitted_ss):
log = ''
- if not all_ss:
+ if not submitted_ss and not not_submitted_ss:
log = "No salary slip found to submit for the above selected criteria"
- else:
- all_ss = [d[0] for d in all_ss]
- submitted_ss = self.format_as_links(list(set(all_ss) - set(not_submitted_ss)))
if submitted_ss:
- log = """
- <b>Salary Slips Submitted:</b> <br><br>%s
- """ % ('<br>'.join(submitted_ss))
+ log = frappe.render_template("templates/includes/salary_slip_log.html",
+ dict(ss_list=submitted_ss,
+ keys=sorted(submitted_ss[0].keys()),
+ title=_('Submitted Salary Slips')))
if not_submitted_ss:
+ log += frappe.render_template(self.get_log_template(),
+ dict(ss_list=not_submitted_ss,
+ keys=sorted(not_submitted_ss[0].keys()),
+ title=_('Not Submitted Salary Slips')))
log += """
- <b>Not Submitted Salary Slips: </b>\
- <br><br> %s <br><br> \
Possible reasons: <br>\
1. Net pay is less than 0 <br>
- 2. Company email id specified in employee master is not valid. <br> \
- """% ('<br>'.join(not_submitted_ss))
+ 2. Company email id specified in employee master is not valid. <br>
+ """
return log
- def format_as_links(self, ss_list):
- return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(s) for s in ss_list]
+ def format_as_links(self, salary_slip):
+ return ['<a href="#Form/Salary Slip/{0}">{0}</a>'.format(salary_slip)]
def get_total_salary(self):
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js
index 6d9111f..a879b39 100644
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js
+++ b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.js
@@ -4,19 +4,18 @@
frappe.query_reports["Monthly Salary Register"] = {
"filters": [
{
- "fieldname":"month",
- "label": __("Month"),
- "fieldtype": "Select",
- "options": "\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug\nSep\nOct\nNov\nDec",
- "default": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
- "Dec"][frappe.datetime.str_to_obj(frappe.datetime.get_today()).getMonth()],
+ "fieldname":"from_date",
+ "label": __("From"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
+ "reqd": 1
},
{
- "fieldname":"fiscal_year",
- "label": __("Fiscal Year"),
- "fieldtype": "Link",
- "options": "Fiscal Year",
- "default": sys_defaults.fiscal_year,
+ "fieldname":"to_date",
+ "label": __("To"),
+ "fieldtype": "Date",
+ "default": frappe.datetime.get_today(),
+ "reqd": 1
},
{
"fieldname":"employee",
diff --git a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
index 1e9d03e..e8d0a0b 100644
--- a/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
+++ b/erpnext/hr/report/monthly_salary_register/monthly_salary_register.py
@@ -18,7 +18,7 @@
data = []
for ss in salary_slips:
row = [ss.name, ss.employee, ss.employee_name, ss.branch, ss.department, ss.designation,
- ss.company, ss.month, ss.leave_withut_pay, ss.payment_days]
+ ss.company, ss.start_date, ss.end_date, ss.leave_withut_pay, ss.payment_days]
for e in earning_types:
row.append(ss_earning_map.get(ss.name, {}).get(e))
@@ -38,7 +38,7 @@
columns = [
_("Salary Slip ID") + ":Link/Salary Slip:150",_("Employee") + ":Link/Employee:120", _("Employee Name") + "::140", _("Branch") + ":Link/Branch:120",
_("Department") + ":Link/Department:120", _("Designation") + ":Link/Designation:120",
- _("Company") + ":Link/Company:120", _("Month") + "::80", _("Leave Without Pay") + ":Float:130",
+ _("Company") + ":Link/Company:120", _("Start Date") + "::80", _("End Date") + "::80", _("Leave Without Pay") + ":Float:130",
_("Payment Days") + ":Float:120"
]
@@ -60,23 +60,18 @@
def get_salary_slips(filters):
conditions, filters = get_conditions(filters)
salary_slips = frappe.db.sql("""select * from `tabSalary Slip` where docstatus = 1 %s
- order by employee, month""" % conditions, filters, as_dict=1)
+ order by employee""" % conditions, filters, as_dict=1)
if not salary_slips:
- frappe.throw(_("No salary slip found for month {0} and year {1}").format(
- filters.get("month"), filters.get("fiscal_year")))
+ frappe.throw(_("No salary slip found between {0} and {1}").format(
+ filters.get("from_date"), filters.get("to_date")))
return salary_slips
def get_conditions(filters):
conditions = ""
- if filters.get("month"):
- month = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov",
- "Dec"].index(filters["month"]) + 1
- filters["month"] = month
- conditions += " and month = %(month)s"
-
- if filters.get("fiscal_year"): conditions += " and fiscal_year = %(fiscal_year)s"
+ if filters.get("from_date"): conditions += " and start_date >= %(from_date)s"
+ if filters.get("to_date"): conditions += " and end_date <= %(to_date)s"
if filters.get("company"): conditions += " and company = %(company)s"
if filters.get("employee"): conditions += " and employee = %(employee)s"
diff --git a/erpnext/public/js/controllers/transaction.js b/erpnext/public/js/controllers/transaction.js
index dcbb56b..799730e 100644
--- a/erpnext/public/js/controllers/transaction.js
+++ b/erpnext/public/js/controllers/transaction.js
@@ -349,7 +349,7 @@
me.frm.set_value("letter_head", company_doc.default_letter_head);
}
}
- if (company_doc.default_terms && me.frm.doc.doctype != "Purchase Invoice") {
+ if (company_doc.default_terms && me.frm.doc.doctype != "Purchase Invoice" && frappe.meta.has_field(me.frm.doc.doctype, "tc_name")) {
me.frm.set_value("tc_name", company_doc.default_terms);
}
diff --git a/erpnext/setup/doctype/item_group/item_group.py b/erpnext/setup/doctype/item_group/item_group.py
index c38e04d..98404a4 100644
--- a/erpnext/setup/doctype/item_group/item_group.py
+++ b/erpnext/setup/doctype/item_group/item_group.py
@@ -28,7 +28,6 @@
def on_update(self):
NestedSet.on_update(self)
- WebsiteGenerator.on_update(self)
invalidate_cache_for(self)
self.validate_name_with_item()
self.validate_one_root()
diff --git a/erpnext/setup/doctype/sms_settings/sms_settings.py b/erpnext/setup/doctype/sms_settings/sms_settings.py
index 681237f..ddfc045 100644
--- a/erpnext/setup/doctype/sms_settings/sms_settings.py
+++ b/erpnext/setup/doctype/sms_settings/sms_settings.py
@@ -77,7 +77,7 @@
for d in arg.get('receiver_list'):
args[ss.receiver_parameter] = d
status = send_request(ss.sms_gateway_url, args)
- if status > 200 and status < 300:
+ if status >= 200 and status < 300:
success_list.append(d)
if len(success_list) > 0:
diff --git a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
index d2b68b4..37f114b 100644
--- a/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
+++ b/erpnext/setup/doctype/terms_and_conditions/terms_and_conditions.py
@@ -9,7 +9,8 @@
class TermsandConditions(Document):
def validate(self):
- validate_template(self.terms)
+ if self.terms:
+ validate_template(self.terms)
@frappe.whitelist()
def get_terms_and_conditions(template_name, doc):
diff --git a/erpnext/stock/doctype/item/item.py b/erpnext/stock/doctype/item/item.py
index b721029..53faa43 100644
--- a/erpnext/stock/doctype/item/item.py
+++ b/erpnext/stock/doctype/item/item.py
@@ -93,7 +93,6 @@
where parentfield='website_item_groups' and parenttype='Item' and parent=%s""", self.name)
def on_update(self):
- super(Item, self).on_update()
invalidate_cache_for_item(self)
self.validate_name_with_item_group()
self.update_item_price()
diff --git a/erpnext/stock/doctype/quality_inspection/quality_inspection.js b/erpnext/stock/doctype/quality_inspection/quality_inspection.js
index 5d7b6b4..53579fb 100644
--- a/erpnext/stock/doctype/quality_inspection/quality_inspection.js
+++ b/erpnext/stock/doctype/quality_inspection/quality_inspection.js
@@ -9,7 +9,7 @@
return {
query: "erpnext.stock.doctype.quality_inspection.quality_inspection.item_query",
filters: {
- "from": doc.reference_type,
+ "from": doc.reference_type + " Item",
"parent": doc.reference_name
}
}
diff --git a/erpnext/templates/includes/salary_slip_log.html b/erpnext/templates/includes/salary_slip_log.html
new file mode 100644
index 0000000..107df51
--- /dev/null
+++ b/erpnext/templates/includes/salary_slip_log.html
@@ -0,0 +1,19 @@
+<table class='table table-bordered'>
+ <caption>{{title}}</caption>
+ <thead>
+ <tr>
+ {% for key in keys %}
+ <th {% if key == "Total Pay"%} style="text-align: right;" {% endif %}> {{ key }} </th>
+ {% endfor %}
+ </tr>
+ </thead>
+ <tbody>
+ {% for ss_dict in ss_list %}
+ <tr>
+ {% for key, value in ss_dict.iteritems()|sort %}
+ <td {% if key == "Total Pay"%} align = "right" {% endif %}> {{value}} </td>
+ {% endfor %}
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
\ No newline at end of file