Merge branch 'hotfix'
This commit is contained in:
commit
1b18bba04a
@ -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__ = '10.1.31'
|
__version__ = '10.1.32'
|
||||||
|
|
||||||
def get_default_company(user=None):
|
def get_default_company(user=None):
|
||||||
'''Get default company for user'''
|
'''Get default company for user'''
|
||||||
|
@ -558,7 +558,8 @@ def get_itemised_tax_breakup_html(doc):
|
|||||||
itemised_tax=itemised_tax,
|
itemised_tax=itemised_tax,
|
||||||
itemised_taxable_amount=itemised_taxable_amount,
|
itemised_taxable_amount=itemised_taxable_amount,
|
||||||
tax_accounts=tax_accounts,
|
tax_accounts=tax_accounts,
|
||||||
company_currency=erpnext.get_company_currency(doc.company)
|
conversion_rate=doc.conversion_rate,
|
||||||
|
currency=doc.currency
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,17 +20,19 @@ class Attendance(Document):
|
|||||||
set_employee_name(self)
|
set_employee_name(self)
|
||||||
|
|
||||||
def check_leave_record(self):
|
def check_leave_record(self):
|
||||||
leave_record = frappe.db.sql("""select leave_type, half_day from `tabLeave Application`
|
leave_record = frappe.db.sql("""select leave_type, half_day, half_day_date from `tabLeave Application`
|
||||||
where employee = %s and %s between from_date and to_date and status = 'Approved'
|
where employee = %s and %s between from_date and to_date and status = 'Approved'
|
||||||
and docstatus = 1""", (self.employee, self.attendance_date), as_dict=True)
|
and docstatus = 1""", (self.employee, self.attendance_date), as_dict=True)
|
||||||
if leave_record:
|
if leave_record:
|
||||||
if leave_record[0].half_day:
|
for d in leave_record:
|
||||||
self.status = 'Half Day'
|
if d.half_day_date == getdate(self.attendance_date):
|
||||||
frappe.msgprint(_("Employee {0} on Half day on {1}").format(self.employee, self.attendance_date))
|
self.status = 'Half Day'
|
||||||
else:
|
frappe.msgprint(_("Employee {0} on Half day on {1}").format(self.employee, self.attendance_date))
|
||||||
self.status = 'On Leave'
|
else:
|
||||||
self.leave_type = leave_record[0].leave_type
|
self.status = 'On Leave'
|
||||||
frappe.msgprint(_("Employee {0} on Leave on {1}").format(self.employee, self.attendance_date))
|
self.leave_type = d.leave_type
|
||||||
|
frappe.msgprint(_("Employee {0} on Leave on {1}").format(self.employee, self.attendance_date))
|
||||||
|
|
||||||
if self.status == "On Leave" and not leave_record:
|
if self.status == "On Leave" and not leave_record:
|
||||||
frappe.throw(_("No leave record found for employee {0} for {1}").format(self.employee, self.attendance_date))
|
frappe.throw(_("No leave record found for employee {0} for {1}").format(self.employee, self.attendance_date))
|
||||||
|
|
||||||
|
@ -95,6 +95,9 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
if (!r.exc && r.message) {
|
if (!r.exc && r.message) {
|
||||||
frm.set_value('leave_balance', r.message);
|
frm.set_value('leave_balance', r.message);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
frm.set_value('leave_balance', "0");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,12 @@ from __future__ import unicode_literals
|
|||||||
import frappe
|
import frappe
|
||||||
from frappe import _
|
from frappe import _
|
||||||
from frappe.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_link_to_form, \
|
from frappe.utils import cint, cstr, date_diff, flt, formatdate, getdate, get_link_to_form, \
|
||||||
comma_or, get_fullname
|
comma_or, get_fullname, nowdate
|
||||||
from erpnext.hr.utils import set_employee_name
|
from erpnext.hr.utils import set_employee_name
|
||||||
from erpnext.hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
|
from erpnext.hr.doctype.leave_block_list.leave_block_list import get_applicable_block_dates
|
||||||
from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
|
from erpnext.hr.doctype.employee.employee import get_holiday_list_for_employee
|
||||||
from erpnext.hr.doctype.employee_leave_approver.employee_leave_approver import get_approver_list
|
from erpnext.hr.doctype.employee_leave_approver.employee_leave_approver import get_approver_list
|
||||||
|
from erpnext.buying.doctype.supplier_scorecard.supplier_scorecard import daterange
|
||||||
|
|
||||||
class LeaveDayBlockedError(frappe.ValidationError): pass
|
class LeaveDayBlockedError(frappe.ValidationError): pass
|
||||||
class OverlapError(frappe.ValidationError): pass
|
class OverlapError(frappe.ValidationError): pass
|
||||||
@ -52,6 +52,7 @@ class LeaveApplication(Document):
|
|||||||
frappe.throw(_("Only Leave Applications with status 'Approved' and 'Rejected' can be submitted"))
|
frappe.throw(_("Only Leave Applications with status 'Approved' and 'Rejected' can be submitted"))
|
||||||
|
|
||||||
self.validate_back_dated_application()
|
self.validate_back_dated_application()
|
||||||
|
self.update_attendance()
|
||||||
|
|
||||||
# notify leave applier about approval
|
# notify leave applier about approval
|
||||||
self.notify_employee(self.status)
|
self.notify_employee(self.status)
|
||||||
@ -100,6 +101,41 @@ class LeaveApplication(Document):
|
|||||||
frappe.throw(_("Leave cannot be applied/cancelled before {0}, as leave balance has already been carry-forwarded in the future leave allocation record {1}")
|
frappe.throw(_("Leave cannot be applied/cancelled before {0}, as leave balance has already been carry-forwarded in the future leave allocation record {1}")
|
||||||
.format(formatdate(future_allocation[0].from_date), future_allocation[0].name))
|
.format(formatdate(future_allocation[0].from_date), future_allocation[0].name))
|
||||||
|
|
||||||
|
def update_attendance(self):
|
||||||
|
if self.status == "Approved":
|
||||||
|
attendance = frappe.db.sql("""select name from `tabAttendance` where employee = %s\
|
||||||
|
and (attendance_date between %s and %s) and docstatus < 2""",(self.employee, self.from_date, self.to_date), as_dict=1)
|
||||||
|
|
||||||
|
if attendance:
|
||||||
|
for d in attendance:
|
||||||
|
doc = frappe.get_doc("Attendance", d.name)
|
||||||
|
if getdate(self.half_day_date) == doc.attendance_date:
|
||||||
|
status = "Half Day"
|
||||||
|
else:
|
||||||
|
status = "On Leave"
|
||||||
|
frappe.db.sql("""update `tabAttendance` set status = %s, leave_type = %s\
|
||||||
|
where name = %s""",(status, self.leave_type, d.name))
|
||||||
|
|
||||||
|
elif self.from_date <= nowdate():
|
||||||
|
for dt in daterange(getdate(self.from_date), getdate(self.to_date)):
|
||||||
|
date = dt.strftime("%Y-%m-%d")
|
||||||
|
if not date == self.half_day_date:
|
||||||
|
doc = frappe.new_doc("Attendance")
|
||||||
|
doc.employee = self.employee
|
||||||
|
doc.attendance_date = date
|
||||||
|
doc.company = self.company
|
||||||
|
doc.status = "On Leave"
|
||||||
|
doc.leave_type = self.leave_type
|
||||||
|
doc.submit()
|
||||||
|
else:
|
||||||
|
doc = frappe.new_doc("Attendance")
|
||||||
|
doc.employee = self.employee
|
||||||
|
doc.attendance_date = date
|
||||||
|
doc.company = self.company
|
||||||
|
doc.status = "Half Day"
|
||||||
|
doc.leave_type = self.leave_type
|
||||||
|
doc.submit()
|
||||||
|
|
||||||
def validate_salary_processed_days(self):
|
def validate_salary_processed_days(self):
|
||||||
if not frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
|
if not frappe.db.get_value("Leave Type", self.leave_type, "is_lwp"):
|
||||||
return
|
return
|
||||||
@ -436,30 +472,17 @@ def add_department_leaves(events, start, end, employee, company):
|
|||||||
and company=%s""", (department, company))
|
and company=%s""", (department, company))
|
||||||
|
|
||||||
match_conditions = "and employee in (\"%s\")" % '", "'.join(department_employees)
|
match_conditions = "and employee in (\"%s\")" % '", "'.join(department_employees)
|
||||||
add_leaves(events, start, end, filter_conditions=match_conditions)
|
add_leaves(events, start, end, match_conditions=match_conditions)
|
||||||
|
|
||||||
def add_leaves(events, start, end, filter_conditions=None):
|
|
||||||
conditions = []
|
|
||||||
|
|
||||||
if filter_conditions:
|
|
||||||
conditions.append(filter_conditions)
|
|
||||||
|
|
||||||
if not cint(frappe.db.get_value("HR Settings", None, "show_leaves_of_all_department_members_in_calendar")):
|
|
||||||
from frappe.desk.reportview import build_match_conditions
|
|
||||||
match_conditions = build_match_conditions("Leave Application")
|
|
||||||
|
|
||||||
if match_conditions:
|
|
||||||
conditions.append(match_conditions)
|
|
||||||
|
|
||||||
|
def add_leaves(events, start, end, match_conditions=None):
|
||||||
query = """select name, from_date, to_date, employee_name, half_day,
|
query = """select name, from_date, to_date, employee_name, half_day,
|
||||||
status, employee, docstatus
|
status, employee, docstatus
|
||||||
from `tabLeave Application` where
|
from `tabLeave Application` where
|
||||||
from_date <= %(end)s and to_date >= %(start)s <= to_date
|
from_date <= %(end)s and to_date >= %(start)s <= to_date
|
||||||
and docstatus < 2
|
and docstatus < 2
|
||||||
and status!="Rejected" """
|
and status!="Rejected" """
|
||||||
|
if match_conditions:
|
||||||
if conditions:
|
query += match_conditions
|
||||||
query += ' and '.join(conditions)
|
|
||||||
|
|
||||||
for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True):
|
for d in frappe.db.sql(query, {"start":start, "end": end}, as_dict=True):
|
||||||
e = {
|
e = {
|
||||||
|
@ -22,6 +22,10 @@ def execute(filters=None):
|
|||||||
holiday_map = get_holiday(holiday_list, filters["month"])
|
holiday_map = get_holiday(holiday_list, filters["month"])
|
||||||
|
|
||||||
data = []
|
data = []
|
||||||
|
leave_types = frappe.db.sql("""select name from `tabLeave Type`""", as_list=True)
|
||||||
|
leave_list = [d[0] for d in leave_types]
|
||||||
|
columns.extend(leave_list)
|
||||||
|
|
||||||
for emp in sorted(att_map):
|
for emp in sorted(att_map):
|
||||||
emp_det = emp_map.get(emp)
|
emp_det = emp_map.get(emp)
|
||||||
if not emp_det:
|
if not emp_det:
|
||||||
@ -49,10 +53,35 @@ def execute(filters=None):
|
|||||||
elif status == "Half Day":
|
elif status == "Half Day":
|
||||||
total_p += 0.5
|
total_p += 0.5
|
||||||
total_a += 0.5
|
total_a += 0.5
|
||||||
|
total_l += 0.5
|
||||||
|
|
||||||
row += [total_p, total_l, total_a]
|
row += [total_p, total_l, total_a]
|
||||||
data.append(row)
|
|
||||||
|
|
||||||
|
if not filters.get("employee"):
|
||||||
|
filters.update({"employee": emp})
|
||||||
|
conditions += " and employee = %(employee)s"
|
||||||
|
elif not filters.get("employee") == emp:
|
||||||
|
filters.update({"employee": emp})
|
||||||
|
|
||||||
|
leave_details = frappe.db.sql("""select leave_type, status, count(*) as count from `tabAttendance`\
|
||||||
|
where leave_type is not NULL %s group by leave_type, status""" % conditions, filters, as_dict=1)
|
||||||
|
|
||||||
|
leaves = {}
|
||||||
|
for d in leave_details:
|
||||||
|
if d.status == "Half Day":
|
||||||
|
d.count = d.count * 0.5
|
||||||
|
if d.leave_type in leaves:
|
||||||
|
leaves[d.leave_type] += d.count
|
||||||
|
else:
|
||||||
|
leaves[d.leave_type] = d.count
|
||||||
|
|
||||||
|
for d in leave_list:
|
||||||
|
if d in leaves:
|
||||||
|
row.append(leaves[d])
|
||||||
|
else:
|
||||||
|
row.append("0.0")
|
||||||
|
|
||||||
|
data.append(row)
|
||||||
return columns, data
|
return columns, data
|
||||||
|
|
||||||
def get_columns(filters):
|
def get_columns(filters):
|
||||||
|
@ -75,7 +75,7 @@ class Project(Document):
|
|||||||
sum = 0
|
sum = 0
|
||||||
for task in self.tasks:
|
for task in self.tasks:
|
||||||
if task.task_weight > 0:
|
if task.task_weight > 0:
|
||||||
sum = sum + task.task_weight
|
sum = flt(sum + task.task_weight, task.precision('task_weight'))
|
||||||
if sum > 0 and sum != 1:
|
if sum > 0 and sum != 1:
|
||||||
frappe.throw(_("Total of all task weights should be 1. Please adjust weights of all Project tasks accordingly"))
|
frappe.throw(_("Total of all task weights should be 1. Please adjust weights of all Project tasks accordingly"))
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if(
|
||||||
this.frm.docstatus < 2
|
this.frm.docstatus < 2
|
||||||
&& this.frm.fields_dict["payment_terms_template"]
|
&& this.frm.fields_dict["payment_terms_template"]
|
||||||
&& this.frm.fields_dict["payment_schedule"]
|
&& this.frm.fields_dict["payment_schedule"]
|
||||||
&& this.frm.doc.payment_terms_template
|
&& this.frm.doc.payment_terms_template
|
||||||
@ -1094,6 +1094,8 @@ erpnext.TransactionController = erpnext.taxes_and_totals.extend({
|
|||||||
me.in_apply_price_list = false;
|
me.in_apply_price_list = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}).always(() => {
|
||||||
|
me.in_apply_price_list = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ def make_address(args, is_primary_address=1):
|
|||||||
return address
|
return address
|
||||||
|
|
||||||
def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, filters):
|
def get_customer_primary_contact(doctype, txt, searchfield, start, page_len, filters):
|
||||||
customer = frappe.db.escape(filters.get('customer'))
|
customer = filters.get('customer')
|
||||||
return frappe.db.sql("""
|
return frappe.db.sql("""
|
||||||
select `tabContact`.name from `tabContact`, `tabDynamic Link`
|
select `tabContact`.name from `tabContact`, `tabDynamic Link`
|
||||||
where `tabContact`.name = `tabDynamic Link`.parent and `tabDynamic Link`.link_name = %(customer)s
|
where `tabContact`.name = `tabDynamic Link`.parent and `tabDynamic Link`.link_name = %(customer)s
|
||||||
|
@ -417,6 +417,7 @@ def raise_production_orders(material_request):
|
|||||||
prod_order.material_request_item = d.name
|
prod_order.material_request_item = d.name
|
||||||
prod_order.planned_start_date = mr.transaction_date
|
prod_order.planned_start_date = mr.transaction_date
|
||||||
prod_order.company = mr.company
|
prod_order.company = mr.company
|
||||||
|
prod_order.set_production_order_operations()
|
||||||
prod_order.save()
|
prod_order.save()
|
||||||
production_orders.append(prod_order.name)
|
production_orders.append(prod_order.name)
|
||||||
else:
|
else:
|
||||||
|
@ -16,16 +16,16 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>{{ item }}</td>
|
<td>{{ item }}</td>
|
||||||
<td class='text-right'>
|
<td class='text-right'>
|
||||||
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item), None, company_currency) }}
|
{{ frappe.utils.fmt_money(itemised_taxable_amount.get(item), None, currency) }}
|
||||||
</td>
|
</td>
|
||||||
{% for tax_account in tax_accounts %}
|
{% for tax_account in tax_accounts %}
|
||||||
{% 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'>
|
||||||
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
{% if tax_details.tax_rate or not tax_details.tax_amount %}
|
||||||
({{ tax_details.tax_rate }}%)
|
({{ tax_details.tax_rate }}%)
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ frappe.utils.fmt_money(tax_details.tax_amount, None, company_currency) }}
|
{{ frappe.utils.fmt_money(tax_details.tax_amount / conversion_rate, None, currency) }}
|
||||||
</td>
|
</td>
|
||||||
{% else %}
|
{% else %}
|
||||||
<td></td>
|
<td></td>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user