def _interval_dates(self, frequency, company): """ Method used to compute the theoretical date from which account move lines should be fetched @param {string} frequency: a valid value of the selection field on the object (daily, monthly, annually) frequencies are literal (daily means 24 hours and so on) @param {recordset} company: the company for which the closing is done @return {dict} the theoretical date from which account move lines are fetched. date_stop date to which the move lines are fetched, always now() the dates are in their Odoo Database string representation """ date_stop = datetime.utcnow() interval_from = None name_interval = '' if frequency == 'daily': interval_from = date_stop - timedelta(days=1) name_interval = _('Daily Closing') elif frequency == 'monthly': month_target = date_stop.month > 1 and date_stop.month - 1 or 12 year_target = month_target < 12 and date_stop.year or date_stop.year - 1 interval_from = date_stop.replace(year=year_target, month=month_target) name_interval = _('Monthly Closing') elif frequency == 'annually': year_target = date_stop.year - 1 interval_from = date_stop.replace(year=year_target) name_interval = _('Annual Closing') return { 'interval_from': FieldDateTime.to_string(interval_from), 'date_stop': FieldDateTime.to_string(date_stop), 'name_interval': name_interval }
def index(self, **kwargs): method = request.httprequest.method if method == "GET": return request.render("hr_sf.attendance_index") elif method == "POST": Attendance = request.env["hr.attendance"].sudo() Employee = request.env["hr.employee"].sudo() UploadLog = request.env["hr_sf.attendance_upload_log"].sudo() try: upload_file = kwargs.get("upload_file", None) source = kwargs.get("source", None) if upload_file is None: raise Exception("can not get upload file from http post data") upload_file_content = upload_file.stream.read() sniffer = csv.Sniffer() dialect = sniffer.sniff(upload_file_content, delimiters=',\t') rows = csv.reader(upload_file_content.splitlines(), dialect=dialect) upload_log = None if rows: base64_file = base64.standard_b64encode(upload_file_content) upload_log = UploadLog.create({"upload_file": base64_file, "file_name": upload_file.filename, "date": Datetime.now(), "source": source}) upload_log_id = upload_log.id employees = Employee.search([]) employee_ids = dict(employees.mapped(lambda r: (r.internal_code, r.id))) line_number = 0 values = [] for row in rows: code, name, year, month, day, hour, minute = row[0:7] location = str(int(row[7])) dt_str = "%s-%s-%s %s:%s:00" % (year, month, day, hour, minute) dt = Datetime.from_string(dt_str) dt = dt - datetime.timedelta(hours=8) odoo_dt_str = Datetime.to_string(dt) exist_count = Attendance.search_count([("code", "=", code), ("name", "=", odoo_dt_str)]) if exist_count <= 0: emp_id = employee_ids.get(code, None) if emp_id is not None: # Attendance.create({"employee_id": emp_id, "name": odoo_dt_str, "location": location, # "action": "action", "upload_log_id": upload_log_id}) values.append({"employee_id": emp_id, "name": odoo_dt_str, "location": location, "action": "action", "upload_log_id": upload_log_id, "forget_card": False}) else: raise Exception("error in line:%d,employee with code:%s not found" % (line_number, code)) line_number += 1 for value in values: Attendance.create(value) return request.render("hr_sf.attendance_upload_finish", {"import_count": len(values)}) except Exception, e: request.env.cr.rollback() return e.message or e.value
def UTC_String_To_TW_TZ(timestr): if not timestr: return None dt_time = UTC_Datetime_To_TW_TZ(timestr) return Datetime.to_string(dt_time)
def attendance_per_location(self, date=None, location=None): if not date: date = Date.today() dt_from = datetime.datetime.strptime("%s 00:00:00" % date, DEFAULT_SERVER_DATETIME_FORMAT) - datetime.timedelta( hours=8) dt_to = datetime.datetime.strptime("%s 23:59:59" % date, DEFAULT_SERVER_DATETIME_FORMAT) - datetime.timedelta( hours=8) if not location: location = "1" Attendance = request.env["hr.attendance"].sudo() Employee = request.env["hr.employee"].sudo() values = {} domain = [] if date: domain.append(("name", ">=", Datetime.to_string(dt_from))) domain.append(("name", "<=", Datetime.to_string(dt_to))) # if location: # domain.append(("location", "=", location)) all_employees = Employee.search([]) emp_attendances_values = [] for emp in all_employees: attendance = dict() attendance["name"] = emp.name attendance["dep"] = emp.department_id.name records = Attendance.search(domain + [("employee_id", "=", emp.id)], order="name") if records and records[-1].location: latest_rec = records[-1] attendance["state"] = "打卡" dt = UTC_Datetime_To_TW_TZ(latest_rec.name) date_part = dt.strftime(DEFAULT_SERVER_DATE_FORMAT) time_part = dt.strftime(DEFAULT_SERVER_TIME_FORMAT) attendance["date"] = date_part attendance["time"] = time_part attendance["location"] = latest_rec.location else: attendance["state"] = "未打卡" attendance["date"] = None attendance["time"] = None attendance["location"] = None leave_time = emp.get_holiday_on(date) attendance["leave"] = string.join(leave_time.keys(), ",") if leave_time else None emp_attendances_values.append(attendance) # attendance_grouped_by_location = itertools.groupby(emp_attendances_values, key=lambda a: a["location"]) attendances = defaultdict(lambda: list()) for attendance in emp_attendances_values: attendances[attendance["location"]].append(attendance) # or _("not attended") print_time = UTC_Datetime_To_TW_TZ(Datetime.now()) values["print_time"] = Datetime.to_string(print_time) values["date"] = date values["location"] = location values["emp_attendances"] = attendances keys = sorted(attendances.keys()) if None in keys: keys.remove(None) keys.append(None) values["attendance_keys"] = keys values["action_count"] = len(filter(lambda a: a.get("date", None), emp_attendances_values)) values["un_action_count"] = len(filter(lambda a: not a.get("date", None), emp_attendances_values)) return request.render("hr_sf.attendance_per_location", values)