def get_calendar_events(self): """Get calendar events for given user""" from frappe.desk.doctype.event.event import get_events events = get_events(self.future_from_date.strftime("%Y-%m-%d"), self.future_to_date.strftime("%Y-%m-%d")) or [] for i, e in enumerate(events): e.starts_on_label = format_time(e.starts_on) e.ends_on_label = format_time(e.ends_on) if e.ends_on else None e.date = formatdate(e.starts) e.link = get_url_to_form("Event", e.name) return events
def set_actual_qty(self): allow_negative_stock = cint(frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) for d in self.get("items"): previous_sle = get_previous_sle( { "item_code": d.item_code, "warehouse": d.s_warehouse or d.t_warehouse, "posting_date": self.posting_date, "posting_time": self.posting_time, } ) # get actual stock at source warehouse d.actual_qty = previous_sle.get("qty_after_transaction") or 0 # validate qty during submit if d.docstatus == 1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty: frappe.throw( _( "Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})".format( d.idx, frappe.bold(d.s_warehouse), formatdate(self.posting_date), format_time(self.posting_time), frappe.bold(d.item_code), ) ) + "<br><br>" + _("Available qty is {0}, you need {1}").format( frappe.bold(d.actual_qty), frappe.bold(d.transfer_qty) ), NegativeStockError, title=_("Insufficient Stock"), )
def get_calendar_events(self): """Get calendar events for given user""" from frappe.desk.doctype.event.event import get_events from_date, to_date = get_future_date_for_calendaer_event(self.frequency) events = get_events(from_date, to_date) event_count = 0 for i, e in enumerate(events): e.starts_on_label = format_time(e.starts_on) e.ends_on_label = format_time(e.ends_on) if e.ends_on else None e.date = formatdate(e.starts) e.link = get_url_to_form("Event", e.name) event_count += 1 return events, event_count
def get_html_table(self, columns=None, data=None): date_time = global_date_format(now()) + " " + format_time(now()) report_doctype = frappe.db.get_value("Report", self.report, "ref_doctype") return frappe.render_template( "frappe/templates/emails/auto_email_report.html", { "title": self.name, "description": self.description, "date_time": date_time, "columns": columns, "data": data, "report_url": get_url_to_report(self.report, self.report_type, report_doctype), "report_name": self.report, "edit_report_settings": get_link_to_form("Auto Email Report", self.name), }, )
def get_html_table(self, columns=None, data=None): date_time = global_date_format(now()) + ' ' + format_time(now()) report_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype') return frappe.render_template( 'frappe/templates/emails/auto_email_report.html', { 'title': self.name, 'description': self.description, 'date_time': date_time, 'columns': columns, 'data': data, 'report_url': frappe.utils.get_url_to_report(self.report, self.report_type, report_doctype), 'report_name': self.report, 'edit_report_settings': frappe.utils.get_link_to_form('Auto Email Report', self.name) })
def test_format_time(self): # Test format_time with various default time formats set for fmt, valid_fmt in test_time_formats.items(): frappe.db.set_default("time_format", fmt) frappe.local.user_time_format = None self.assertEqual(get_user_time_format(), fmt) self.assertEqual(format_time(test_time), valid_fmt)
def set_actual_qty(self): allow_negative_stock = cint( frappe.db.get_value("Stock Settings", None, "allow_negative_stock")) for d in self.get('items'): previous_sle = get_previous_sle({ "item_code": d.item_code, "warehouse": d.s_warehouse or d.t_warehouse, "posting_date": self.posting_date, "posting_time": self.posting_time }) # get actual stock at source warehouse d.actual_qty = previous_sle.get("qty_after_transaction") or 0 # validate qty during submit if d.docstatus == 1 and d.s_warehouse and not allow_negative_stock and d.actual_qty < d.transfer_qty: frappe.throw(_( "Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})" .format(d.idx, frappe.bold(d.s_warehouse), formatdate(self.posting_date), format_time(self.posting_time), frappe.bold(d.item_code))) + '<br><br>' + _("Available qty is {0}, you need {1}").format( frappe.bold(d.actual_qty), frappe.bold(d.transfer_qty)), NegativeStockError, title=_('Insufficient Stock'))
def send_shopfloor_activities_summary_report(): """ Similar to auto_email_report.send(), but renders the report in to a jinja template to allow for more flexibility """ # Get auto email report auto_email_report = frappe.get_doc( "Auto Email Report", "Horizon Global (PTA): Shopfloor Activities Summary") report = frappe.get_doc('Report', auto_email_report.report) # Get report content columns, data = report.get_data(limit=auto_email_report.no_of_rows or 100, user=auto_email_report.user, filters=auto_email_report.filters, as_dict=True) # Render template date_time = global_date_format(now()) + ' ' + format_time(now()) report_doctype = frappe.db.get_value('Report', auto_email_report.report, 'ref_doctype') report_html_data = frappe.render_template( 'quality_management_system/process/report/shopfloor_activities_summary/shopfloor_activities_summary_jinja.html', { 'title': auto_email_report.name, 'description': auto_email_report.description, 'date_time': date_time, 'columns': columns, 'data': data, 'report_url': get_url_to_report(auto_email_report.report, auto_email_report.report_type, report_doctype), 'report_name': auto_email_report.report, 'edit_report_settings': get_link_to_form('Auto Email Report', auto_email_report.name), 'site_url': get_url() }) # Later for testing: create PDF and attach # file_name = "test_dirk7.html" # from frappe.utils.file_manager import save_file # my_file = save_file(file_name, report_html_data, "Workstation", # "MagnaFlux Machine", "Home/Attachments") # Send email, according to Auto Email Report settings attachments = None message = report_html_data frappe.sendmail(recipients=auto_email_report.email_to.split(), subject=auto_email_report.name, message=message, attachments=attachments, reference_doctype=auto_email_report.doctype, reference_name=auto_email_report.name)
def get_chart_data(filters, columns): # for example # labels = ["0:00","4:00","8:00", "12:00","16:00","20:00"] lab_list = [] time_list = [] for i in range(len(columns)): if i + 1 < len(columns): time_list.append((columns[i], columns[i + 1])) lab_list.append( format_time(columns[i]) + "-" + format_time(columns[i + 1])) if filters.get("from_date") == filters.get("to_date"): labels = lab_list else: labels = columns[:-1] data_vals = get_data_vals(time_list) data = [] datasets = [] for l in data_vals: # frappe.msgprint(cstr(l)) datasets.append({'title': '℃', 'values': l}) data.append(l) # for example # datasets.append({'title': 'Temperature', 'values': [41,40,41,45,41,44]}) # datasets.append({'title': 'Temperature', 'values': [36,-38,45,42,33,30]}) chart = { "data": { 'labels': labels, 'datasets': datasets }, "colors": ['light-blue'] * len(datasets), "isNavigable": 1 } chart["type"] = "bar" chart["barOptions"] = {"spaceRatio": 0} return chart, data, labels
def validate_posting_date_for_negative_stock(self): if frappe.defaults.get_global_default('allow_negative_stock') and frappe.defaults.get_global_default('auto_accounting_for_stock'): items = self.get_items_and_warehouses() for item in self.get("items"): value = frappe.db.sql("""select voucher_type, voucher_no, posting_date, posting_time from `tabStock Ledger Entry` where voucher_type in ("Sales Invoice","Delivery Note") and item_code = %(item_code)s and timestamp(posting_date, posting_time) <= timestamp(%(date)s, %(time)s) and warehouse = %(warehouse)s and qty_after_transaction < 0""", {"date":self.posting_date, "time":self.posting_time,"item_code":item.item_code,"warehouse":item.t_warehouse},as_dict=1) if value: frappe.throw(_('The Posting date in this Stock Entry is after {0} {1} in {2}: <a href="#Form/{2}/{3}">{3}</a> Stock entries need to be before').format( formatdate(self.posting_date), format_time(self.posting_time), value[0].voucher_type, value[0].voucher_no))
def test_format_time_forced_broken_locale(self): # Test with forced time formats # Currently format_time defaults to HH:mm:ss if the locale is # broken, so this is an expected failure. lang = frappe.local.lang try: # Force fallback from Babel frappe.local.lang = 'FAKE' self.assertEqual(format_time(test_time, 'ss:mm:HH'), test_date_obj.strftime('%S:%M:%H')) finally: frappe.local.lang = lang
def set_actual_qty(self): allow_negative_stock = cint( frappe.db.get_value("Stock Settings", fieldname="allow_negative_stock")) for d in self.get("items"): # RESEARCH s_warehouse_previous_sle = get_previous_sle({ "item_code": d.item_code, "warehouse": d.s_warehouse, "posting_date": self.posting_date, "posting_time": self.posting_time }) """ On submitting Transfer Receive, we have to check from Transfer Buffer Warehouse. not source warehouse but still we have to give the actual qty at source """ buffer_warehouse_previous_sle = get_previous_sle({ "item_code": d.item_code, "warehouse": self.transfer_buffer_warehouse, "posting_date": self.posting_date, "posting_time": self.posting_time }) # get actual stock at source warehouse d.actual_qty = s_warehouse_previous_sle.get( "qty_after_transaction") or 0 test_actual_qty = self.purpose == "Transfer Issue" and d.actual_qty or buffer_warehouse_previous_sle.get( "qty_after_transaction") # validate qty during submit if d.docstatus == 1 and not allow_negative_stock and test_actual_qty < d.transfer_qty: frappe.throw(_( "Row {0}: Qty not available for {4} in warehouse {1} at posting time of the entry ({2} {3})" ).format(d.idx, frappe.bold(d.s_warehouse), formatdate(self.posting_date), format_time(self.posting_time), frappe.bold(d.item_code)) + '<br><br>' + _("Available qty is {0}, you need {1}").format( frappe.bold(d.actual_qty), frappe.bold(d.transfer_qty)), NegativeStockError, title=_('Insufficient Stock'))
def get_html_table(self, columns=None, data=None): date_time = global_date_format(now()) + ' ' + format_time(now()) report_doctype = frappe.db.get_value('Report', self.report, 'ref_doctype') return frappe.render_template('frappe/templates/emails/auto_email_report.html', { 'title': self.name, 'description': self.description, 'date_time': date_time, 'columns': columns, 'data': data, 'report_url': get_url_to_report(self.report, self.report_type, report_doctype), 'report_name': self.report, 'edit_report_settings': get_link_to_form('Auto Email Report', self.name) })
def create_checkin(self): emp = frappe.get_doc("Employee", self.employee) if not emp.default_shift: frappe.throw(_("""Employee should to have Default Shift""")) shift = frappe.get_doc("Shift Type", emp.default_shift) ec = frappe.get_doc( frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime( formatdate(self.date, 'YYYY-mm-dd') + ' ' + format_time(shift.start_time if self.log_type == 'IN' else shift.end_time)), "employee_checkin_request": self.name })) ec.insert()
def format_value(value, df=None, doc=None, currency=None, translated=False, format=None): '''Format value based on given fieldtype, document reference, currency reference. If docfield info (df) is not given, it will try and guess based on the datatype of the value''' if isinstance(df, str): df = frappe._dict(fieldtype=df) if not df: df = frappe._dict() if isinstance(value, datetime.datetime): df.fieldtype = 'Datetime' elif isinstance(value, datetime.date): df.fieldtype = 'Date' elif isinstance(value, datetime.timedelta): df.fieldtype = 'Time' elif isinstance(value, int): df.fieldtype = 'Int' elif isinstance(value, float): df.fieldtype = 'Float' else: df.fieldtype = 'Data' elif (isinstance(df, dict)): # Convert dict to object if necessary df = frappe._dict(df) if value is None: value = "" elif translated: value = frappe._(value) if not df: return value elif df.get("fieldtype") == "Date": return formatdate(value) elif df.get("fieldtype") == "Datetime": return format_datetime(value) elif df.get("fieldtype") == "Time": return format_time(value) elif value == 0 and df.get("fieldtype") in ( "Int", "Float", "Currency", "Percent") and df.get("print_hide_if_no_value"): # this is required to show 0 as blank in table columns return "" elif df.get("fieldtype") == "Currency": default_currency = frappe.db.get_default("currency") currency = currency or get_field_currency(df, doc) or default_currency return fmt_money(value, precision=get_field_precision(df, doc), currency=currency, format=format) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # I don't know why we support currency option for float currency = currency or get_field_currency(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp) == 1 or cint(temp[1]) == 0: precision = 0 return fmt_money(value, precision=precision, currency=currency) elif df.get("fieldtype") == "Percent": return "{}%".format(flt(value, 2)) elif df.get("fieldtype") in ("Text", "Small Text"): if not re.search(r"(<br|<div|<p)", value): return frappe.safe_decode(value).replace("\n", "<br>") elif df.get("fieldtype") == "Markdown Editor": return frappe.utils.markdown(value) elif df.get("fieldtype") == "Table MultiSelect": meta = frappe.get_meta(df.options) link_field = [df for df in meta.fields if df.fieldtype == 'Link'][0] values = [v.get(link_field.fieldname, 'asdf') for v in value] return ', '.join(values) elif df.get("fieldtype") == "Duration": hide_days = df.hide_days return format_duration(value, hide_days) elif df.get("fieldtype") == "Text Editor": return "<div class='ql-snow'>{}</div>".format(value) return value
def format_value(value, df=None, doc=None, currency=None, translated=False): '''Format value based on given fieldtype, document reference, currency reference. If docfield info (df) is not given, it will try and guess based on the datatype of the value''' if isinstance(df, string_types): df = frappe._dict(fieldtype=df) if not df: df = frappe._dict() if isinstance(value, datetime.datetime): df.fieldtype = 'Datetime' elif isinstance(value, datetime.date): df.fieldtype = 'Date' elif isinstance(value, datetime.timedelta): df.fieldtype = 'Time' elif isinstance(value, int): df.fieldtype = 'Int' elif isinstance(value, float): df.fieldtype = 'Float' else: df.fieldtype = 'Data' elif (isinstance(df, dict)): # Convert dict to object if necessary df = frappe._dict(df) if value is None: value = "" elif translated: value = frappe._(value) if not df: return value elif df.get("fieldtype")=="Date": return formatdate(value) elif df.get("fieldtype")=="Datetime": return format_datetime(value) elif df.get("fieldtype")=="Time": return format_time(value) elif value==0 and df.get("fieldtype") in ("Int", "Float", "Currency", "Percent") and df.get("print_hide_if_no_value"): # this is required to show 0 as blank in table columns return "" elif df.get("fieldtype") == "Currency" or (df.get("fieldtype")=="Float" and (df.options or "").strip()): return fmt_money(value, precision=get_field_precision(df, doc), currency=currency if currency else (get_field_currency(df, doc) if doc else None)) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp)==1 or cint(temp[1])==0: precision = 0 return fmt_money(value, precision=precision) elif df.get("fieldtype") == "Percent": return "{}%".format(flt(value, 2)) elif df.get("fieldtype") in ("Text", "Small Text"): if not re.search("(\<br|\<div|\<p)", value): return value.replace("\n", "<br>") return value
def get_report_content(company, customer_name, from_date=None, to_date=None): """Returns html for the report in PDF format""" settings_doc = frappe.get_single("Customer Statements Sender") if not from_date: from_date = get_first_day(today()).strftime("%Y-%m-%d") if not to_date: to_date = today() # Get General Ledger report content report_gl = frappe.get_doc("Report", "General Ledger") report_gl_filters = { "company": company, "party_type": "Customer", "party": [customer_name], "from_date": from_date, "to_date": to_date, "group_by": "Group by Voucher (Consolidated)", } columns_gl, data_gl = report_gl.get_data(limit=500, user="******", filters=report_gl_filters, as_dict=True) # Add serial numbers columns_gl.insert(0, frappe._dict(fieldname="idx", label="", width="30px")) for i in range(len(data_gl)): data_gl[i]["idx"] = i + 1 # Get ageing summary report content data_ageing = [] labels_ageing = [] if settings_doc.no_ageing != 1: report_ageing = frappe.get_doc("Report", "Accounts Receivable Summary") report_ageing_filters = { "company": company, "ageing_based_on": "Posting Date", "report_date": datetime.datetime.today(), "range1": 30, "range2": 60, "range3": 90, "range4": 120, "customer": customer_name, } columns_ageing, data_ageing = report_ageing.get_data( limit=50, user="******", filters=report_ageing_filters, as_dict=True) labels_ageing = {} for col in columns_ageing: if "range" in col["fieldname"]: labels_ageing[col["fieldname"]] = col["label"] # Get Letter Head no_letterhead = bool( frappe.db.get_single_value("Customer Statements Sender", "no_letter_head")) letter_head = frappe._dict( printview.get_letter_head(settings_doc, no_letterhead) or {}) if letter_head.content: letter_head.content = frappe.utils.jinja.render_template( letter_head.content, {"doc": settings_doc.as_dict()}) # Render Template date_time = global_date_format(now()) + " " + format_time(now()) currency = frappe.db.get_value("Company", company, "default_currency") report_html_data = frappe.render_template( "erpnext_customer_statements_sender/templates/report/customer_statement_jinja.html", { "title": "Customer Statement for {0}".format(customer_name), "description": "Customer Statement for {0}".format(customer_name), "date_time": date_time, "columns": columns_gl, "data": data_gl, "report_name": "Customer Statement for {0}".format(customer_name), "filters": report_gl_filters, "currency": currency, "letter_head": letter_head.content, "billing_address": get_billing_address(customer_name), "labels_ageing": labels_ageing, "data_ageing": data_ageing, }, ) return report_html_data
def format_value(value, df=None, doc=None, currency=None, translated=False): '''Format value based on given fieldtype, document reference, currency reference. If docfield info (df) is not given, it will try and guess based on the datatype of the value''' if isinstance(df, string_types): df = frappe._dict(fieldtype=df) if not df: df = frappe._dict() if isinstance(value, datetime.datetime): df.fieldtype = 'Datetime' elif isinstance(value, datetime.date): df.fieldtype = 'Date' elif isinstance(value, datetime.timedelta): df.fieldtype = 'Time' elif isinstance(value, int): df.fieldtype = 'Int' elif isinstance(value, float): df.fieldtype = 'Float' else: df.fieldtype = 'Data' elif (isinstance(df, dict)): # Convert dict to object if necessary df = frappe._dict(df) if value is None: value = "" elif translated: value = frappe._(value) if not df: return value elif df.get("fieldtype") == "Date": return formatdate(value) elif df.get("fieldtype") == "Datetime": return format_datetime(value) elif df.get("fieldtype") == "Time": return format_time(value) elif value == 0 and df.get("fieldtype") in ( "Int", "Float", "Currency", "Percent") and df.get("print_hide_if_no_value"): # this is required to show 0 as blank in table columns return "" elif df.get("fieldtype") == "Currency" or (df.get("fieldtype") == "Float" and (df.options or "").strip()): return fmt_money(value, precision=get_field_precision(df, doc), currency=currency if currency else (get_field_currency(df, doc) if doc else None)) elif df.get("fieldtype") == "Float": precision = get_field_precision(df, doc) # show 1.000000 as 1 # options should not specified if not df.options and value is not None: temp = cstr(value).split(".") if len(temp) == 1 or cint(temp[1]) == 0: precision = 0 return fmt_money(value, precision=precision) elif df.get("fieldtype") == "Percent": precision = get_field_precision(df, doc) formatted = fmt_money(value, precision=get_field_precision(df, doc)) return "{}%".format(formatted) elif df.get("fieldtype") in ("Text", "Small Text"): if not re.search("(\<br|\<div|\<p)", value): return value.replace("\n", "<br>") return value
def get_report_content(company, customer_name, from_date=None, to_date=None): '''Returns html for the report in PDF format''' settings_doc = frappe.get_single('Customer Statements Sender') if not from_date: from_date = get_first_day(today()).strftime("%Y-%m-%d") if not to_date: to_date = today() # Get General Ledger report content report_gl = frappe.get_doc('Report', 'General Ledger') report_gl_filters = { 'company': company, 'party_type': 'Customer', 'party': [customer_name], 'from_date': from_date, 'to_date': to_date, 'group_by': 'Group by Voucher (Consolidated)' } columns_gl, data_gl = report_gl.get_data(limit=500, user="******", filters=report_gl_filters, as_dict=True) # Add serial numbers columns_gl.insert(0, frappe._dict(fieldname='idx', label='', width='30px')) for i in range(len(data_gl)): data_gl[i]['idx'] = i + 1 # Get ageing summary report content data_ageing = [] labels_ageing = [] if settings_doc.no_ageing != 1: report_ageing = frappe.get_doc('Report', 'Accounts Receivable Summary') report_ageing_filters = { 'company': company, 'ageing_based_on': 'Posting Date', 'report_date': datetime.datetime.today(), 'range1': 30, 'range2': 60, 'range3': 90, 'range4': 120, 'customer': customer_name } columns_ageing, data_ageing = report_ageing.get_data( limit=50, user="******", filters=report_ageing_filters, as_dict=True) labels_ageing = {} for col in columns_ageing: if 'range' in col['fieldname']: labels_ageing[col['fieldname']] = col['label'] # Get Letter Head no_letterhead = bool( frappe.db.get_single_value('Customer Statements Sender', 'no_letter_head')) letter_head = frappe._dict( printview.get_letter_head(settings_doc, no_letterhead) or {}) if letter_head.content: letter_head.content = frappe.utils.jinja.render_template( letter_head.content, {"doc": settings_doc.as_dict()}) # Render Template date_time = global_date_format(now()) + ' ' + format_time(now()) currency = frappe.db.get_value('Company', company, 'default_currency') report_html_data = frappe.render_template( 'erpnext_customer_statements_sender/templates/report/customer_statement_jinja.html', { 'title': 'Customer Statement for {0}'.format(customer_name), 'description': 'Customer Statement for {0}'.format(customer_name), 'date_time': date_time, 'columns': columns_gl, 'data': data_gl, 'report_name': 'Customer Statement for {0}'.format(customer_name), 'filters': report_gl_filters, 'currency': currency, 'letter_head': letter_head.content, 'billing_address': get_billing_address(customer_name), 'labels_ageing': labels_ageing, 'data_ageing': data_ageing }) return report_html_data
def test_format_time_forced(self): # Test with forced time formats self.assertEqual(format_time(test_time, 'ss:mm:HH'), test_date_obj.strftime('%S:%M:%H'))
def create_checkin(self): emp = frappe.get_doc("Employee", self.employee) if not emp.default_shift: frappe.throw(_("""Employee should to have Default Shift""")) shift = frappe.get_doc("Shift Type", emp.default_shift) if self.is_manual: ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(self.from_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(self.to_time)), "employee_checkin_request": self.name })) ec.insert() elif self.enable_two_period_in_ecr==1: if self.period_type=='First': if self.log_type=='ALL': ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_time if self.log_type=='IN' else shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() elif self.period_type=='Second': if self.log_type=='ALL': ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_second_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_second_period if self.log_type=='IN' else shift.end_time)), "employee_checkin_request": self.name })) ec.insert() elif self.period_type=='ALL': if self.log_type=='ALL': ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.end_first_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_second_period)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: frappe.throw(_("""If the Period Type equal ALL, the Log Type should to be ALL""")) else: if self.log_type=='ALL': ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "IN", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_time)), "employee_checkin_request": self.name })) ec.insert() ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": "OUT", "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.end_time)), "employee_checkin_request": self.name })) ec.insert() else: ec = frappe.get_doc(frappe._dict({ "doctype": "Employee Checkin", "employee": self.employee, "log_type": self.log_type, "time": get_datetime(formatdate(self.date,'YYYY-mm-dd')+' '+format_time(shift.start_time if self.log_type=='IN' else shift.end_time)), "employee_checkin_request": self.name })) ec.insert()