def onchange_range(self, dtrange, date_from, date_till, resetRange=False): value = {} res = { "value" : value } if not date_from or resetRange: if dtrange == "month": date_from = util.getFirstOfLastMonth() elif dtrange == "week": day = util.strToDate(util.currentDate()) day = day - relativedelta(days=(7+day.weekday())) date_from = util.dateToStr(day) else: day = util.strToDate(util.currentDate()) day = day - relativedelta(days=1) date_from = util.dateToStr(day) if dtrange == "month": dt_date_from = util.strToDate(date_from) date_till = util.dateToStr(dt_date_from + relativedelta(months=1,days=-1)) elif dtrange == "week": dt_date_from = util.strToDate(date_from) weekday = dt_date_from.weekday() date_till = util.dateToStr(dt_date_from + relativedelta(days=weekday+(6-weekday))) else: date_till = date_from value["date_from"] = date_from value["date_till"] = date_till return res
def _update_pos_rate(self, cr, uid, start_date=None, history_months=1, nofilter=False, context=None): ranges = [] if not nofilter: if not start_date: cr.execute("SELECT MAX(date_order) FROM pos_order") res = cr.fetchone() start_date = res and res[0] and util.strToDate(res[0]) or datetime.now() start_date = start_date - relativedelta(months=history_months) start_date = util.dateToStr(start_date) ranges.append("o.date_order >= '%s'" % start_date) if history_months: history_start_dt = util.strToDate(start_date) - relativedelta(years=1) history_delta = relativedelta(weeks=(history_months*2)) history_start = util.dateToStr(history_start_dt - history_delta) history_end = util.dateToStr(history_start_dt + history_delta) ranges.append("(o.date_order >= '%s' AND o.date_order <= '%s')" % (history_start, history_end)) rangeStr = ranges and "AND (%s)" % " OR ".join(ranges) or "" query = ("SELECT p.id, COUNT(l) FROM product_product p " " INNER JOIN product_template pt ON pt.id = p.product_tmpl_id " " LEFT JOIN pos_order_line l ON l.product_id = p.id " " LEFT JOIN pos_order o ON o.id = l.order_id " " WHERE pt.available_in_pos %s " " GROUP BY 1 " % rangeStr) cr.execute(query) res = cr.fetchall() total = 0.0 for product_id, usage in res: if usage: total += usage if total: for product_id, usage in res: if usage: rate = (usage / total)*100.0 self.write(cr, uid, [product_id], {"pos_rate" : rate}, context=context) else: self.write(cr, uid, [product_id], {"pos_rate" : 0.0}, context=context) # reset non used cr.execute("UPDATE product_product SET pos_rate = 0 WHERE product_tmpl_id IN " " (SELECT pt.id FROM product_template pt WHERE NOT pt.available_in_pos) ") # update templates cr.execute("UPDATE product_template SET tmpl_pos_rate = 0") cr.execute("UPDATE product_template " " SET tmpl_pos_rate = t.pos_rate " " FROM ( " " SELECT product_tmpl_id, SUM(p.pos_rate) AS pos_rate " " FROM product_product p " " GROUP BY 1 " " ) t " " WHERE t.product_tmpl_id = id AND t.pos_rate IS NOT NULL")
def interval_hours_without_leaves(self, cr, uid, sid, dt_from, dt_to, resource=False, context=None): if not sid: return 0.0 leaves = self.get_leave_intervals(cr, uid, sid, resource, dt_from, dt_to, context=None) hours = 0.0 step = relativedelta(days=1) while (dt_from <= dt_to): cur_date = util.dateToStr(dt_from) if not cur_date in leaves: cr.execute( "SELECT hour_from,hour_to FROM resource_calendar_attendance WHERE dayofweek='%s' and calendar_id=%s ORDER BY hour_from", (dt_from.weekday(), sid)) der = cr.fetchall() for (hour_from, hour_to) in der: hours += math.fabs(hour_to - hour_from) dt_from += step return hours
def working_day_count(self, cr, uid, sid, dt_from, dt_to, resource=False, context=None): if not sid: return 0 dt_from = util.timeToDate(dt_from) dt_to = util.timeToDate(dt_to) attent_obj = self.pool.get("resource.calendar.attendance") leaves = self.get_leave_intervals(cr, uid, sid, resource, dt_from, dt_to, context=context) step = relativedelta(days=1) working_days = 0 while (dt_from <= dt_to): cur_date = util.dateToStr(dt_from) if not cur_date in leaves: attent_count = attent_obj.search_count( cr, uid, [('dayofweek', '=', str(dt_from.weekday())), ('calendar_id', '=', sid)]) if attent_count: working_days += 1 dt_from += step return working_days
def _cashreport_range(self, start_date=None, offset=0): if not start_date: start_date = util.currentDate() cashreport_name = _("Cashreport") date_from = start_date date_till = start_date f = format.LangFormat(self._cr, self._uid, self._context) # calc month if self.range == "month": dt_date_from = util.strToDate(util.getFirstOfMonth(start_date)) if offset: dt_date_from += relativedelta(months=offset) date_from = util.dateToStr(dt_date_from) date_till = util.getEndOfMonth(dt_date_from) month_name = helper.getMonthName(self._cr, self._uid, dt_date_from.month, context=self._context) cashreport_name = "%s - %s %s" % (cashreport_name, month_name, dt_date_from.year) # calc week elif self.range == "week": dt_date_from = util.strToDate(start_date) if offset: dt_date_from += relativedelta(weeks=offset) weekday = dt_date_from.weekday() dt_date_from = dt_date_from + relativedelta(days=-weekday) kw = dt_date_from.isocalendar()[1] date_from = util.dateToStr(dt_date_from) date_till = util.dateToStr(dt_date_from + relativedelta(days=weekday + (6 - weekday))) cashreport_name = _("%s - CW %s %s") % (cashreport_name, kw, dt_date_from.year) # calc date else: if offset: dt_date_from = util.strToDate(start_date) dt_date_from += relativedelta(days=offset) date_from = util.dateToStr(dt_date_from) date_till = date_from cashreport_name = _("%s - %s") % (cashreport_name, f.formatLang(date_from, date=True)) return (date_from, date_till, cashreport_name)
def get_address(prefix): """ parse address data """ # simple get def get(name): arg = kwargs.get("%s_%s" % (prefix, name)) return arg and arg.strip() or "" firstname = get("firstname") lastname = get("lastname") email = get("email") if not firstname or not lastname or not email: return None name = "%s %s" % (lastname, firstname) city = get("city") zip_code = get("zip") res = { "name": name, "email": email, "street": get("street"), "zip": zip_code, "city": city } nationality = get("nationality") if nationality: res["nationality"] = nationality birthday_dt, birthday = util.tryParseDate(get("birthday")) if birthday_dt: res["birthday"] = util.dateToStr(birthday_dt) phone = get("phone") if phone: res["phone"] = phone city_values = city_obj.search_read(cr, hidden_uid, [("code", "=", zip)], ["name", "state_id"], context=context) for city_val in city_values: if re.sub("[^A-Za-z]", "", city) == re.sub("[^A-Za-z]", "", city_val["name"]): res["state_id"] = city_val["state_id"] res["city"] = city_val["name"] break return res
def get_leaves(self, cr, uid, sid, context=None): res = {} sheet = self.browse(cr, uid, sid, context) employee_obj = self.pool.get("hr.employee") contract = employee_obj._get_contract(cr, uid, sheet.employee_id.id, date_from=sheet.date_from, date_to=sheet.date_to, context=context) if contract: cr.execute( "SELECT id, name, date_from, date_to FROM resource_calendar_leaves " " WHERE resource_id = %s OR resource_id IS NULL " " AND ( (date_from >= %s AND date_from <= %s) " " OR (date_to >= %s AND date_to <= %s ) " " OR (date_from <= %s AND date_to >= %s ) )", (sheet.employee_id.resource_id.id, sheet.date_from, sheet.date_to, sheet.date_from, sheet.date_to, sheet.date_from, sheet.date_to)) for oid, name, leave_date_from, leave_date_to in cr.fetchall(): date_from = util.timeToDateStr(leave_date_from) if date_from < sheet.date_from: date_from = sheet.date_from date_to = util.timeToDateStr(leave_date_to) if date_to > sheet.date_to: date_to = sheet.date_to d_datefrom = util.strToDate(date_from) d_dateto = util.strToDate(date_to) d_cur = d_datefrom d_delta = relativedelta(days=1) while d_cur <= d_dateto: cur_date = util.dateToStr(d_cur) leaves = res.get(cur_date) if not leaves: leaves = [] res[cur_date] = leaves leaves.append((oid, name)) d_cur += d_delta return res
def onchange_unit(self, unit): value = {} res = {"value": value} if unit == "semester": reg_obj = self.pool["academy.registration"] semester_id = reg_obj._get_semester_id(self._cr, self._uid, self._context) value["sem_start_id"] = semester_id value["sem_end_id"] = semester_id value.update(self.onchange_sem(semester_id, semester_id)["value"]) elif unit == "period": period_obj = self.pool["account.period"] month = util.dateToStr(datetime.today() - relativedelta(months=1)) period_id = period_obj.search_id(self._cr, self._uid, [("date_start", "<=", month), ("date_stop", ">=", month)]) value["period_start_id"] = period_id value["period_end_id"] = period_id value.update(self.onchange_period(period_id, period_id)["value"]) return res
def holidays_validate(self, cr, uid, ids, context=None): """ Add Resource Leaves """ if super(hr_holidays, self).holidays_validate(cr, uid, ids, context=context): data_holiday = self.browse(cr, uid, ids, context=context) employee_obj = self.pool.get("hr.employee") obj_res_leave = self.pool.get('resource.calendar.leaves') for record in data_holiday: # only holidays from employees if record.holiday_type == 'employee' and record.type == 'remove': # get holiday date date_from = helper.strToLocalDateStr( cr, uid, record.date_from, context) date_to = util.dateToStr( util.getLastTimeOfDay( util.strToDate( helper.strToLocalDateStr( cr, uid, record.date_to, context)))) # get contract contract = employee_obj._get_contract( cr, uid, record.employee_id.id, date_from=date_from, date_to=date_to, context=context) if contract: vals = { 'name': record.name, 'calendar_id': contract["working_hours"].id, 'resource_id': record.employee_id.resource_id.id, 'date_from': date_from, 'date_to': date_to, 'holiday_id': record.id } leave_id = obj_res_leave.create(cr, uid, vals) self.write(cr, uid, ids, {'leave_id': leave_id}) return True return False
def _total_target(self, cr, uid, ids, field_name, arg, context=None): res = dict.fromkeys(ids, 0.0) working_hour_obj = self.pool.get("resource.calendar") employee_obj = self.pool.get("hr.employee") for daily_sheet in self.browse(cr, uid, ids, context): sheet = daily_sheet.sheet_id date_from = daily_sheet.name date_to = util.dateToStr( util.getLastTimeOfDay(util.strToDate(date_from))) contract = employee_obj._get_contract(cr, uid, sheet.employee_id.id, date_from=date_from, date_to=date_to, context=context) if contract: res[sheet.id] = working_hour_obj.interval_hours_without_leaves( cr, uid, contract["working_hours"].id, util.strToDate(contract["date_from"]), util.strToDate(contract["date_to"]), sheet.employee_id.resource_id.id) return res
def passed_range(self, cr, uid, id, dt_from, working_days, resource=False, context=None): if not id: return None dt_cur = util.timeToDate(dt_from) step = relativedelta(days=1) attent_obj = self.pool.get("resource.calendar.attendance") leaves = self.get_leave_intervals(cr, uid, id, resource, dt_from, context=context) res_dt_from = None res_dt_to = None iter_watchdog = 0 days_left = working_days while (days_left > 0): cur_date = util.dateToStr(dt_cur) if not cur_date in leaves: attent_ids = attent_obj.search( cr, uid, [('dayofweek', '=', str(dt_cur.weekday())), ('calendar_id', '=', id)]) if attent_ids: dt_first = None dt_last = None for attent in attent_obj.browse(cr, uid, attent_ids): dt_attent_from = dt_cur + relativedelta( hours=attent.hour_from) dt_attent_until = dt_cur + relativedelta( hours=attent.hour_to) if not dt_first or dt_first > dt_attent_from: dt_first = dt_attent_from if not dt_last or dt_last < dt_attent_until: dt_last = dt_attent_until if dt_from <= dt_first: iter_watchdog = 0 days_left -= 1 if not res_dt_from: res_dt_from = dt_first res_dt_to = dt_attent_until elif iter_watchdog > 7: #no days found break iter_watchdog += 1 dt_cur += step res = None if res_dt_from and res_dt_to: res = {"from": res_dt_from, "to": res_dt_to} elif res_dt_from: res = { "from": res_dt_from, "to": res_dt_from + relativedelta(days=working_days) } else: res = { "from": dt_from, "to": dt_from + relativedelta(days=working_days) } return res
def _prepare_invoice_data(self, cr, uid, contract, context=None): invoice = super(account_analytic_account, self)._prepare_invoice_data(cr, uid, contract, context=context) # invoice name to contract name invoice["name"] = contract.name # determine user user_id = contract.manager_id or contract.user_id if user_id: invoice["user_id"] = user_id.id # determine shop if contract.shop_id: invoice["shop_id"] = contract.shop_id.id else: # shop from template template = contract.template_id if template and template.shop_id: invoice["shop_id"] = template.shop_id.id else: parent = contract.parent_id if parent: # get shop from parent if parent.shop_id: invoice["shop_id"] = parent.shop_id.id else: # shop from autocreate shop_obj = self.pool["sale.shop"] shop_ids = shop_obj.search(cr, uid, [("autocreate_order_parent_id","=",parent.id)], limit=2) if not shop_ids: shop_ids = shop_obj.search(cr, uid, [("project_id","=",parent.id)], limit=2) # check if only one shop is assinged if len(shop_ids) == 1: invoice["shop_id"] = shop_ids[0] # performance period if contract.recurring_invoices: # get next date function def getNextDate(cur_date,sign=1): interval = contract.recurring_interval*sign if contract.recurring_rule_type == 'daily': return cur_date+relativedelta(days=+interval) elif contract.recurring_rule_type == 'weekly': return cur_date+relativedelta(weeks=+interval) elif contract.recurring_rule_type == 'monthly': return cur_date+relativedelta(months=+interval) else: return cur_date+relativedelta(years=+interval) cur_date = util.strToDate(contract.recurring_next_date or util.currentDate()) if contract.recurring_prepaid: invoice["perf_enabled"] = True invoice["perf_start"] = cur_date invoice["perf_end"] = getNextDate(cur_date) else: invoice["perf_enabled"] = True invoice["perf_start"] = getNextDate(cur_date,-1) invoice["perf_end"] = cur_date # first of month and last of month if contract.recurring_rule_type == 'monthly': invoice["perf_end"] = util.strToDate(util.getEndOfMonth(invoice["perf_end"])) if contract.recurring_interval > 0: interval = -(contract.recurring_interval-1) invoice["perf_start"] = util.strToDate(util.getFirstOfMonth(invoice["perf_end"]))+relativedelta(months=interval) # convert dt to str invoice["perf_start"] = util.dateToStr(invoice["perf_start"]) invoice["perf_end"] = util.dateToStr(invoice["perf_end"]) return invoice
def _recurring_task_create(self, cr, uid, ids, automatic=False, context=None): if context is None: context = {} task_ids = [] current_date = util.currentDate() if ids: contract_ids = ids else: contract_ids = self.search(cr, uid, [("use_tasks","=",True), ("recurring_task_next","<=", current_date), ("state","=", "open"), ("recurring_task","=", True), ("type", "=", "contract")]) if contract_ids: task_obj = self.pool["project.task"] recurring_task_obj = self.pool["account.analytic.recurring.task"] project_obj = self.pool["project.project"] f = format.LangFormat(cr, uid, context) cr.execute("SELECT company_id, array_agg(id) as ids FROM account_analytic_account WHERE id IN %s GROUP BY company_id", (tuple(contract_ids),)) for company_id, ids in cr.fetchall(): context_contract = dict(context, company_id=company_id, force_company=company_id) for contract in self.browse(cr, uid, ids, context=context_contract): project_ids = project_obj.search(cr, uid, [("analytic_account_id","=",contract.id)], context=context_contract) if not project_ids: raise Warning(_("No Project for generating tasks of contract %s found") % contract.name) project = project_obj.browse(cr, uid, project_ids[0], context=context_contract) try: # get interval interval = contract.recurring_task_interval rule = contract.recurring_rule_type next_date = contract.recurring_task_next or current_date if contract.recurring_task_rule == "daily": # daily dt_interval = relativedelta(days=interval) interval_name = f.formatLang(next_date, date=True) elif contract.recurring_task_rule == "weekly": # weekly dt_interval = relativedelta(weeks=interval) interval_name = _("%s WE%s") % (util.getYearStr(next_date), util.getWeek(next_date)) elif contract.recurring_task_rule == "monthly": # monthly dt_interval = relativedelta(months=interval) interval_name = helper.getMonthYear(cr, uid, next_date, context=context) else: # yearly interval_name = util.getYearStr(next_date) dt_interval = relativedelta(years=interval) # next date next_date = util.dateToStr(util.strToDate(next_date) + dt_interval) # execute task processed_tasks = 0 finished_tasks = 0 for recurring_task in contract.recurring_task_ids: task_values = self._recurring_task_prepare(cr, uid, project, recurring_task, interval_name, next_date, context=context_contract) if task_values: processed_tasks += 1 # execute task if it is not finished task_count = recurring_task.count if not recurring_task.repeat or task_count < recurring_task.repeat: task_count = recurring_task.count + 1 task_ids.append(task_obj.create(cr, uid, task_values, context=context_contract)) recurring_task_obj.write(cr, uid, [recurring_task.id], {"count": task_count}, context=context_contract) # check if task is finished if recurring_task.repeat and task_count >= recurring_task.repeat: finished_tasks += 1 # check if all tasks are finished if finished_tasks and finished_tasks == processed_tasks: values["recurring_task"] = False # update contract values = {"recurring_task_next": next_date} self.write(cr, uid, [contract.id], values, context=context) # commit if automatic if automatic: cr.commit() except Exception: # log error if automatic if automatic: cr.rollback() _logger.exception("Fail to create recurring task for contract %s [%s]", (contract.name, contract.code)) else: raise return task_ids
def _import_ofx(self, cr, uid, wizard, context=None): statement_obj = self.pool["account.bank.statement"] line_obj = self.pool["account.bank.statement.line"] stat_id = util.active_ids(context, "account.bank.statement") if not stat_id: return False stat = statement_obj.browse(cr, uid, stat_id, context=context) datas = wizard.ofx_datas if not datas: return False datab = base64.decodestring(datas) if not datab: return False if stat.state != "draft": return False fp = StringIO(datab) ofx = OfxParser.parse(fp) if not ofx: return False for account in ofx.accounts: statement = account.statement statement_date = util.dateToStr(statement.start_date) balance_end = statement.balance balance_start = balance_end lines = [] for trans in statement.transactions: trans_date = datetime_field.context_timestamp( cr, uid, timestamp=trans.date, context=context) balance_start -= trans.amount line = (0, 0, { "sequence": len(lines) + 1, "name": trans.memo, "date": util.dateToStr(trans_date), "ref": trans.id, "amount": float(trans.amount) }) lines.append(line) values = {} # change journal journal_id = stat.journal_id.id onchange_values = statement_obj.onchange_journal_id( cr, uid, [], journal_id).get("value") if onchange_values: values.update(onchange_values) # change date onchange_values = statement_obj.onchange_date( cr, uid, [], statement_date, values.get("company_id")).get("value") if onchange_values: values.update(onchange_values) values.update({ "date": statement_date, "journal_id": journal_id, "balance_end_real": float(balance_end), "balance_start": float(balance_start), "line_ids": lines }) # remove old lines line_ids = line_obj.search(cr, uid, [("statement_id", "=", stat.id)]) if line_ids: line_obj.unlink(cr, uid, line_ids) # update statement statement_id = statement_obj.write(cr, uid, [stat.id], values, context=context) return True
def get_timesheet_data(self, cr, uid, oid, context=None): #inner function for get lines def _get_attendances(in_days, in_day): data = in_days.get(in_day, None) if data == None: data = {} in_days[in_day] = data attendance = data.get("attendances", None) if attendance == None: attendance = [] in_days[in_day]["attendances"] = attendance return attendance timesheet = self.browse(cr, uid, oid, context) attendance_obj = self.pool.get("hr.attendance") attendance_ids = attendance_obj.search( cr, uid, [("sheet_id", "=", timesheet.id)], order="name asc") next_range = {"day": None, "from": None, "to": None} days = {} for att in attendance_obj.browse(cr, uid, attendance_ids, context): cur_day = util.timeToDateStr(att.name) if att.action == "sign_in": next_range = { "day": cur_day, "from": helper.strToLocalTimeStr(cr, uid, att.name, context), "to": None } _get_attendances(days, cur_day).append(next_range) elif att.action == "sign_out": if next_range["day"] != cur_day: next_range = { "day": cur_day, "from": None, "to": helper.strToLocalTimeStr(cr, uid, att.name, context) } _get_attendances(days, cur_day).append(next_range) else: next_range["to"] = helper.strToLocalTimeStr( cr, uid, att.name, context) leaves = self.get_leaves(cr, uid, oid, context) date_from = util.strToDate(timesheet.date_from) date_to = util.strToDate(timesheet.date_to) date_cur = date_from delta_day = relativedelta(days=1) range_open = False while date_cur <= date_to: date_cur_str = util.dateToStr(date_cur) attendances = _get_attendances(days, date_cur_str) days[date_cur_str]['total_attendance_day'] = 0.0 days[date_cur_str]['total_timesheet_day'] = 0.0 days[date_cur_str]['total_difference_day'] = 0.0 leaves_for_day = leaves.get(date_cur_str) if leaves_for_day: days[date_cur_str]["leaves"] = leaves_for_day if not attendances and range_open: attendances.append({ "day": date_cur_str, "from": date_cur_str + " 00:00:00", "to": date_cur_str + " 24:00:00" }) elif attendances: if range_open: attendances[0]["from"] = date_cur_str + " 00:00:00" range_open = False last_range = attendances[-1] if not last_range.get("to"): range_open = True last_range["to"] = util.timeToStr(date_cur + delta_day) date_cur += delta_day #get total days cr.execute( 'SELECT day.name, day.total_attendance, day.total_timesheet, day.total_difference\ FROM hr_timesheet_sheet_sheet AS sheet \ LEFT JOIN hr_timesheet_sheet_sheet_day AS day \ ON (sheet.id = day.sheet_id \ AND day.name IN %s) \ WHERE sheet.id = %s', (tuple(days.keys()), oid)) for total_day in cr.fetchall(): if total_day[0]: days[total_day[0]]['total_attendance_day'] = total_day[1] days[total_day[0]]['total_timesheet_day'] = total_day[2] days[total_day[0]]['total_difference_day'] = total_day[3] #get analytic lines line_obj = self.pool.get("hr.analytic.timesheet") for key, value in days.items(): value["lines"] = line_obj.search(cr, uid, [("date", "=", key), ("sheet_id", "=", timesheet.id)], order="id asc") return days
def get_leave_intervals(self, cr, uid, id, resource_id=None, start_datetime=None, end_datetime=None, context=None): """Get the leaves of the calendar. Leaves can be filtered on the resource, the start datetime or the end datetime. :param int resource_id: the id of the resource to take into account when computing the leaves. If not set, only general leaves are computed. If set, generic and specific leaves are computed. :param datetime start_datetime: if provided, do not take into account leaves ending before this date. :param datetime end_datetime: if provided, do not take into account leaves beginning after this date. :return list leaves: list of tuples (start_datetime, end_datetime) of leave intervals """ resource_cal_leaves = self.pool.get('resource.calendar.leaves') dt_leave = [] query = "SELECT id FROM resource_calendar_leaves AS l WHERE ( l.calendar_id IS NULL OR calendar_id=%s )" % ( str(id), ) if resource_id: query += " AND ( l.resource_id IS NULL OR l.resource_id = %s )" % ( str(resource_id), ) else: query += " AND l.resource_id IS NULL " if start_datetime and end_datetime: query += " AND (DATE '%s', DATE '%s') OVERLAPS (l.date_from,l.date_to) " % ( util.dateToStr(start_datetime), util.dateToStr(end_datetime)) elif start_datetime: query += " AND l.date_to >= DATE '%s'" % ( util.dateToStr(start_datetime), ) elif end_datetime: query += " AND l.date_from <= DATE '%s' " % ( util.dateToStr(end_datetime), ) query += " ORDER BY l.date_from " cr.execute(query) resource_leave_ids = [row[0] for row in cr.fetchall()] res_leaves = resource_cal_leaves.browse(cr, uid, resource_leave_ids, context=context) for leave in res_leaves: dtf = util.strToTime(leave.date_from) dtt = util.strToTime(leave.date_to) no = dtt - dtf [ dt_leave.append(util.dateToStr(dtf + timedelta(days=x))) for x in range(int(no.days + 1)) ] dt_leave.sort() return dt_leave
def start_quotation(self, cr, uid, ids, context=None): if not ids: return True purchase_order_obj = self.pool["purchase.order"] purchase_line_obj = self.pool["purchase.order.line"] for line in self.browse(cr, uid, ids, context=context): # check order order = line.order_id if not order: continue # search existing unused, and delete or deactivate product = line.product_id self._unlink_purchase_line( cr, uid, purchase_line_obj.search( cr, uid, [("sale_line_id", "=", line.id), ("product_id", "!=", product and product.id or False)]), context=context) if not product: continue # check suppliers supplier_infos = product.seller_ids if not supplier_infos: continue quotation_active = False # process suppliers for supplier_info in supplier_infos: partner = supplier_info.name date_planned = util.dateToStr( datetime.datetime.today() + datetime.timedelta(line.delay or 0.0)) purchase_line_vals = { "product_id": product.id, "product_qty": line.product_uom_qty, "product_uom": line.product_uom.id, "sale_line_id": line.id, "date_planned": date_planned } purchase_order_vals = { "partner_id": partner.id, "origin": order.name, "sale_order_id": order.id } # update or create new purchase_line_id = purchase_line_obj.search_id( cr, uid, [("sale_line_id", "=", line.id), ("product_id", "=", product.id), ("partner_id", "=", partner.id)]) purchase_line = None purchase_line_state = None if purchase_line_id: purchase_line = purchase_line_obj.browse(cr, uid, purchase_line_id, context=context) # check readonly state if purchase_line.state in ("confirmed", "approved", "done"): continue purchase_line_vals["price_unit"] = purchase_line.price_unit purchase_line_state = purchase_line.state or 'draft' purchase_order = purchase_line.order_id if purchase_order: purchase_order_vals[ "picking_type_id"] = purchase_order.picking_type_id.id else: purchase_order_vals[ "picking_type_id"] = purchase_order_obj._get_picking_in( cr, uid, context=context) # reset selected if not update purchase_line_vals["quot_sent"] = False # onchange for order purchase_order_vals.update( purchase_order_obj.onchange_partner_id( cr, uid, [], partner.id, context=context)["value"]) purchase_order_vals.update( purchase_order_obj.onchange_picking_type_id( cr, uid, [], purchase_order_vals.get("picking_type_id"), context=context)["value"]) # onchaneg for line purchase_line_vals.update( purchase_line_obj.onchange_product_id( cr, uid, [], purchase_order_vals.get("pricelist_id"), purchase_line_vals.get("product_id"), purchase_line_vals.get("product_qty"), purchase_line_vals.get("product_uom"), purchase_order_vals.get("partner_id"), date_planned=purchase_order_vals.get("date_planned"), price_unit=purchase_line_vals.get("price_unit", False), state=purchase_line_state, context=context)["value"]) purchase_line_vals["name"] = line.name purchase_line_vals["taxes_id"] = [ (6, 0, purchase_line_vals.get("taxes_id", [])) ] # pop related fields purchase_order_vals.pop("related_location_id") purchase_order_vals.pop("related_usage") # update or create if purchase_line_id: purchase_order_vals["order_line"] = [(1, purchase_line_id, purchase_line_vals)] purchase_order_obj.write(cr, uid, [purchase_line.order_id.id], purchase_order_vals, context=context) else: purchase_order_vals["order_line"] = [(0, 0, purchase_line_vals)] purchase_order_obj.create(cr, uid, purchase_order_vals, context=context) # enable quotation quotation_active = True # update line self.write(cr, uid, [line.id], { "quotation_active": True, "quotation_id": False }) return True
def _students(self, cr, uid, ids, date_from, date_to, context=None): res = [] reg_obj = self.pool["academy.registration"] dt_from = util.strToDate(date_from) dt_to = util.strToDate(date_to) for trainer in self.browse(cr, uid, ids, context=context): # get week end dt_we = dt_from + relativedelta(days=(6 - dt_from.weekday())) # get week start dt_ws = dt_from # registry per trainer regs = {} trainer_data = {"trainer": trainer, "regs": regs} res.append(trainer_data) # start loop while dt_ws <= dt_to: # until to date # convert to str we = util.dateToStr(dt_we) ws = util.dateToStr(dt_ws) # query students cr.execute( "SELECT ts.reg_id, ts.day FROM academy_trainer_student ts " "INNER JOIN academy_registration r ON r.id = ts.reg_id " " AND r.state = 'assigned' " "LEFT JOIN academy_semester sb ON sb.id = r.semester_id " "LEFT JOIN academy_semester se ON se.id = r.unreg_semester_id " "WHERE ts.trainer_id = %s " " AND sb.date_start <= %s" " AND ( se.date_end IS NULL OR se.date_end >= %s )" " AND ( r.abort_date IS NULL OR r.abort_date > %s )" " AND ts.day = ( SELECT MAX(ts2.day) FROM academy_trainer_student ts2 " " WHERE ts2.reg_id = ts.reg_id " " AND ts2.day < %s " ") " " GROUP BY 1,2 ", ( trainer.id, # trainer ws, # check semester start ws, # check semester end we, # check abort we # check trainer assignment )) # process registers rows = cr.fetchall() if rows: for reg_id, start_date in rows: reg_data = regs.get(reg_id, None) if reg_data is None: reg_data = { "reg": reg_obj.browse(cr, uid, reg_id, context=context), "start_date": start_date, "hours": 0.0 } reg = reg_data["reg"] # check if day is in the other month dt_reg_start = util.strToDate(start_date) dt_course_date = dt_ws - relativedelta( days=dt_ws.weekday()) + relativedelta( days=dt_reg_start.weekday()) if dt_to < dt_course_date or dt_from > dt_course_date: continue # increment hours reg_data["hours"] = reg_data["hours"] + ( int(round(reg.hours * 60.0)) / 60.0) regs[reg_id] = reg_data # increment # .. next week start dt_ws = dt_we + relativedelta(days=1) # .. next week end dt_we += relativedelta(weeks=1) return res
def _build_sheet(self, cr, uid, date_from=None, date_to=None, months=None, employee=None, sheets=None, context=None): # check context date if not context is None: if not date_from: date_from = context.get("date_from") if not date_to: date_to = context.get("date_to") # check months if date_from and months: date_to = util.getNextDayOfMonth(date_from, inMonth=months) # if employ was passed if employee: date_cur = util.currentDate() if not date_from: date_from = util.getFirstOfMonth(date_cur) if not date_to: date_to = util.getEndOfMonth(date_cur) cr.execute( "SELECT s.id FROM hr_timesheet_sheet_sheet s " " WHERE (( s.date_from <= %s AND s.date_to >= %s) " " OR ( s.date_from <= %s AND s.date_to >= %s) " " OR ( s.date_from >= %s AND s.date_to <= %s)) " " AND s.employee_id = %s " " ORDER BY s.date_from ", (date_from, date_from, date_to, date_to, date_from, date_to, employee.id)) sheet_ids = [r[0] for r in cr.fetchall()] sheets = self.browse(cr, uid, sheet_ids, context=context) # if sheets was passed elif sheets: if not date_from: date_from = sheets[0].date_from if not date_to: date_to = sheets[-1].date_to # return if no sheet if not sheets or not date_from or not date_to: return None cr.execute( "SELECT s.id FROM hr_timesheet_sheet_sheet s " " WHERE s.date_to = ( SELECT MAX(s2.date_to) FROM hr_timesheet_sheet_sheet s2 " " WHERE s2.date_to < %s AND s2.employee_id = s.employee_id )" " AND s.employee_id = %s " " ORDER BY s.date_from ", (sheets[0].date_from, sheets[0].employee_id.id)) query_res = cr.fetchall() sheet_before = None if query_res: sheet_before = self.browse(cr, uid, query_res[0][0], context=context) days = [] res = { "date_from": date_from, "date_to": date_to, "days": days, "employee": sheets[0].employee_id } dt_to = util.strToDate(date_to) dt_from = util.strToDate(date_from) total_timesheet = 0.0 total_target = 0.0 total = 0.0 total_saldo = 0.0 current_saldo = 0.0 leaves_taken = 0.0 sick_leaves = 0.0 last_saldo = 0.0 remaining_leaves = sheets[0].remaining_leaves max_leaves = sheets[0].remaining_leaves if sheet_before: current_saldo = sheet_before.current_saldo last_saldo = current_saldo leave_obj = self.pool.get("resource.calendar.leaves") timesheet_line_obj = self.pool.get("hr.analytic.timesheet") for sheet in sheets: timesheet_data = self.get_timesheet_data(cr, sheet.user_id.id, sheet.id, context=context) sheet_dt_from = util.strToDate(sheet.date_from) sheet_dt_cur = sheet_dt_from sheet_dt_to = util.strToDate(sheet.date_to) delta_day = relativedelta(days=1) while sheet_dt_cur <= sheet_dt_to and sheet_dt_cur <= dt_to: date_day = util.dateToStr(sheet_dt_cur) timesheet_day = timesheet_data.get(date_day) if timesheet_day: # vars day_saldo = timesheet_day.get("total_saldo") or 0.0 # increment saldo current_saldo += day_saldo # check if date is in date from if sheet_dt_cur >= dt_from: # get vars day_total_timesheet = timesheet_day.get( "total_timesheet_day") or 0.0 day_target = timesheet_day.get("total_target") or 0.0 day_attendance = timesheet_day.get( "total_attendance_day") or 0.0 # get attendance attendance = [] attendance_text = [] attendance_lines = timesheet_day.get( "attendances", None) if attendance_lines: for attendance_line in attendance_lines: timestamp_to = attendance_line["to"] time_only = timestamp_to and timestamp_to.split( " ")[1] or None if time_only != "24:00:00": time_from = util.timeToStrHours( attendance_line["from"]) time_to = util.timeToStrHours(timestamp_to) attendance_text.append( "%s - %s" % (time_from, time_to)) attendance.append({ "time_from": time_from, "time_to": time_to }) # get work work = timesheet_line_obj.browse(cr, uid, timesheet_day.get( "lines", []), context=context) # process leaves leaves = timesheet_day.get("leaves", []) leave_names = [] for leave in leave_obj.browse(cr, uid, [l[0] for l in leaves], context=context): leave_names.append(leave.name) if leave.name: attendance_text.append(leave.name) holiday = leave.holiday_id holiday_status = holiday.holiday_status_id if holiday_status: holiday_categ = holiday_status.categ_id if holiday_categ: if holiday_categ.leave_type == "holiday": leaves_taken += 1 if holiday_categ.leave_type == "sickness": sick_leaves += 1 # ONLY ONE LEAVE per DAY break # increment counters total_timesheet += day_total_timesheet total_target += day_target total += day_attendance total_saldo += day_saldo day = { "day": date_day, "total_timesheet": day_total_timesheet, "total": day_attendance, "total_saldo": day_saldo, "total_target": day_target, "current_saldo": current_saldo, "attendance": attendance, "attendance_text": "\n".join(attendance_text), "work": work, "leaves": leave_names, "leaves_taken": leaves_taken, "remaining_leaves": remaining_leaves, "sick_leaves": sick_leaves, "sheet": sheet } days.append(day) elif sheet_dt_cur < dt_from: last_saldo = current_saldo # next day sheet_dt_cur += delta_day res["max_leaves"] = max_leaves res["last_saldo"] = last_saldo res["current_saldo"] = current_saldo res["leaves_taken"] = leaves_taken res["remaining_leaves"] = remaining_leaves res["total_timesheet"] = total_timesheet res["total_target"] = total_target res["sick_leaves"] = sick_leaves res["total"] = total res["total_saldo"] = total_saldo return res
def toStrDate(key): dtValue = data[key] if dtValue: dtValue = util.dateToStr(dtValue) data[key] = dtValue return dtValue