Merge branch 'develop' into clarkejj-patch-1
This commit is contained in:
commit
15e4ea0472
@ -14,6 +14,9 @@ frappe.treeview_settings["Account"] = {
|
|||||||
on_change: function() {
|
on_change: function() {
|
||||||
var me = frappe.treeview_settings['Account'].treeview;
|
var me = frappe.treeview_settings['Account'].treeview;
|
||||||
var company = me.page.fields_dict.company.get_value();
|
var company = me.page.fields_dict.company.get_value();
|
||||||
|
if (!company) {
|
||||||
|
frappe.throw(__("Please set a Company"));
|
||||||
|
}
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
method: "erpnext.accounts.doctype.account.account.get_root_company",
|
||||||
args: {
|
args: {
|
||||||
|
@ -19,11 +19,15 @@
|
|||||||
"attendance_date",
|
"attendance_date",
|
||||||
"company",
|
"company",
|
||||||
"department",
|
"department",
|
||||||
"shift",
|
|
||||||
"attendance_request",
|
"attendance_request",
|
||||||
"amended_from",
|
"details_section",
|
||||||
|
"shift",
|
||||||
|
"in_time",
|
||||||
|
"out_time",
|
||||||
|
"column_break_18",
|
||||||
"late_entry",
|
"late_entry",
|
||||||
"early_exit"
|
"early_exit",
|
||||||
|
"amended_from"
|
||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
@ -172,13 +176,36 @@
|
|||||||
"fieldname": "early_exit",
|
"fieldname": "early_exit",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Early Exit"
|
"label": "Early Exit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "details_section",
|
||||||
|
"fieldtype": "Section Break",
|
||||||
|
"label": "Details"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "shift",
|
||||||
|
"fieldname": "in_time",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "In Time",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "shift",
|
||||||
|
"fieldname": "out_time",
|
||||||
|
"fieldtype": "Datetime",
|
||||||
|
"label": "Out Time",
|
||||||
|
"read_only": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldname": "column_break_18",
|
||||||
|
"fieldtype": "Column Break"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"icon": "fa fa-ok",
|
"icon": "fa fa-ok",
|
||||||
"idx": 1,
|
"idx": 1,
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-04-11 11:40:14.319496",
|
"modified": "2020-05-29 13:51:37.177231",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Attendance",
|
"name": "Attendance",
|
||||||
|
@ -139,13 +139,13 @@ frappe.ui.form.on('Employee Advance', {
|
|||||||
employee: function (frm) {
|
employee: function (frm) {
|
||||||
if (frm.doc.employee) {
|
if (frm.doc.employee) {
|
||||||
return frappe.call({
|
return frappe.call({
|
||||||
method: "erpnext.hr.doctype.employee_advance.employee_advance.get_due_advance_amount",
|
method: "erpnext.hr.doctype.employee_advance.employee_advance.get_pending_amount",
|
||||||
args: {
|
args: {
|
||||||
"employee": frm.doc.employee,
|
"employee": frm.doc.employee,
|
||||||
"posting_date": frm.doc.posting_date
|
"posting_date": frm.doc.posting_date
|
||||||
},
|
},
|
||||||
callback: function(r) {
|
callback: function(r) {
|
||||||
frm.set_value("due_advance_amount",r.message);
|
frm.set_value("pending_amount",r.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
"column_break_11",
|
"column_break_11",
|
||||||
"advance_amount",
|
"advance_amount",
|
||||||
"paid_amount",
|
"paid_amount",
|
||||||
"due_advance_amount",
|
"pending_amount",
|
||||||
"claimed_amount",
|
"claimed_amount",
|
||||||
"return_amount",
|
"return_amount",
|
||||||
"section_break_7",
|
"section_break_7",
|
||||||
@ -102,14 +102,6 @@
|
|||||||
"options": "Company:company:default_currency",
|
"options": "Company:company:default_currency",
|
||||||
"read_only": 1
|
"read_only": 1
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"depends_on": "eval:cur_frm.doc.employee",
|
|
||||||
"fieldname": "due_advance_amount",
|
|
||||||
"fieldtype": "Currency",
|
|
||||||
"label": "Due Advance Amount",
|
|
||||||
"options": "Company:company:default_currency",
|
|
||||||
"read_only": 1
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"fieldname": "claimed_amount",
|
"fieldname": "claimed_amount",
|
||||||
"fieldtype": "Currency",
|
"fieldtype": "Currency",
|
||||||
@ -177,11 +169,19 @@
|
|||||||
"fieldname": "repay_unclaimed_amount_from_salary",
|
"fieldname": "repay_unclaimed_amount_from_salary",
|
||||||
"fieldtype": "Check",
|
"fieldtype": "Check",
|
||||||
"label": "Repay unclaimed amount from salary"
|
"label": "Repay unclaimed amount from salary"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"depends_on": "eval:cur_frm.doc.employee",
|
||||||
|
"fieldname": "pending_amount",
|
||||||
|
"fieldtype": "Currency",
|
||||||
|
"label": "Pending Amount",
|
||||||
|
"options": "Company:company:default_currency",
|
||||||
|
"read_only": 1
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"is_submittable": 1,
|
"is_submittable": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2020-03-06 15:11:33.747535",
|
"modified": "2020-06-12 12:42:39.833818",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "HR",
|
"module": "HR",
|
||||||
"name": "Employee Advance",
|
"name": "Employee Advance",
|
||||||
|
@ -95,7 +95,7 @@ class EmployeeAdvance(Document):
|
|||||||
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
|
frappe.db.set_value("Employee Advance", self.name, "status", self.status)
|
||||||
|
|
||||||
@frappe.whitelist()
|
@frappe.whitelist()
|
||||||
def get_due_advance_amount(employee, posting_date):
|
def get_pending_amount(employee, posting_date):
|
||||||
employee_due_amount = frappe.get_all("Employee Advance", \
|
employee_due_amount = frappe.get_all("Employee Advance", \
|
||||||
filters = {"employee":employee, "docstatus":1, "posting_date":("<=", posting_date)}, \
|
filters = {"employee":employee, "docstatus":1, "posting_date":("<=", posting_date)}, \
|
||||||
fields = ["advance_amount", "paid_amount"])
|
fields = ["advance_amount", "paid_amount"])
|
||||||
|
@ -72,7 +72,7 @@ def add_log_based_on_employee_field(employee_field_value, timestamp, device_id=N
|
|||||||
return doc
|
return doc
|
||||||
|
|
||||||
|
|
||||||
def mark_attendance_and_link_log(logs, attendance_status, attendance_date, working_hours=None, late_entry=False, early_exit=False, shift=None):
|
def mark_attendance_and_link_log(logs, attendance_status, attendance_date, working_hours=None, late_entry=False, early_exit=False, in_time=None, out_time=None, shift=None):
|
||||||
"""Creates an attendance and links the attendance to the Employee Checkin.
|
"""Creates an attendance and links the attendance to the Employee Checkin.
|
||||||
Note: If attendance is already present for the given date, the logs are marked as skipped and no exception is thrown.
|
Note: If attendance is already present for the given date, the logs are marked as skipped and no exception is thrown.
|
||||||
|
|
||||||
@ -100,7 +100,9 @@ def mark_attendance_and_link_log(logs, attendance_status, attendance_date, worki
|
|||||||
'company': employee_doc.company,
|
'company': employee_doc.company,
|
||||||
'shift': shift,
|
'shift': shift,
|
||||||
'late_entry': late_entry,
|
'late_entry': late_entry,
|
||||||
'early_exit': early_exit
|
'early_exit': early_exit,
|
||||||
|
'in_time': in_time,
|
||||||
|
'out_time': out_time
|
||||||
}
|
}
|
||||||
attendance = frappe.get_doc(doc_dict).insert()
|
attendance = frappe.get_doc(doc_dict).insert()
|
||||||
attendance.submit()
|
attendance.submit()
|
||||||
|
@ -46,6 +46,7 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
|
|
||||||
make_dashboard: function(frm) {
|
make_dashboard: function(frm) {
|
||||||
var leave_details;
|
var leave_details;
|
||||||
|
let lwps;
|
||||||
if (frm.doc.employee) {
|
if (frm.doc.employee) {
|
||||||
frappe.call({
|
frappe.call({
|
||||||
method: "erpnext.hr.doctype.leave_application.leave_application.get_leave_details",
|
method: "erpnext.hr.doctype.leave_application.leave_application.get_leave_details",
|
||||||
@ -61,6 +62,7 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
if (!r.exc && r.message['leave_approver']) {
|
if (!r.exc && r.message['leave_approver']) {
|
||||||
frm.set_value('leave_approver', r.message['leave_approver']);
|
frm.set_value('leave_approver', r.message['leave_approver']);
|
||||||
}
|
}
|
||||||
|
lwps = r.message["lwps"];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$("div").remove(".form-dashboard-section.custom");
|
$("div").remove(".form-dashboard-section.custom");
|
||||||
@ -70,12 +72,17 @@ frappe.ui.form.on("Leave Application", {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
frm.dashboard.show();
|
frm.dashboard.show();
|
||||||
|
let allowed_leave_types = Object.keys(leave_details);
|
||||||
|
|
||||||
|
// lwps should be allowed, lwps don't have any allocation
|
||||||
|
allowed_leave_types = allowed_leave_types.concat(lwps);
|
||||||
|
|
||||||
frm.set_query('leave_type', function(){
|
frm.set_query('leave_type', function(){
|
||||||
return {
|
return {
|
||||||
filters : [
|
filters : [
|
||||||
['leave_type_name', 'in', Object.keys(leave_details)]
|
['leave_type_name', 'in', allowed_leave_types]
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -19,7 +19,6 @@ class NotAnOptionalHoliday(frappe.ValidationError): pass
|
|||||||
|
|
||||||
from frappe.model.document import Document
|
from frappe.model.document import Document
|
||||||
class LeaveApplication(Document):
|
class LeaveApplication(Document):
|
||||||
|
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
return _("{0}: From {0} of type {1}").format(self.employee_name, self.leave_type)
|
return _("{0}: From {0} of type {1}").format(self.employee_name, self.leave_type)
|
||||||
|
|
||||||
@ -463,9 +462,14 @@ def get_leave_details(employee, date):
|
|||||||
"pending_leaves": leaves_pending,
|
"pending_leaves": leaves_pending,
|
||||||
"remaining_leaves": remaining_leaves}
|
"remaining_leaves": remaining_leaves}
|
||||||
|
|
||||||
|
#is used in set query
|
||||||
|
lwps = frappe.get_list("Leave Type", filters = {"is_lwp": 1})
|
||||||
|
lwps = [lwp.name for lwp in lwps]
|
||||||
|
|
||||||
ret = {
|
ret = {
|
||||||
'leave_allocation': leave_allocation,
|
'leave_allocation': leave_allocation,
|
||||||
'leave_approver': get_leave_approver(employee)
|
'leave_approver': get_leave_approver(employee),
|
||||||
|
'lwps': lwps
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
@ -28,13 +28,14 @@ class ShiftType(Document):
|
|||||||
logs = frappe.db.get_list('Employee Checkin', fields="*", filters=filters, order_by="employee,time")
|
logs = frappe.db.get_list('Employee Checkin', fields="*", filters=filters, order_by="employee,time")
|
||||||
for key, group in itertools.groupby(logs, key=lambda x: (x['employee'], x['shift_actual_start'])):
|
for key, group in itertools.groupby(logs, key=lambda x: (x['employee'], x['shift_actual_start'])):
|
||||||
single_shift_logs = list(group)
|
single_shift_logs = list(group)
|
||||||
attendance_status, working_hours, late_entry, early_exit = self.get_attendance(single_shift_logs)
|
attendance_status, working_hours, late_entry, early_exit, in_time, out_time = self.get_attendance(single_shift_logs)
|
||||||
mark_attendance_and_link_log(single_shift_logs, attendance_status, key[1].date(), working_hours, late_entry, early_exit, self.name)
|
mark_attendance_and_link_log(single_shift_logs, attendance_status, key[1].date(), working_hours, late_entry, early_exit, in_time, out_time, self.name)
|
||||||
for employee in self.get_assigned_employee(self.process_attendance_after, True):
|
for employee in self.get_assigned_employee(self.process_attendance_after, True):
|
||||||
self.mark_absent_for_dates_with_no_attendance(employee)
|
self.mark_absent_for_dates_with_no_attendance(employee)
|
||||||
|
|
||||||
def get_attendance(self, logs):
|
def get_attendance(self, logs):
|
||||||
"""Return attendance_status, working_hours for a set of logs belonging to a single shift.
|
"""Return attendance_status, working_hours, late_entry, early_exit, in_time, out_time
|
||||||
|
for a set of logs belonging to a single shift.
|
||||||
Assumtion:
|
Assumtion:
|
||||||
1. These logs belongs to an single shift, single employee and is not in a holiday date.
|
1. These logs belongs to an single shift, single employee and is not in a holiday date.
|
||||||
2. Logs are in chronological order
|
2. Logs are in chronological order
|
||||||
@ -48,10 +49,10 @@ class ShiftType(Document):
|
|||||||
early_exit = True
|
early_exit = True
|
||||||
|
|
||||||
if self.working_hours_threshold_for_absent and total_working_hours < self.working_hours_threshold_for_absent:
|
if self.working_hours_threshold_for_absent and total_working_hours < self.working_hours_threshold_for_absent:
|
||||||
return 'Absent', total_working_hours, late_entry, early_exit
|
return 'Absent', total_working_hours, late_entry, early_exit, in_time, out_time
|
||||||
if self.working_hours_threshold_for_half_day and total_working_hours < self.working_hours_threshold_for_half_day:
|
if self.working_hours_threshold_for_half_day and total_working_hours < self.working_hours_threshold_for_half_day:
|
||||||
return 'Half Day', total_working_hours, late_entry, early_exit
|
return 'Half Day', total_working_hours, late_entry, early_exit, in_time, out_time
|
||||||
return 'Present', total_working_hours, late_entry, early_exit
|
return 'Present', total_working_hours, late_entry, early_exit, in_time, out_time
|
||||||
|
|
||||||
def mark_absent_for_dates_with_no_attendance(self, employee):
|
def mark_absent_for_dates_with_no_attendance(self, employee):
|
||||||
"""Marks Absents for the given employee on working days in this shift which have no attendance marked.
|
"""Marks Absents for the given employee on working days in this shift which have no attendance marked.
|
||||||
|
@ -680,6 +680,7 @@ erpnext.patches.v12_0.update_appointment_reminder_scheduler_entry
|
|||||||
erpnext.patches.v12_0.retain_permission_rules_for_video_doctype
|
erpnext.patches.v12_0.retain_permission_rules_for_video_doctype
|
||||||
erpnext.patches.v12_0.remove_duplicate_leave_ledger_entries #2020-05-22
|
erpnext.patches.v12_0.remove_duplicate_leave_ledger_entries #2020-05-22
|
||||||
erpnext.patches.v13_0.patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive
|
erpnext.patches.v13_0.patch_to_fix_reverse_linking_in_additional_salary_encashment_and_incentive
|
||||||
|
erpnext.patches.v12_0.move_due_advance_amount_to_pending_amount
|
||||||
execute:frappe.delete_doc_if_exists("Page", "appointment-analytic")
|
execute:frappe.delete_doc_if_exists("Page", "appointment-analytic")
|
||||||
execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
|
execute:frappe.rename_doc("Desk Page", "Getting Started", "Home", force=True)
|
||||||
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
erpnext.patches.v12_0.unset_customer_supplier_based_on_type_of_item_price
|
||||||
|
@ -0,0 +1,9 @@
|
|||||||
|
# Copyright (c) 2019, Frappe and Contributors
|
||||||
|
# License: GNU General Public License v3. See license.txt
|
||||||
|
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
import frappe
|
||||||
|
|
||||||
|
def execute():
|
||||||
|
''' Move from due_advance_amount to pending_amount '''
|
||||||
|
frappe.db.sql(''' UPDATE `tabEmployee Advance` SET pending_amount=due_advance_amount ''')
|
@ -7,4 +7,4 @@ def execute():
|
|||||||
for entry in doctypes:
|
for entry in doctypes:
|
||||||
if frappe.db.exists('DocType', entry):
|
if frappe.db.exists('DocType', entry):
|
||||||
frappe.reload_doc('Healthcare', 'doctype', entry)
|
frappe.reload_doc('Healthcare', 'doctype', entry)
|
||||||
frappe.db.sql("update `tab{dt}` set company = '{company}' where ifnull(company, '') = ''".format(dt=entry, company=company))
|
frappe.db.sql("update `tab{dt}` set company = {company} where ifnull(company, '') = ''".format(dt=entry, company=frappe.db.escape(company)))
|
||||||
|
@ -3,16 +3,19 @@
|
|||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import frappe
|
import frappe
|
||||||
|
import json
|
||||||
from frappe.model.naming import set_name_by_naming_series
|
from frappe.model.naming import set_name_by_naming_series
|
||||||
from frappe import _, msgprint, throw
|
from frappe import _, msgprint
|
||||||
import frappe.defaults
|
import frappe.defaults
|
||||||
from frappe.utils import flt, cint, cstr, today
|
from frappe.utils import flt, cint, cstr, today, get_formatted_email
|
||||||
from frappe.desk.reportview import build_match_conditions, get_filters_cond
|
from frappe.desk.reportview import build_match_conditions, get_filters_cond
|
||||||
from erpnext.utilities.transaction_base import TransactionBase
|
from erpnext.utilities.transaction_base import TransactionBase
|
||||||
from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
|
from erpnext.accounts.party import validate_party_accounts, get_dashboard_info, get_timeline_data # keep this
|
||||||
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
|
from frappe.contacts.address_and_contact import load_address_and_contact, delete_contact_and_address
|
||||||
from frappe.model.rename_doc import update_linked_doctypes
|
from frappe.model.rename_doc import update_linked_doctypes
|
||||||
from frappe.model.mapper import get_mapped_doc
|
from frappe.model.mapper import get_mapped_doc
|
||||||
|
from frappe.utils.user import get_users_with_role
|
||||||
|
|
||||||
|
|
||||||
class Customer(TransactionBase):
|
class Customer(TransactionBase):
|
||||||
def get_feed(self):
|
def get_feed(self):
|
||||||
@ -378,10 +381,45 @@ def check_credit_limit(customer, company, ignore_outstanding_sales_order=False,
|
|||||||
.format(customer, customer_outstanding, credit_limit))
|
.format(customer, customer_outstanding, credit_limit))
|
||||||
|
|
||||||
# If not authorized person raise exception
|
# If not authorized person raise exception
|
||||||
credit_controller = frappe.db.get_value('Accounts Settings', None, 'credit_controller')
|
credit_controller_role = frappe.db.get_single_value('Accounts Settings', 'credit_controller')
|
||||||
if not credit_controller or credit_controller not in frappe.get_roles():
|
if not credit_controller_role or credit_controller_role not in frappe.get_roles():
|
||||||
throw(_("Please contact to the user who have Sales Master Manager {0} role")
|
# form a list of emails for the credit controller users
|
||||||
.format(" / " + credit_controller if credit_controller else ""))
|
credit_controller_users = get_users_with_role(credit_controller_role or "Sales Master Manager")
|
||||||
|
|
||||||
|
# form a list of emails and names to show to the user
|
||||||
|
credit_controller_users_list = [user for user in credit_controller_users if frappe.db.exists("Employee", {"prefered_email": user})]
|
||||||
|
credit_controller_users = [get_formatted_email(user).replace("<", "(").replace(">", ")") for user in credit_controller_users_list]
|
||||||
|
|
||||||
|
if not credit_controller_users:
|
||||||
|
frappe.throw(_("Please contact your administrator to extend the credit limits for {0}.".format(customer)))
|
||||||
|
|
||||||
|
message = """Please contact any of the following users to extend the credit limits for {0}:
|
||||||
|
<br><br><ul><li>{1}</li></ul>""".format(customer, '<li>'.join(credit_controller_users))
|
||||||
|
|
||||||
|
# if the current user does not have permissions to override credit limit,
|
||||||
|
# prompt them to send out an email to the controller users
|
||||||
|
frappe.msgprint(message,
|
||||||
|
title="Notify",
|
||||||
|
raise_exception=1,
|
||||||
|
primary_action={
|
||||||
|
'label': 'Send Email',
|
||||||
|
'server_action': 'erpnext.selling.doctype.customer.customer.send_emails',
|
||||||
|
'args': {
|
||||||
|
'customer': customer,
|
||||||
|
'customer_outstanding': customer_outstanding,
|
||||||
|
'credit_limit': credit_limit,
|
||||||
|
'credit_controller_users_list': credit_controller_users_list
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
@frappe.whitelist()
|
||||||
|
def send_emails(args):
|
||||||
|
args = json.loads(args)
|
||||||
|
subject = (_("Credit limit reached for customer {0}").format(args.get('customer')))
|
||||||
|
message = (_("Credit limit has been crossed for customer {0} ({1}/{2})")
|
||||||
|
.format(args.get('customer'), args.get('customer_outstanding'), args.get('credit_limit')))
|
||||||
|
frappe.sendmail(recipients=[args.get('credit_controller_users_list')], subject=subject, message=message)
|
||||||
|
|
||||||
def get_customer_outstanding(customer, company, ignore_outstanding_sales_order=False, cost_center=None):
|
def get_customer_outstanding(customer, company, ignore_outstanding_sales_order=False, cost_center=None):
|
||||||
# Outstanding based on GL Entries
|
# Outstanding based on GL Entries
|
||||||
|
@ -8,7 +8,7 @@ from frappe.utils import getdate, flt
|
|||||||
|
|
||||||
def execute(filters=None):
|
def execute(filters=None):
|
||||||
if not filters: filters = {}
|
if not filters: filters = {}
|
||||||
float_preceision = frappe.db.get_default("float_preceision")
|
float_precision = frappe.db.get_default("float_precision")
|
||||||
|
|
||||||
condition = get_condition(filters)
|
condition = get_condition(filters)
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ def execute(filters=None):
|
|||||||
data = []
|
data = []
|
||||||
for item in items:
|
for item in items:
|
||||||
total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0))
|
total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0))
|
||||||
avg_daily_outgoing = flt(total_outgoing / diff, float_preceision)
|
avg_daily_outgoing = flt(total_outgoing / diff, float_precision)
|
||||||
reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock)
|
reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock)
|
||||||
|
|
||||||
data.append([item.name, item.item_name, item.item_group, item.brand, item.description,
|
data.append([item.name, item.item_name, item.item_group, item.brand, item.description,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user