예제 #1
0
 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
예제 #2
0
파일: product.py 프로젝트: suningwz/fdoo
    def _active_version(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids)
        date = context and context.get(
            "date", util.currentDate()) or util.currentDate()
        cr.execute(
            "SELECT v.pricelist_id, v.id "
            " FROM product_pricelist_version AS v "
            " WHERE v.pricelist_id IN %s AND active=True "
            "   AND (date_start is NULL OR date_start <= %s) "
            "   AND (date_end is NULL OR date_end >= %s ) "
            " GROUP BY 1,2 ", (tuple(ids), date, date))

        for row in cr.fetchall():
            res[row[0]] = row[1]
        return res
예제 #3
0
파일: project.py 프로젝트: suningwz/fdoo
 def onchange_user(self, cr, uid, ids, date, hours, user_id):
     if uid == user_id:
         ts_obj = self.pool.get("hr_timesheet_sheet.sheet")
         ts_day = ts_obj.get_timesheet_day(cr, uid, util.currentDate())
         if ts_day:
             return {"value": {"hours": ts_day.total_difference}}
     return {}
예제 #4
0
파일: fpos.py 프로젝트: funkring/fdoo-extra
    def _send_report(self, start_date=None, session=None):
        if not start_date:
            start_date = util.currentDate()
        for report_email in self.search([]):
            offset = -1
            has_pos = False

            # check for main pos to send, or delay one day
            pos = report_email.pos_id
            if pos and session and session.config_id.id == pos.id:
                has_pos = True
                offset = 0

            # send last...
            mail_range = report_email._cashreport_range(start_date, offset)
            has_report = report_email.range_start < mail_range[0] and mail_range[1] < start_date
            # ... or current
            if has_pos and mail_range[1] == start_date:
                has_report = True

            if has_report:
                report_email._send_mail(mail_range[0])
                range_start = mail_range[0]
                # send other
                if report_email.range_start:
                    while True:
                        mail_range = report_email._cashreport_range(mail_range[0], -1)
                        if report_email.range_start < mail_range[0]:
                            report_email._send_mail(mail_range[0])
                        else:
                            break
                report_email.range_start = range_start
예제 #5
0
    def logbook_weeks(self):
        weeks = []

        f = format.LangFormat(self._cr, self._uid, self._context)
        week_start = util.getFirstOfWeek(self.date_start)
        date_end = self.date_end or util.getPrevDayDate(
            util.getFirstOfNextWeek(util.currentDate()))

        while week_start <= date_end:
            week_str = datetime.strftime(util.strToDate(week_start),
                                         _("CW %W"))
            week_first = week_start
            week_start = util.getFirstOfNextWeek(week_start)
            week_end = util.getPrevDayDate(week_start)

            weeks.append({
                "name": week_str,
                "date_start": week_first,
                "group": week_first[:7],
                "start": f.formatLang(week_first, date=True),
                "end": f.formatLang(week_end, date=True)
            })

        weeks.sort(key=lambda v: v["date_start"], reverse=True)
        return weeks
예제 #6
0
class academy_advance_payment(osv.Model):
    def _default_semester_id(self, cr, uid, context=None):
        # get current semester
        user = self.pool["res.users"].browse(cr, uid, uid, context)
        semester = user.company_id.academy_semester_id
        if semester:
            return semester.id
        return None

    def unlink(self, cr, uid, ids, context=None):
        ids = util.idList(ids)
        for payment in self.browse(cr, uid, ids, context):
            if payment.invoice_id:
                raise osv.except_osv(
                    _("Error"), _("Payment which is posted could not deleted"))
        super(academy_advance_payment, self).unlink(cr,
                                                    uid,
                                                    ids,
                                                    context=context)

    _name = "academy.payment"
    _description = "Advance Payment"
    _rec_name = "reg_id"
    _columns = {
        "date":
        fields.date("Date", required=True),
        "reg_id":
        fields.many2one("academy.registration",
                        "Registration",
                        select=True,
                        required=True),
        "semester_id":
        fields.many2one("academy.semester",
                        "Semester",
                        select=True,
                        required=True),
        "amount":
        fields.float("Amount",
                     digits_compute=dp.get_precision('Account'),
                     required=True),
        "ref":
        fields.char("Reference", select=True),
        "invoice_id":
        fields.many2one("account.invoice",
                        "Invoice",
                        select=True,
                        readonly=True),
        "voucher_id":
        fields.many2one("account.voucher",
                        "Voucher",
                        select=True,
                        readonly=True)
    }

    _defaults = {
        "date": util.currentDate(),
        "semester_id": _default_semester_id
    }
예제 #7
0
class academy_journal(osv.Model):
    _name = "academy.journal"
    _description = "Academy Journal"

    def onchange_topic(self, cr, uid, ids, topic_id, context=None):
        res = {"value": {}}

        if topic_id:
            topic = self.pool.get("academy.topic").browse(cr, uid, topic_id)
            res["value"]["name"] = str(topic.name) + "\n" + str(
                topic.description)
            res["value"]["duration"] = topic.duration
            res["value"]["course_id"] = topic.course_id.id

        return res

    _columns = {
        "name":
        fields.text("Name"),
        "date":
        fields.date("Date", required=True),
        "begin":
        fields.float(
            "Begin",
            help=
            "The time must be between 00:00 and 24:00 o'clock and must not be bigger than the end"
        ),
        "end":
        fields.float("End",
                     help="The time must be between 00:00 and 24:00 o'clock"),
        "topic_id":
        fields.many2one("academy.topic", "Topic", required=True),
        "student_ids":
        fields.many2many("res.partner", "res_partner_journal_rel",
                         "partner_id", "journal_id", "Students"),
        "absence_ids":
        fields.one2many("academy.journal.absence", "journal_id", "Absences"),
        "trainer_id":
        fields.many2one("academy.trainer", "Trainer", required=True),
        "course_id":
        fields.related("topic_id",
                       "course_id",
                       type="many2one",
                       readonly=True,
                       relation="academy.course",
                       string="Course"),
        "duration":
        fields.float("Unit(s)"),
        "expenses":
        fields.float("Transport Expenses"),
        "place":
        fields.char("Place", size=64)
    }

    _defaults = {
        "date": util.currentDate(),
    }
예제 #8
0
 def __init__(self, cr, uid, name, context):
     super(Parser, self).__init__(cr, uid, name, context)
     self.localcontext.update({
         "accounts_get": self._accounts_get,
         "date_from_get": self._date_from_get,
         "date_to_get": self._date_to_get,
         "code_str": self._code_str,
         "name_str": self._name_str,
         "debit_str": self._debit_str,
         "credit_str": self._credit_str,
         "balance_str": self._balance_str,
     })
     self.localcontext["report_title"] = context.get(
         "report_title", _("Balance list"))
     self.localcontext["date_from"] = context.get(
         "date_from", util.getFirstOfMonth(util.currentDate()))
     self.localcontext["date_to"] = context.get(
         "date_to", util.getEndOfMonth(util.currentDate()))
예제 #9
0
 def _default_logbook_id(self):
     logbooks = self.env["farm.chicken.logbook"].search([("state", "=",
                                                          "active")])
     default_day = util.currentDate()
     for logbook in logbooks:
         logs = self.search([("logbook_id", "=", logbook.id),
                             ("day", "=", default_day)])
         if not logs:
             return logbook.id
     return None
예제 #10
0
    def _check_birthday(self, cr, uid):
        dt_current = util.strToDate(util.currentDate())
        date_search = "%%-%02d-%02d" % (dt_current.month,dt_current.day)
        template_xmlid = "partner_birthday_mail.email_partner_birthday"

        partner_ids = self.search(cr, uid, [("birthday","ilike",date_search)])
        template_obj = self.pool["email.template"]
        template_id = self.pool["ir.model.data"].xmlid_to_res_id(cr, uid, template_xmlid)
        if template_id:
            for partner in self.browse(cr, uid, partner_ids):
                template_obj.send_mail(cr, uid, template_id, partner.id, force_send=True)
예제 #11
0
파일: employee.py 프로젝트: suningwz/fdoo
    def _get_contract(self,
                      cr,
                      uid,
                      employee_id,
                      date_from=None,
                      date_to=None,
                      context=None):
        if not date_from:
            date_from = util.currentDate()
        if not date_to:
            date_to = date_from

        contract_obj = self.pool["hr.contract"]

        # fetch contracts
        cr.execute(
            "SELECT c.id FROM hr_contract c"
            " WHERE c.employee_id = %s "
            "   AND (c.date_start IS NULL OR (c.date_start <= %s AND (c.date_end IS NULL OR c.date_end >= %s) OR (c.date_start <= %s AND c.date_start >= %s)) )"
            " ORDER BY c.date_start DESC ",
            (employee_id, date_from, date_from, date_to, date_from))

        contract_ids = [r[0] for r in cr.fetchall()]

        # return if not found
        if not contract_ids:
            return None

        # validate range
        for contract in contract_obj.browse(cr,
                                            uid,
                                            contract_ids,
                                            context=context):
            # check working_hours
            if not contract.working_hours:
                continue

            # validate range
            if date_from < contract.date_start:
                date_from = contract.date_start
            if contract.date_end and contract.date_end < date_to:
                date_to = contract.date_end

            # check date_to
            if date_to < date_from:
                continue

            return {
                "contract": contract,
                "working_hours": contract.working_hours,
                "date_from": date_from,
                "date_to": date_to
            }
        return None
예제 #12
0
파일: fpos.py 프로젝트: funkring/fdoo-extra
    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)
예제 #13
0
    def _get_semester_id(self, cr, uid, context=None):

        # get current semester
        user = self.pool["res.users"].browse(cr, uid, uid, context)
        semester = user.company_id.academy_semester_id
        if semester:
            return semester.id

        # search semester based on date if current semester is not set
        semester_obj = self.pool["academy.semester"]
        #search next semester
        semester_ids = semester_obj.search(
            cr,
            uid, [("date_start", ">", util.currentDate())],
            order="date_start asc")
        if not semester_ids:
            # get current semester
            return semester_obj.search_id(cr, uid, [], order="date_end desc")
        return semester_ids and semester_ids[0] or None
예제 #14
0
    def _prepare_cost_invoice(self, cr, uid, partner, company_id, currency_id, analytic_lines, context=None):
        res = super(account_analytic_line, self)._prepare_cost_invoice(cr, uid, partner, company_id, currency_id, analytic_lines, context=context)
        
        line_ids = [l.id for l in analytic_lines]
        account = analytic_lines[0].account_id
        f = format.LangFormat(cr, uid, context)
         
        cr.execute("SELECT MIN(line.date), MAX(line.date) " \
                    "FROM account_analytic_line as line " \
                    "WHERE account_id = %s " \
                        "AND id IN %s AND to_invoice IS NOT NULL", (account.id, tuple(line_ids)))

        invoice_name = None
        for date_from, date_to in cr.fetchall():
            if date_from and date_to:
                invoice_name = "%s %s - %s" % ( account.name or "",f.formatLang(date_from,date=True), f.formatLang(date_to,date=True))

        if not invoice_name:
            invoice_name = "%s %s" % (account.name or "",f.formatLang(util.currentDate(),date=True))

        res["name"] = invoice_name
        return res
예제 #15
0
    def _get_date_planned(self,
                          cr,
                          uid,
                          order,
                          line,
                          start_date,
                          context=None):
        start_date = util.strToTime(start_date)
        company = order.company_id
        date_planned = None

        real_delay = (line.delay or 0.0) - company.security_lead
        if real_delay:
            if company.calendar_id:
                date_planned = self.pool.get('resource.calendar').passed_range(
                    cr, uid, company.calendar_id.id, start_date,
                    real_delay)["to"]
            else:
                date_planned = start_date + relativedelta(days=real_delay)
        if date_planned:
            date_planned = util.timeToStr(date_planned)
        else:
            return util.currentDate()
        return date_planned
예제 #16
0
파일: analytic.py 프로젝트: suningwz/fdoo
    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
예제 #17
0
파일: fpos.py 프로젝트: funkring/fdoo-extra
    def _send_mail(self, start_date=None):
        if not start_date:
            start_date = start_date = util.currentDate()

        mail_obj = self.pool["mail.mail"]
        mail_tmpl_obj = self.pool["email.template"]
        att_obj = self.pool["ir.attachment"]
        rzl_obj = self.env["fpos.wizard.export.rzl"]
        bmd_obj = self.env["fpos.wizard.export.bmd"]
        config_obj = self.env["pos.config"]

        data_obj = self.pool["ir.model.data"]
        template_id = data_obj.xmlid_to_res_id(self._cr, self._uid, "fpos.email_report", raise_if_not_found=True)

        mail_context = self._context and dict(self._context) or {}
        mail_context["start_date"] = start_date
        mail_range = self._cashreport_range(start_date)
        mail_context["cashreport_name"] = mail_range[2]

        # check options
        if self.detail:
            mail_context["print_detail"] = True
        if self.separate:
            mail_context["no_group"] = True
        if self.product:
            mail_context["print_product"] = True

        # build config
        config_ids = []
        if self.pos_ids:
            for pos in self.pos_ids:
                config_ids.append(pos.id)
        else:
            for config in config_obj.search([("liveop", "=", True)]):
                config_ids.append(config.id)

        # add report info
        mail_context["pos_report_info"] = {
            "from": mail_range[0],
            "till": mail_range[1],
            "name": mail_range[2],
            "config_ids": config_ids,
        }

        attachment_ids = []
        if self.rzl_export or self.bmd_export:
            session_ids = self._session_ids(mail_range)

            # export rzl
            if self.rzl_export:
                rzl_data = rzl_obj.with_context(active_model="pos.session", active_ids=session_ids).default_get(
                    ["data", "data_name"]
                )
                attachment_ids.append(
                    att_obj.create(
                        self._cr,
                        self._uid,
                        {
                            "name": rzl_data["data_name"],
                            "datas_fname": rzl_data["data_name"],
                            "datas": rzl_data["data"],
                        },
                        context=self._context,
                    )
                )

            # export bmd
            if self.bmd_export:
                bmd_data = bmd_obj.with_context(active_model="pos.session", active_ids=session_ids).default_get(
                    ["data", "data_name"]
                )
                attachment_ids.append(
                    att_obj.create(
                        self._cr,
                        self._uid,
                        {"name": "buerf", "datas_fname": "buerf", "datas": bmd_data["buerf"]},
                        context=self._context,
                    )
                )

        # write
        msg_id = mail_tmpl_obj.send_mail(
            self._cr, self._uid, template_id, self.id, force_send=False, context=mail_context
        )
        if attachment_ids:
            mail = mail_obj.browse(self._cr, self._uid, msg_id, context=self._context)
            # link with message
            att_obj.write(
                self._cr,
                self._uid,
                attachment_ids,
                {"res_model": "mail.message", "res_id": mail.mail_message_id.id},
                context=self._context,
            )
            # add attachment ids to message
            mail_obj.write(
                self._cr,
                self._uid,
                [msg_id],
                {"attachment_ids": [(4, oid) for oid in attachment_ids]},
                context=self._context,
            )
        # send
        mail_obj.send(self._cr, self._uid, [msg_id], context=mail_context)
예제 #18
0
class chicken_log(models.Model):
    @api.one
    def _parent_log(self):
        parent_house = self.logbook_id.house_id.parent_id
        if parent_house:
            parent_logs = self.search([("logbook_id.house_id",
                                        "=", parent_house.id),
                                       ("day", "=", self.day)])
            return parent_logs and parent_logs[0] or None

    @api.multi
    def action_draft(self):
        return self.write({"state": "draft"})

    @api.one
    def _validate_inv(self):
        # get childs
        parent = self.parent_id
        if not parent:
            parent = self
        logs = [parent]
        logs.extend(parent.child_ids)

        # get invoice logs
        inv_logs = []
        non_inv_logs = []
        inv_parent = False
        delivered = False
        for log in logs:
            if log.delivered:
                delivered = True
            if log.inv_exists:
                inv_logs.append(log)
                if log.id == parent.id:
                    inv_parent = True
            else:
                non_inv_logs.append(log)

        # check if invoice exist
        if inv_logs:
            for inv_log in inv_logs:
                inv_log.inv_hierarchy = True

            # check if parent has no invoice
            if not inv_parent:
                # sumup invoice fields
                inv_fields = {}
                for inv_field in self._inv_fields:
                    val = inv_logs[0][inv_field]
                    for inv_log in inv_logs[1:]:
                        val += inv_log[inv_field]
                    inv_fields[inv_field] = val

                # set it to parent
                for inv_field, val in inv_fields.iteritems():
                    parent[inv_field] = val

                if delivered:
                    parent.delivered = delivered

        else:
            for log in logs:
                log.inv_hierarchy = False

        return True

    @api.multi
    def action_validate(self):
        for log in self:
            log._validate_inv()
            logs_after = log.search([("logbook_id", "=", self.logbook_id.id),
                                     ("day", ">", self.day)],
                                    order="day desc")
            logs_after._validate_inv()
        return self.write({"state": "valid"})

    @api.one
    @api.depends("loss", "loss_fix", "loss_fix_amount")
    def _compute_loss_total(self):
        # add loss without fix
        self._cr.execute(
            "SELECT SUM(COALESCE(loss,0)) FROM farm_chicken_log l "
            " WHERE l.logbook_id = %s AND l.day <= %s AND NOT COALESCE(l.loss_fix,False) ",
            (self.logbook_id.id, self.day))
        res = self._cr.fetchone()
        loss_total = res and res[0] or 0

        # add loss with fix
        self._cr.execute(
            "SELECT SUM(COALESCE(loss_fix_amount,0)) FROM farm_chicken_log l "
            " WHERE l.logbook_id = %s AND l.day <= %s AND l.loss_fix ",
            (self.logbook_id.id, self.day))
        res = self._cr.fetchone()
        loss_total += res and res[0] or 0

        self.loss_total = loss_total

        self.loss_amount = self.loss
        if self.loss_fix:
            self.loss_amount = self.loss_fix_amount

    @api.one
    @api.depends("loss")
    def _compute_loss_total_real(self):
        self._cr.execute(
            "SELECT SUM(COALESCE(loss,0)) FROM farm_chicken_log l "
            " WHERE l.logbook_id = %s AND l.day <= %s ",
            (self.logbook_id.id, self.day))
        res = self._cr.fetchone()
        loss_total = res and res[0] or 0

        self.loss_total_real = loss_total

    @api.one
    @api.depends("loss_total_real", "loss")
    def _compute_chicken_count(self):
        self.chicken_count = self.logbook_id.chicken_count - self.loss_total_real

    @api.one
    @api.depends("eggs_total", "eggs_removed")
    def _compute_eggs_count(self):
        self._cr.execute(
            "SELECT SUM(COALESCE(eggs_total,0))-SUM(COALESCE(eggs_removed,0))-(SUM(COALESCE(delivered_eggs_mixed,0))+SUM(COALESCE(delivered_eggs_industry,0))) FROM farm_chicken_log l "
            " WHERE l.logbook_id = %s AND l.day <= %s ",
            (self.logbook_id.id, self.day))
        res = self._cr.fetchone()
        self.eggs_count = res and res[0] or None

    @api.one
    @api.depends("delivered_eggs_mixed", "delivered_eggs_industry",
                 "inv_eggs_xl", "inv_eggs_m", "inv_eggs_l", "inv_eggs_s",
                 "inv_eggs_s45g", "inv_eggs_industry", "inv_eggs_presorted")
    def _compute_delivery(self):
        self.delivered_eggs = self.delivered_eggs_mixed + self.delivered_eggs_industry
        self.inv_eggs = self.inv_eggs_xl + self.inv_eggs_l + self.inv_eggs_m + self.inv_eggs_s + self.inv_eggs_s45g + self.inv_eggs_industry + self.inv_eggs_presorted
        self.inv_diff_eggs = self.inv_eggs - self.delivered_eggs
        self.inv_diff_presorted = self.inv_eggs_presorted - self.delivered_eggs_industry

    @api.one
    @api.depends("logbook_id.date_start", "logbook_id.chicken_age")
    def _compute_chicken_age(self):
        logbook = self.logbook_id
        dt_start = util.strToDate(logbook.date_start)
        dt_cur = util.strToDate(self.day)
        diff = dt_cur - dt_start
        self.chicken_age = logbook.chicken_age + diff.days
        self.chicken_age_weeks = self.chicken_age / 7.0

    @api.one
    @api.depends("eggs_total", "chicken_count")
    def _compute_eggs_performance(self):
        if self.chicken_count:
            self.eggs_performance = 100.0 / self.chicken_count * self.eggs_total
        else:
            self.eggs_performance = 0.0

    @api.model
    def _default_logbook_id(self):
        logbooks = self.env["farm.chicken.logbook"].search([("state", "=",
                                                             "active")])
        default_day = util.currentDate()
        for logbook in logbooks:
            logs = self.search([("logbook_id", "=", logbook.id),
                                ("day", "=", default_day)])
            if not logs:
                return logbook.id
        return None

    @api.one
    @api.depends("day", "logbook_id", "logbook_id.house_id",
                 "logbook_id.house_id.parent_id")
    def _compute_parent_id(self):
        if self.state != "done":
            parent_log = None
            parent_house = self.logbook_id.house_id.parent_id

            if parent_house:
                # assign parent log
                parent_log = self.search([("day", "=", self.day),
                                          ("logbook_id.state", "=", "active"),
                                          ("logbook_id.house_id", "=",
                                           parent_house.id)])
                # create parent if not exist
                if parent_log:
                    parent_log = parent_log[0]

            self.parent_id = parent_log

    @api.one
    def _validate(self, values=None):
        if self.state != "done":
            parent = self.parent_id

            # validate parent
            parent_house = self.logbook_id.house_id.parent_id
            if not parent and parent_house:
                logbook_obj = self.env["farm.chicken.logbook"]
                parent_logbook = logbook_obj._get_active(parent_house.id)
                if parent_logbook:
                    self.parent_id = self.create({
                        "logbook_id": parent_logbook.id,
                        "day": self.day
                    })
                    parent = self.parent_id

            # check if parent exists
            # and validate
            if parent:
                # check for validate
                if values:
                    validate_fields = []
                    for field in self._forward_fields:
                        if field in values:
                            validate_fields.append(field)
                else:
                    validate_fields = self._forward_fields

                # validate fields
                if validate_fields:
                    childs = parent.child_ids
                    if childs:
                        values = self.read(validate_fields)[0]
                        for key in validate_fields:
                            val = values[key]
                            for child in childs:
                                if child.id == self.id:
                                    continue
                                val += child[key]
                            values[key] = val
                        parent.write(values)

    @api.multi
    def _calc_beyond(self):
        for field in ("chicken_count", "chicken_age", "chicken_age_weeks",
                      "eggs_performance"):
            self._fields[field]._compute_value(self)

    def _create(self, cr, uid, vals, context=None):
        res = super(chicken_log, self)._create(cr, uid, vals, context=context)
        # validate
        log = self.browse(cr, uid, res, context=context)
        log._validate(vals)
        # validate beyond
        log._calc_beyond()
        return res

    def _write(self, cr, uid, ids, vals, context=None):
        # check invalid
        invalid_ids = []
        if "loss" in vals:
            for stored_vals in self.search_read(cr,
                                                uid, [("id", "in", ids)],
                                                ["loss"],
                                                order="day asc",
                                                context=context):
                if vals.get("loss", 0) != stored_vals["loss"]:
                    invalid_ids.append(stored_vals["id"])

        # write
        res = super(chicken_log, self)._write(cr,
                                              uid,
                                              ids,
                                              vals,
                                              context=context)

        # validate
        self.browse(cr, uid, ids, context=context)._validate(vals)
        # validate beyond
        if invalid_ids:
            cr.execute(
                "SELECT l.logbook_id, MIN(l.day) FROM farm_chicken_log l WHERE l.id IN %s GROUP BY 1",
                (tuple(invalid_ids), ))
            for logbook_id, day in cr.fetchall():
                log_ids = self.search(cr,
                                      uid, [("logbook_id", "=", logbook_id),
                                            ("day", ">", day)],
                                      order="day asc")
                self.browse(cr, uid, log_ids, context=context)._calc_beyond()

        return res

    _name = "farm.chicken.log"
    _description = "Log"
    _inherit = ["mail.thread"]
    _order = "day desc, logbook_id"
    _rec_name = "day"

    _forward_fields = ["feed", "water", "eggs_machine"]
    _inv_fields = [
        "delivered_eggs_mixed", "delivered_eggs_industry", "inv_eggs_xl",
        "inv_eggs_m", "inv_eggs_l", "inv_eggs_s", "inv_eggs_s45g",
        "inv_eggs_industry", "inv_eggs_presorted"
    ]
    _calc_fields = ["loss", "eggs_total"]

    _sql_constraints = [("date_uniq", "unique(logbook_id, day)",
                         "Only one log entry per day allowed!")]

    logbook_id = fields.Many2one("farm.chicken.logbook",
                                 "Logbook",
                                 required=True,
                                 index=True,
                                 readonly=True,
                                 states={'draft': [('readonly', False)]},
                                 default=_default_logbook_id,
                                 ondelete="restrict")

    day = fields.Date("Day",
                      required=True,
                      readonly=True,
                      index=True,
                      states={'draft': [('readonly', False)]},
                      default=lambda self: util.currentDate())

    loss = fields.Integer("Loss",
                          readonly=True,
                          states={'draft': [('readonly', False)]})
    loss_fix = fields.Boolean("Loss Fix",
                              readonly=True,
                              states={'draft': [('readonly', False)]})
    loss_fix_amount = fields.Integer("Loss Fix Amount",
                                     readonly=True,
                                     states={'draft': [('readonly', False)]})
    loss_total = fields.Integer("Loss Total",
                                readonly=True,
                                compute="_compute_loss_total")
    loss_total_real = fields.Integer("Real Loss",
                                     readonly=True,
                                     compute="_compute_loss_total_real")
    loss_amount = fields.Integer("Loss Amount",
                                 readonly=True,
                                 compute="_compute_loss_total")

    weight = fields.Float("Weight [kg]",
                          readonly=True,
                          states={'draft': [('readonly', False)]})
    feed_manual = fields.Boolean("Manual Feed Input",
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    feed = fields.Float("Feet [kg]",
                        readonly=True,
                        states={'draft': [('readonly', False)]})
    water = fields.Float("Water [l]",
                         readonly=True,
                         states={'draft': [('readonly', False)]})
    co2 = fields.Float("Co2",
                       readonly=True,
                       states={'draft': [('readonly', False)]})
    temp = fields.Float("Temperature [°C]",
                        readonly=True,
                        states={'draft': [('readonly', False)]})
    humidity = fields.Float("Humidity [%]",
                            readonly=True,
                            states={'draft': [('readonly', False)]})
    eggs_total = fields.Integer("Eggs Total",
                                readonly=True,
                                states={'draft': [('readonly', False)]})
    eggs_machine = fields.Integer("Eggs Machine",
                                  readonly=True,
                                  states={'draft': [('readonly', False)]})

    eggs_nest = fields.Integer("Nest Eggs",
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    eggs_top = fields.Integer("Eggs moved above",
                              readonly=True,
                              states={'draft': [('readonly', False)]})
    eggs_buttom = fields.Integer("Eggs laid down",
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    eggs_weight = fields.Float("Eggs Weight [g]",
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    eggs_dirty = fields.Integer("Dirty Eggs",
                                readonly=True,
                                states={'draft': [('readonly', False)]})
    eggs_broken = fields.Integer("Broken Eggs",
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})

    eggs_color = fields.Selection(
        [
            (1, "01"),
            (2, "02"),
            (3, "03"),
            (4, "04"),
            (5, "05"),
            (6, "06"),
            (7, "07"),
            (8, "08"),
            (9, "09"),
            (10, "10"),
            (11, "11"),
            (12, "12"),
            (13, "13"),
            (14, "14"),
            (15, "15"),
        ],
        string="Eggs Color",
        help="Color aligned to the DSM Yolk Color Fan",
        readonly=True,
        states={'draft': [('readonly', False)]})

    eggs_color_dote = fields.Selection(
        [(1, "01"), (2, "02"), (3, "03"), (4, "04"), (5, "05")],
        string="Eggs Dote Color",
        help="Color aligned to the DSM Yolk Color Fan",
        readonly=True,
        states={'draft': [('readonly', False)]})

    eggs_thickness = fields.Float("Eggs Thickness [kg]",
                                  readonly=True,
                                  states={'draft': [('readonly', False)]})

    state = fields.Selection([("draft", "Draft"), ("valid", "Valid"),
                              ("done", "Done")],
                             string="State",
                             default="draft")

    eggs_removed = fields.Integer("Eggs Removed",
                                  readonly=True,
                                  states={'draft': [('readonly', False)]})

    chicken_age = fields.Integer("Chicken Age [Days]",
                                 readonly=True,
                                 compute="_compute_chicken_age",
                                 store=True)
    chicken_age_weeks = fields.Integer("Chicken Age [Weeks]",
                                       readonly=True,
                                       compute="_compute_chicken_age",
                                       store=True)
    chicken_count = fields.Integer("Chicken Count",
                                   readonly=True,
                                   compute="_compute_chicken_count",
                                   store=True)

    eggs_count = fields.Integer("Eggs Stock",
                                readonly=True,
                                compute="_compute_eggs_count")
    eggs_performance = fields.Float("Eggs Performance",
                                    readonly=True,
                                    compute="_compute_eggs_performance",
                                    store=True)

    delivered = fields.Boolean("Delivery",
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    delivered_eggs_mixed = fields.Integer(
        "Delivered Eggs",
        readonly=True,
        states={'draft': [('readonly', False)]})
    delivered_eggs_industry = fields.Integer(
        "Delivered Eggs Industry",
        readonly=True,
        states={'draft': [('readonly', False)]})
    delivered_eggs = fields.Integer("Delivered Eggs Total",
                                    readonly=True,
                                    compute="_compute_delivery",
                                    store=True)

    inv_exists = fields.Boolean(
        "Invoice Exists",
        help="Standalone invoice for the delivery exists",
        states={'draft': [('readonly', False)]})
    inv_hierarchy = fields.Boolean("Invoice in Hierarchy Exists")
    inv_eggs_xl = fields.Integer("Invoiced Eggs XL",
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    inv_eggs_l = fields.Integer("Invoiced Eggs L",
                                readonly=True,
                                states={'draft': [('readonly', False)]})
    inv_eggs_m = fields.Integer("Invoiced Eggs M",
                                readonly=True,
                                states={'draft': [('readonly', False)]})
    inv_eggs_s = fields.Integer("Invoiced Eggs S",
                                readonly=True,
                                states={'draft': [('readonly', False)]})
    inv_eggs_s45g = fields.Integer("Invoiced Eggs < 45g",
                                   readonly=True,
                                   states={'draft': [('readonly', False)]})
    inv_eggs_industry = fields.Integer("Invoiced Eggs Industry",
                                       readonly=True,
                                       states={'draft': [('readonly', False)]})
    inv_eggs_presorted = fields.Integer(
        "Invoiced Eggs Industry (presorted)",
        readonly=True,
        states={'draft': [('readonly', False)]})
    inv_eggs = fields.Integer("Invoiced Eggs Total",
                              readonly=True,
                              compute="_compute_delivery",
                              store=True)

    inv_diff_eggs = fields.Integer("Eggs Difference",
                                   readonly=True,
                                   compute="_compute_delivery",
                                   store=True)
    inv_diff_presorted = fields.Integer("Eggs Difference (presorted)",
                                        readonly=True,
                                        compute="_compute_delivery",
                                        store=True)

    child_ids = fields.One2many("farm.chicken.log",
                                "parent_id",
                                string="Child Logs",
                                readonly=True)
    parent_id = fields.Many2one("farm.chicken.log",
                                string="Parent Log",
                                compute="_compute_parent_id",
                                readonly=True,
                                store=True)

    note = fields.Text("Note")
예제 #19
0
    def logbook_week(self, date_start=None):
        if not date_start:
            date_start = util.currentDate()

        f = format.LangFormat(self._cr, self._uid, self._context)

        week_start = util.getFirstOfWeek(date_start)
        week_next = util.getFirstOfNextWeek(date_start)
        week_str = datetime.strftime(util.strToDate(week_start), _("CW %W"))

        week_day = week_start
        week_end = week_day

        days = []
        log_obj = self.env["farm.chicken.log"]

        sum_loss = 0

        first_weight = 0.0

        valid_count = 0
        fill_count = 0
        day_count = 0

        chicken_count = 0

        avg_data = {}

        def getAvg(name, calc=True):
            data = avg_data.get(name, None)
            if data is None:
                data = {"val": [], "avg": 0.0}
                avg_data[name] = data

            if calc:
                val = data["val"][:7]
                val_len = len(val)
                if val_len:
                    data["avg"] = sum(val) / val_len

            return data

        def addAvg(name, val):
            if val:
                data = getAvg(name, calc=False)
                data["val"].insert(0, val)
            return val

        # get 14 logs for average calc
        logByDay = {}
        logs = log_obj.search([("logbook_id", "=", self.id),
                               ("day", "<", week_next)],
                              limit=14,
                              order="day desc")
        if logs:
            # set new start
            week_day_avg = logs[-1].day
            if week_day_avg < week_day:
                week_day = week_day_avg
            # assign log
            for log in logs:
                logByDay[log.day] = log

        chicken_age_weeks = 0

        while week_day < week_next:
            week_end = week_day

            loss = 0
            loss_fix = False
            loss_fix_amount = 0
            loss_amount = 0
            eggs_performance = 0.0
            weight = 0

            eggs_total = 0
            eggs_broken = 0
            eggs_dirty = 0
            eggs_weight = 0
            eggs_machine = 0
            chicken_age = 0

            feed = 0
            water = 0

            valid = False
            filled = False
            note = ""

            log = logByDay.get(week_day)
            if log:
                loss = log.loss
                loss_amount = log.loss_amount or 0
                loss_fix = log.loss_fix
                loss_fix_amount = log.loss_fix_amount

                eggs_total = addAvg("eggs_total", log.eggs_total)
                eggs_broken = addAvg("eggs_broken", log.eggs_broken)
                eggs_dirty = addAvg("eggs_dirty", log.eggs_dirty)
                eggs_weight = addAvg("eggs_weight", log.eggs_weight)
                eggs_machine = addAvg("eggs_machine", log.eggs_machine)
                eggs_performance = addAvg("eggs_performance",
                                          log.eggs_performance)

                feed = addAvg("feed", log.feed)
                water = addAvg("water", log.water)

                weight = log.weight
                if weight and not first_weight:
                    first_weight = weight

                chicken_count = log.chicken_count

                note = log.note or note
                chicken_age_weeks = log.chicken_age_weeks
                chicken_age = log.chicken_age
                valid = log.state != "draft"
                filled = True

            if filled:
                day_count += 1
                sum_loss += loss_amount

            # add day only if within week
            if week_day >= week_start:
                if filled:
                    fill_count += 1
                if valid:
                    valid_count += 1

                days.append({
                    "name":
                    format_date(util.strToDate(week_day),
                                "E d.M.y",
                                locale=self._context.get("lang")
                                or tools.config.defaultLang),
                    "day":
                    week_day,
                    "loss":
                    loss,
                    "loss_fix":
                    loss_fix,
                    "loss_fix_amount":
                    loss_fix_amount,
                    "eggs_total":
                    eggs_total,
                    "eggs_broken":
                    eggs_broken,
                    "eggs_dirty":
                    eggs_dirty,
                    "eggs_weight":
                    eggs_weight,
                    "eggs_machine":
                    eggs_machine,
                    "weight":
                    weight,
                    "note":
                    note,
                    "valid":
                    valid,
                    "filled":
                    filled,
                    "chicken_age_weeks":
                    chicken_age_weeks,
                    "overview": [{
                        "name": _("Eggs Total"),
                        "value": "%s" % eggs_total
                    }, {
                        "name": _("Eggs Machine"),
                        "value": "%s" % eggs_machine
                    }, {
                        "name": _("Broken Eggs"),
                        "value": "%s" % eggs_broken
                    }, {
                        "name": _("Dirty Eggs"),
                        "value": "%s" % eggs_dirty
                    }, {
                        "name": _("Eggs Weight"),
                        "value": "%s g" % f.formatLang(eggs_weight)
                    }, {
                        "name":
                        _("Egg Performance"),
                        "value":
                        "%s %%" % f.formatLang(eggs_performance)
                    }, {
                        "name": _("Loss"),
                        "value": "%s" % loss_amount
                    }, {
                        "name": _("Chicken Count"),
                        "value": "%s" % chicken_count
                    }, {
                        "name": _("Chicken Weight"),
                        "value": "%s kg" % f.formatLang(weight)
                    }, {
                        "name": _("Day Age"),
                        "value": "%s" % chicken_age
                    }, {
                        "name":
                        _("Feed"),
                        "value":
                        "%s kg" % f.formatLang(feed, digits=0)
                    }, {
                        "name": _("Water"),
                        "value": "%s l" % f.formatLang(water)
                    }]
                })

            week_day = util.getNextDayDate(week_day)

        days_len = len(days)
        return {
            "name":
            "%s %s" % (self.name, week_str),
            "week":
            week_str,
            "date":
            week_start,
            "start":
            f.formatLang(week_start, date=True),
            "end":
            f.formatLang(week_end, date=True),
            "filled":
            days_len == fill_count,
            "validated":
            days_len == valid_count,
            "days":
            days,
            "overview": [{
                "name":
                _("Eggs"),
                "value":
                "%s" % f.formatLang(getAvg("eggs_total")["avg"])
            }, {
                "name":
                _("Eggs Machine"),
                "value":
                "%s" % f.formatLang(getAvg("eggs_machine")["avg"])
            }, {
                "name":
                _("Broken Eggs"),
                "value":
                "%s" % f.formatLang(getAvg("eggs_broken")["avg"])
            }, {
                "name":
                _("Dirty Eggs"),
                "value":
                "%s" % f.formatLang(getAvg("eggs_dirty")["avg"])
            }, {
                "name":
                _("Eggs Weight"),
                "value":
                "%s g" % f.formatLang(getAvg("eggs_weight")["avg"])
            }, {
                "name":
                _("Egg Performance"),
                "value":
                "%s %%" % f.formatLang(getAvg("eggs_performance")["avg"])
            }, {
                "name": _("Loss"),
                "value": "%s" % sum_loss,
            }, {
                "name": _("Chicken Count"),
                "value": "%s" % chicken_count
            }, {
                "name": _("Chicken Weight"),
                "value": "%s kg" % f.formatLang(first_weight)
            }, {
                "name": _("Week Age"),
                "value": "%s" % chicken_age_weeks
            }, {
                "name":
                _("Feed"),
                "value":
                "%s kg" % f.formatLang(getAvg("feed")["avg"], digits=0)
            }, {
                "name": _("Water"),
                "value": "%s l" % f.formatLang(getAvg("water")["avg"])
            }]
        }
예제 #20
0
 def action_create_contract(self, cr, uid, ids, context=None):
   account_obj = self.pool["account.analytic.account"]
   project_obj = self.pool["project.project"]
   
   for line in self.browse(cr, uid, ids, context=context):
     if line.is_contract:
       contract = None
       contract_id = False
       contract_ids = []
       if line.contract_id:
         contract = line.contract_id
         contract_id = line.contract_id.id
         contract_ids = [contract_id]
         
       
       # check
       if not line.contract_name or not line.contract_start:
         raise Warning(_("No contract name or start date for %s") % line.name)
       if line.contract_start < util.currentDate():
         raise Warning(_("Contract start date is before current date for %s") % line.name)
       if line.contract_end and line.contract_end < line.contract_start:
         raise Warning(_("Contract end date is before contract start date %s" % line.name))
       
       # check task specific
       if line.is_task:
         if not line.contract_start_task:
           raise Warning(_("No task start date for %s") % line.name)
         if line.contract_start_task < util.currentDate():
           raise Warning(_("Task start date is before current date for %s") % line.name)
           
     
       # get values
       values = self._prepare_contract(cr, uid, line, context=context)
       if not values:
         continue
                 
       product = line.product_id
       recurring_tmpl = product.recurring_tmpl_id
       recurring_task = False
       
       # partner values
       helper.onChangeValuesPool(cr, uid, account_obj, values, 
         account_obj.on_change_partner_id(cr, uid, contract_ids, values.get("partner_id"), name=values.get("name"), context=context), 
         context=context)
       
       if recurring_tmpl:
         
         # recurring values
         values["template_id"] = recurring_tmpl.id
         helper.onChangeValuesPool(cr, uid, account_obj, values, 
           account_obj.on_change_template(cr, uid, contract_ids, recurring_tmpl.id, date_start=values.get("date_start"), context=context), 
           context=context)
         
         # check if tonract already exist
         if contract:
           # recurring task update
           if not values.get("recurring_task_ids") and contract.recurring_task_ids:
             recurring_task_update = []
             for rec_task in contract.recurring_task_ids:
               recurring_task_update.append((1,rec_task.id, {
                 "name": rec_task.name,
                 "product_id": rec_task.product_id.id, 
                 "description": rec_task.description,
                 "planned_hours": rec_task.planned_hours,
                 "repeat": rec_task.repeat
               }))
             values["recurring_task_ids"] = recurring_task_update
             
           # recurring invoice update
           if not values.get("recurring_invoice_line_ids") and contract.recurring_invoice_line_ids:
             recurring_inv_update = []
             for rec_inv in contract.recurring_invoice_line_ids:
               recurring_inv_update.append((1, rec_inv.id, {
                 "product_id": rec_inv.product_id.id,
                 "uom_id": rec_inv.uom_id.id,
                 "name": rec_inv.name,
                 "quantity": rec_inv.quantity,
                 "price_unit": rec_inv.price_unit
               }))
               values["recurring_invoice_line_ids"] = recurring_inv_update
         
       else:
         # build on product
         
         # check if task should created automatically
         if product.auto_create_task:
           values["recurring_task"] = True
           values["recurring_interval"] = product.recurring_interval
           values["recurring_task_rule"] = product.recurring_rule_type
           values["recurring_task_next"] = line.contract_start_task
           
           # check for existing task line
           recurring_task_id = 0
           recurring_found = 0
           if contract:
             for recurring_task in contract.recurring_task_ids:
               recurring_task_id = recurring_task.id
               recurring_found = 1 
           
           # prepare recurrent task template
           values["recurring_task_ids"] = [(recurring_found, recurring_task_id, {
             "name": line.name.split("\n")[0],
             "product_id": line.product_id.id, 
             "description": line.procurement_note,
             "planned_hours": product.planned_hours                
           })]
             
         # billed at cost task
         if product.auto_create_task and product.billed_at_cost:
           values["invoice_on_timesheets"] = True
           
           # enable invoice on timesheets
           helper.onChangeValuesPool(cr, uid, account_obj, values, 
                                      account_obj.onchange_invoice_on_timesheets(cr, uid, contract_ids, True, context=context), 
                                      context=context)
           
         else:
           values["recurring_invoices"] = True
           values["recurring_interval"] = product.recurring_interval
           values["recurring_rule_type"] = product.recurring_rule_type
           
           # check for existing line
           recurring_invoice_line_id = 0
           recurring_found = 0
           if contract:
             for recurring_invoice_line in  contract.recurring_invoice_line_ids:
               recurring_invoice_line_id = recurring_invoice_line.id
               recurring_found = 1
                             
           # only create invoice if it isn't a billed at cost task              
           values["recurring_invoice_line_ids"] = [(recurring_found, recurring_invoice_line_id, {
             "product_id": product.id,
             "uom_id": line.product_uom.id,
             "name": line.name,
             "quantity": line.product_uom_qty,
             "price_unit": line.price_unit
           })]
       
       
       # calc contract
       self._calc_contract(cr, uid, line, values, context)          
       if contract_id:
         # update
         account_obj.write(cr, uid, contract_id, values, context=context)
       else:
         # create
         shop = line.order_id.shop_id
         project_template = shop.project_template_id
         if project_template:
           project_id = project_obj.copy(cr, uid, project_template.id, values, context=context)
           account_id = project_obj.browse(cr, uid, project_id, context=context).analytic_account_id.id
           self.write(cr, uid, line.id, {"contract_id": account_id}, context=context)            
         else:
           account_id = account_obj.create(cr, uid, values, context=context)
           self.write(cr, uid, line.id, {"contract_id": account_id}, context=context)
       
   return True
예제 #21
0
    def model_copy(self, cr, uid, ids, context=None):
        for row in self.read(cr, uid, ids, context=context):
            if not row.get('cron_id', False):
                continue
            cron_ids = [row['cron_id'][0]]
            remaining = self.pool.get('ir.cron').read(
                cr, uid, cron_ids, ['numbercall'])[0]['numbercall']
            model = None
            try:
                (model_name, oid) = row['doc_source'].split(',')
                oid = int(oid)
                model = self.pool.get(model_name)
            except:
                raise osv.except_osv(
                    _('Wrong Source Document !'),
                    _('Please provide another source document.\nThis one does not exist !'
                      ))

            default = {'state': 'draft'}
            doc_obj = self.pool.get('subscription.document')
            document_ids = doc_obj.search(cr, uid,
                                          [('model.model', '=', model_name)])
            doc = doc_obj.browse(cr, uid, document_ids)[0]
            for f in doc.field_ids:
                value = False
                if f.value == 'date':
                    value = util.currentDate()
                elif f.value == 'text' and f.value_text:
                    field_values = {}
                    curDate = util.currentDate()
                    it = re.finditer(PATTERN_TEXTSUBST, f.value_text)
                    for m in it:
                        field_name = m.group(1)
                        if (field_name == "year"):
                            field_values[field_name] = util.formatDate(
                                curDate, "%Y")
                        elif (field_name == "month"):
                            field_values[field_name] = util.formatDate(
                                curDate, "%m")
                        elif (field_name == "month_name"):
                            field_values[field_name] = helper.getMonth(
                                cr, uid, curDate, context)
                        else:
                            field_values[field_name] = model.read(
                                cr, uid, oid, [field_name],
                                context)[field_name]
                    value = f.value_text % field_values

                default[f.field.name] = value

            state = 'running'

            # if there was only one remaining document to generate
            # the subscription is over and we mark it as being done
            if remaining == 1:
                state = 'done'
            copy_id = model.copy(cr, uid, oid, default, context)
            self.pool.get('subscription.subscription.history').create(
                cr, uid, {
                    'subscription_id': row['id'],
                    'date': time.strftime('%Y-%m-%d %H:%M:%S'),
                    'document_id': model_name + ',' + str(copy_id)
                })
            self.write(cr, uid, [row['id']], {'state': state})
        return True
예제 #22
0
    def do_assumption(self, cr, uid, ids, context=None):

        btakeover_line_obj = self.pool.get("account.btakeover.line")
        account_obj = self.pool.get("account.account")
        move_obj = self.pool.get("account.move")
        journal_obj = self.pool.get("account.journal")
        period_obj = self.pool.get("account.period")
        #currency_obj = self.pool.get("res.currency")
        #currency_id = currency_obj.search(cr, uid, [("symbol", "=", "€")])

        user = self.pool.get("res.users").browse(cr, uid, uid)
        for btakeover in self.browse(cr, uid, ids):
            for line in btakeover.line_ids:
                account_ids = account_obj.search(
                    cr, uid, [("code", "=", line.code),
                              ("company_id", "=", user.company_id.id)])
                account_id = account_ids and account_ids[0] or None
                if account_id:
                    balance = account_obj._compute_account(
                        cr,
                        uid, [account_id],
                        date_till=btakeover.date,
                        context=context)[account_id]
                    balance_is = float(balance["balance"])
                    balance_diff = balance_is - line.balance_nominal

                else:
                    raise osv.except_osv(
                        _('Error'),
                        _('There is no account for the entered code!'))
                name = str(
                    journal_obj.create_sequence(
                        cr, uid, {
                            "name": btakeover.journal_id.name,
                            "code": btakeover.journal_id.code
                        }, context))
                date = btakeover.date
                if not date:
                    date = util.currentDate()
                period = period_obj.search(
                    cr, uid, [("date_start", "=", util.getFirstOfMonth(date))])
                account = account_obj.browse(cr, uid, account_id)
                values = {
                    "name":
                    name,
                    "ref":
                    _("Balance Correction %s" % (btakeover.name)),
                    "period_id":
                    period[0],
                    "journal_id":
                    btakeover.journal_id.id,
                    "date":
                    date,
                    "amount":
                    line.balance_nominal,
                    "line_id": [(0, 0, {
                        "name":
                        name,
                        "account_id":
                        btakeover.account_id.id,
                        "currency_id":
                        account.currency_id.id,
                        "period_id":
                        period[0],
                        "journal_id":
                        btakeover.journal_id.id,
                        "debit":
                        balance_diff > 0.0 and balance_diff or 0.0,
                        "credit":
                        balance_diff < 0.0 and (balance_diff * -1) or 0.0
                    }),
                                (0, 0, {
                                    "name":
                                    name,
                                    "account_id":
                                    account_id,
                                    "currency_id":
                                    account.currency_id.id,
                                    "period_id":
                                    period[0],
                                    "journal_id":
                                    btakeover.journal_id.id,
                                    "debit":
                                    balance_diff < 0.0 and (balance_diff * -1)
                                    or 0.0,
                                    "credit":
                                    balance_diff > 0.0 and balance_diff or 0.0
                                })]
                }
                move_id = move_obj.create(cr, uid, values, context)

                btakeover_line_obj.write(
                    cr, uid, line.id, {
                        "state": "assumed",
                        "move_id": move_id,
                        "balance_is": balance_is
                    }, context)
            self.write(cr, uid, btakeover.id, {
                "state": "assumed",
                "date": date
            })
        return True
예제 #23
0
class account_btakeover(osv.osv):
    def copy_data(self, cr, uid, id, default=None, context=None):
        if not default:
            default = {}
        btakeover = self.browse(cr, uid, id)
        default.update({"state": "draft", "name": btakeover.name + _(" copy")})

        res = super(account_btakeover, self).copy_data(cr, uid, id, default,
                                                       context)
        return res

    def do_draft(self, cr, uid, ids, context):
        btakeover_line_obj = self.pool.get("account.btakeover.line")
        move_obj = self.pool.get("account.move")

        for record in self.browse(cr, uid, ids):
            for line in record.line_ids:

                btakeover_line_obj.write(cr, uid, line.id, {"state": "draft"},
                                         context)
                move_obj.button_cancel(cr,
                                       uid, [line.move_id.id],
                                       context=context)
                move_obj.unlink(cr, uid, [line.move_id.id], context=context)
            self.write(cr, uid, record.id, {"state": "draft"})

        return True

    def do_assumption(self, cr, uid, ids, context=None):

        btakeover_line_obj = self.pool.get("account.btakeover.line")
        account_obj = self.pool.get("account.account")
        move_obj = self.pool.get("account.move")
        journal_obj = self.pool.get("account.journal")
        period_obj = self.pool.get("account.period")
        #currency_obj = self.pool.get("res.currency")
        #currency_id = currency_obj.search(cr, uid, [("symbol", "=", "€")])

        user = self.pool.get("res.users").browse(cr, uid, uid)
        for btakeover in self.browse(cr, uid, ids):
            for line in btakeover.line_ids:
                account_ids = account_obj.search(
                    cr, uid, [("code", "=", line.code),
                              ("company_id", "=", user.company_id.id)])
                account_id = account_ids and account_ids[0] or None
                if account_id:
                    balance = account_obj._compute_account(
                        cr,
                        uid, [account_id],
                        date_till=btakeover.date,
                        context=context)[account_id]
                    balance_is = float(balance["balance"])
                    balance_diff = balance_is - line.balance_nominal

                else:
                    raise osv.except_osv(
                        _('Error'),
                        _('There is no account for the entered code!'))
                name = str(
                    journal_obj.create_sequence(
                        cr, uid, {
                            "name": btakeover.journal_id.name,
                            "code": btakeover.journal_id.code
                        }, context))
                date = btakeover.date
                if not date:
                    date = util.currentDate()
                period = period_obj.search(
                    cr, uid, [("date_start", "=", util.getFirstOfMonth(date))])
                account = account_obj.browse(cr, uid, account_id)
                values = {
                    "name":
                    name,
                    "ref":
                    _("Balance Correction %s" % (btakeover.name)),
                    "period_id":
                    period[0],
                    "journal_id":
                    btakeover.journal_id.id,
                    "date":
                    date,
                    "amount":
                    line.balance_nominal,
                    "line_id": [(0, 0, {
                        "name":
                        name,
                        "account_id":
                        btakeover.account_id.id,
                        "currency_id":
                        account.currency_id.id,
                        "period_id":
                        period[0],
                        "journal_id":
                        btakeover.journal_id.id,
                        "debit":
                        balance_diff > 0.0 and balance_diff or 0.0,
                        "credit":
                        balance_diff < 0.0 and (balance_diff * -1) or 0.0
                    }),
                                (0, 0, {
                                    "name":
                                    name,
                                    "account_id":
                                    account_id,
                                    "currency_id":
                                    account.currency_id.id,
                                    "period_id":
                                    period[0],
                                    "journal_id":
                                    btakeover.journal_id.id,
                                    "debit":
                                    balance_diff < 0.0 and (balance_diff * -1)
                                    or 0.0,
                                    "credit":
                                    balance_diff > 0.0 and balance_diff or 0.0
                                })]
                }
                move_id = move_obj.create(cr, uid, values, context)

                btakeover_line_obj.write(
                    cr, uid, line.id, {
                        "state": "assumed",
                        "move_id": move_id,
                        "balance_is": balance_is
                    }, context)
            self.write(cr, uid, btakeover.id, {
                "state": "assumed",
                "date": date
            })
        return True

    _name = "account.btakeover"
    _columns = {
        "name":
        fields.char("Name", size=64, required=True),
        "date":
        fields.date("Date"),
        "journal_id":
        fields.many2one("account.journal",
                        "Journal",
                        required=True,
                        domain=[("type", "=", "general")]),
        "line_ids":
        fields.one2many("account.btakeover.line", "btakeover_id", "Lines"),
        "state":
        fields.selection([("draft", "Draft"), ("assumed", "Assumed")],
                         "State",
                         readonly=True),
        "account_id":
        fields.many2one("account.account", "Account", required=True)
    }

    _defaults = {
        "date": util.currentDate(),
        "state": "draft",
    }
예제 #24
0
파일: timesheet.py 프로젝트: suningwz/fdoo
    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
예제 #25
0
파일: analytic.py 프로젝트: suningwz/fdoo
    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
예제 #26
0
    def barkeeper_status(self, cr, uid, options, context=None):
        order_obj = self.pool["pos.order"]
        session_obj = self.pool["pos.session"]
        config_obj = self.pool["pos.config"]
        company_obj = self.pool["res.company"]

        company_id = company_obj._company_default_get(cr, uid, context=context)
        company = company_obj.browse(cr, uid, company_id, context=context)
        currency = company.currency_id.symbol

        # result
        stat = {
            "title": _("No Data"),
            "currency": currency,
            "name": "",
            "group": "",
            "range": ""
        }

        # search first order if
        # and build default options
        # if no options are passed
        config_id = None
        config = None
        date = None
        mode = "today"
        if options:
            config_id = options.get("config_id")
            # if mode is today
            # date is none
            mode = options.get("mode")
            if not mode or mode == "today":
                date = None
                options["mode"] = "today"
            else:
                date = options.get("date")

        nodata = False
        if not config_id or not date:
            # get latest order
            order_id = None
            if config_id:
                config = config_obj.browse(cr, uid, config_id, context=context)
                order_id = order_obj.search_id(
                    cr,
                    uid, [
                        '|', ("session_id.config_id", "=", config_id),
                        ('session_id.config_id.parent_user_id', '=',
                         config.user_id.id)
                    ],
                    order="date_order desc",
                    context=None)
            else:
                order_id = order_obj.search_id(cr,
                                               uid,
                                               [("session_id", "!=", False)],
                                               order="date_order desc",
                                               context=None)

            # check if order exist
            if order_id:
                order = order_obj.browse(cr, uid, order_id, context=context)

                # get parent
                config = order.session_id.config_id
                while config.parent_user_id:
                    parent_config_id = config_obj.search_id(
                        cr,
                        uid, [("user_id", "=", config.parent_user_id.id)],
                        context=context)
                    if not parent_config_id or parent_config_id == config.id:
                        break
                    config = config_obj.browse(cr,
                                               uid,
                                               parent_config_id,
                                               context=context)

                config_id = config.id
                options = {
                    "mode": "today",
                    "date": util.timeToDateStr(order.date_order),
                    "config_id": config_id
                }
            else:
                nodata = True

        # set options
        stat["options"] = options

        # if not data return
        if not config_id:
            return stat

        # get current mode
        if not config or config.id != config_id:
            config = config_obj.browse(cr, uid, config_id, context=context)
        config_ids = [config_id]

        # build title and group description
        stat["name"] = config.name
        if config.user_id:
            group = []
            childEntries = config_obj.search_read(
                cr,
                uid, [("parent_user_id", "=", config.user_id.id)],
                ["name", "sign_pid"],
                context=context)
            for childEntry in childEntries:
                group.append(childEntry["sign_pid"] or childEntry["name"])
                config_ids.append(childEntry["id"])
            if group:
                group.insert(0, config.sign_pid or config.name)
            stat["group"] = ", ".join(group)

        # return if no default data
        if nodata:
            return stat

        # find start
        statDate = options.get("date")
        if not statDate:
            options["date"] = statDate = util.currentDate()

        # add amount
        orderDicts = []

        def addAmount(amount, amountStat, sections, count=False):
            for section in sections:

                subsections = None
                sectionStat = None

                if len(section) == 1:
                    key = section[0]
                    sectionStat = amountStat.get(key)
                    if sectionStat is None:
                        sectionStat = {
                            "amount": 0.0,
                            "count": 0,
                            "currency": currency
                        }
                        amountStat[key] = sectionStat

                elif len(section) >= 2:
                    field = section[0]
                    key = section[1]

                    if len(section) >= 3:
                        subsections = section[2]

                    keyStat = amountStat.get(field)
                    if keyStat is None:
                        keyStat = {}
                        amountStat[field] = keyStat
                        orderDicts.append((amountStat, field, keyStat))

                    sectionStat = keyStat.get(key)
                    if sectionStat is None:
                        sectionStat = {
                            "key": key,
                            "amount": 0.0,
                            "count": 0,
                            "currency": currency
                        }
                        keyStat[key] = sectionStat

                sectionStat["amount"] = sectionStat["amount"] + amount
                if count:
                    sectionStat["count"] = sectionStat["count"] + 1

                if subsections:
                    addAmount(amount, sectionStat, subsections, count=count)

        # setup range
        time_keyfunc = lambda date_order: helper.strToLocalDateStr(
            cr, uid, date_order, context=context)
        if mode == "year":
            stat["title"] = _("Year")
            startDate = util.getFirstOfYear(statDate)
            endDate = util.getFirstOfNextYear(statDate)
            dt_delta = relativedelta(years=1)
            time_keyfunc = lambda date_order: helper.strToLocalDateStr(
                cr, uid, date_order, context=context)[:7]
        elif mode == "month":
            stat["title"] = _("Month")
            startDate = util.getFirstOfMonth(statDate)
            endDate = util.getFirstOfNextMonth(statDate)
            dt_delta = relativedelta(months=1)
        elif mode == "week":
            stat["title"] = _("Week")
            startDate = util.getFirstOfWeek(statDate)
            endDate = util.getFirstOfNextWeek(statDate)
            dt_delta = relativedelta(weeks=1)
        else:
            time_keyfunc = lambda date_order: "%s:00" % helper.strToLocalTimeStr(
                cr, uid, date_order, context=context).split(" ")[1][:2]
            stat["title"] = _("Day")
            startDate = statDate
            endDate = util.getNextDayDate(statDate)
            dt_delta = relativedelta(hours=1)

        # query session build range
        session_ids = session_obj.search(cr,
                                         uid,
                                         [("start_at", ">=", startDate),
                                          ("start_at", "<", endDate),
                                          ("config_id", "in", config_ids)],
                                         order="start_at asc",
                                         context=context)
        stat["range"] = helper.getRangeName(cr,
                                            uid,
                                            startDate,
                                            util.getPrevDayDate(endDate),
                                            context=context)

        # query orders
        order_ids = order_obj.search(cr,
                                     uid, [("session_id", "in", session_ids)],
                                     order="date_order asc",
                                     context=context)
        orders = order_obj.browse(cr, uid, order_ids, context=context)

        # build base
        addAmount(0, stat, [("total", )])
        if orders:
            firstOrder = orders[0]
            lastOrder = orders[-1]

            curTime = util.strToTime(firstOrder.date_order)
            timeEnd = util.strToTime(lastOrder.date_order)
            while curTime <= timeEnd:
                time_key = time_keyfunc(util.timeToStr(curTime))
                addAmount(0, stat, [("byTime", time_key)])
                curTime += dt_delta

        # iterate orders
        for order in orders:
            # check if it is relevant
            fpos_order = order.fpos_order_id
            notbalance = fpos_order.tag != "s"
            user = order.user_id

            # add turnover for journal
            for st in order.statement_ids:
                journal = st.journal_id
                amount = notbalance and st.amount or 0.0
                addAmount(
                    amount, stat,
                    [("byJournal", journal.name),
                     ("byUser", user.name, [("byJournal", journal.name)])],
                    True)

            # add to order
            time_key = time_keyfunc(order.date_order)
            amount = notbalance and order.amount_total or 0.0
            addAmount(amount, stat,
                      [("total", ),
                       ("byTime", time_key, [("byUser", user.name)])], True)

        # sort dicts
        for (parent, key, value) in orderDicts:
            parent[key] = value and sorted(value.values(),
                                           key=lambda en: en["key"]) or []

        return stat
예제 #27
0
파일: analytic.py 프로젝트: suningwz/fdoo
class account_analytic_account(osv.osv):    
    
    def name_get(self, cr, uid, ids, context=None):
        ids = util.idList(ids)
        res = super(account_analytic_account,self).name_get(cr,uid,ids,context=context)        
        if ids:
            cr.execute("SELECT a.id, p.name FROM account_analytic_account AS a "
                       " INNER JOIN res_partner AS p ON p.id = a.partner_id "
                       " WHERE a.id IN %s",
                       (tuple(ids),))
            
            partner_names = {}            
            for row in cr.fetchall():
                partner_names[row[0]] = row[1]            
                
            new_res = []
            for value in res:
                cur_id = value[0]
                cur_name = value[1]                
                name = partner_names.get(cur_id)                
                if name:
                    new_res.append((cur_id,cur_name + " [" + name + "]"))                    
                else:
                    new_res.append(value)
                       
            return new_res                 
        return res
      
    def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):        
        res = super(account_analytic_account,self).name_search(cr,uid,name,args=args,operator=operator,context=context,limit=limit)   
        if not res:
            account_ids = self.search(cr, uid, [("partner_id.name", operator, name)], limit=limit, context=context)
            if account_ids:
                return self.name_get(cr, uid, account_ids, context=context)
                        
            order_res = self.pool.get("sale.order").name_search(cr,uid,name,args=None,operator=operator,context=context,limit=limit)
            res = []
            if order_res:
                ids = [x[0] for x in order_res]
                analytic_id_for_order = {}
                cr.execute("SELECT id,project_id FROM sale_order WHERE id IN %s AND project_id IS NOT NULL",(tuple(ids),))                
                for row in cr.fetchall():
                    analytic_id_for_order[row[0]]=row[1]                    
                for tup in order_res:
                    analytic_id = analytic_id_for_order.get(tup[0])
                    if analytic_id:
                        res.append((analytic_id,tup[1]))
        return res
    
    def on_change_template(self, cr, uid, ids, template_id, date_start=False, context=None):
        res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, date_start=date_start, context=context)
        
        if template_id:
            template = self.browse(cr, uid, template_id, context=context)
            values = res["value"]
            if not ids:
                # take shop
                shop = template.shop_id
                if shop:
                  values["shop_id"] = shop.id
              
                # overtake prepaid
                values["recurring_prepaid"] = template.recurring_prepaid
                recurring_task_obj = self.pool("account.analytic.recurring.task")
                
                # overtake recurring task values
                recurring_task_vals = []
                for recurring_task in template.recurring_task_ids:
                  recurring_task_copy = recurring_task_obj.copy_data(cr, uid, recurring_task.id, context=context)
                  del recurring_task_copy["analytic_account_id"]
                  recurring_task_vals.append((0, 0, recurring_task_copy))
                  
                values["recurring_task"] = template.recurring_task
                values["recurring_task_interval"] = template.recurring_task_interval
                values["recurring_task_rule"] = template.recurring_task_rule
                values["recurring_task_ids"] = recurring_task_vals

        return res
      
    def unlink(self, cr, uid, ids, context=None):
        # unlink project if it is contract
        project_obj = self.pool.get('project.project')
        for account in self.browse(cr, uid, ids, context=context):
          if account.is_contract:            
            project_ids = project_obj.search(cr, uid, [('analytic_account_id','in',ids)])
            if project_ids:
              project_obj.unlink(cr, uid, project_ids, context=context)
        return super(account_analytic_account, self).unlink(cr, uid, ids, context=context)

    
    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 _root_account(self, cr, uid, ids, field_name, arg, context=None):
        res = dict.fromkeys(ids)
        for obj in self.browse(cr, uid, ids, context):
            parent = obj.parent_id            
            if parent:
                while parent.parent_id:
                    parent = parent.parent_id
                res[obj.id] = parent.id
        return res
    
    def _relids_account(self, cr, uid, ids, context=None):
        res = self.search(cr, uid, [("id","child_of",ids)], context=context)
        return res
    
    def onchange_recurring_task(self, cr, uid, ids, recurring_task, date_start=False, context=None):
        if date_start and recurring_task:
            return {'value': {'recurring_task_next': date_start}}
        return {}
    
    def recurring_task_create(self, cr, uid, ids, context=None):
        return self._recurring_task_create(cr, uid, ids, context=context)
   
    def _cron_recurring_task_create(self, cr, uid, context=None):
        return self._recurring_task_create(cr, uid, [], automatic=True, context=context)

    def _recurring_task_prepare(self, cr, uid, project, recurring_task, interval_name, next_date, context=None):
        name = "%s %s" % (recurring_task.name, interval_name)
        values = {
          "name": name,
          "description": recurring_task.description,
          "project_id": project.id,
          "planned_hours": recurring_task.planned_hours,
          "sequence": recurring_task.sequence,
          "date_deadline": util.getPrevDayDate(next_date),          
        }
        product = recurring_task.product_id
        if product:
          values["inv_product_id"] = product.id
        return values

    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

    
    _inherit = "account.analytic.account"    
    _columns = {
        "order_id" : fields.many2one("sale.order", "Order", ondelete="cascade", copy=False, select=True),
        "shop_id" : fields.many2one("sale.shop", "Shop", select=True),
        "recurring_prepaid" : fields.boolean("Prepaid"),
        "root_account_id" : fields.function(_root_account, type="many2one", obj="account.analytic.account", string="Root", select=True, store={
            "account.analytic.account" : (_relids_account, ["parent_id"], 10)
        }),
        "is_contract": fields.boolean("Contract"),
        "section_id": fields.related("order_id", "section_id", type="many2one", relation="crm.case.section", string="Sales Team"),
        "categ_ids" : fields.related("order_id", "categ_ids", type="many2many", relation="crm.case.categ", string="Tags",
                                     domain="['|', ('section_id', '=', section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}"),
               
        "recurring_task": fields.boolean("Recurring Tasks"),
        "recurring_task_ids": fields.one2many("account.analytic.recurring.task", "analytic_account_id", "Recurring Tasks", copy=True),
        "recurring_task_rule": fields.selection([
              ("daily", "Day(s)"),
              ("weekly", "Week(s)"),
              ("monthly", "Month(s)"),
              ("yearly", "Year(s)")], "Task Recurrency", help="Task automatically repeat at specified interval"),
        "recurring_task_interval": fields.integer("Repeat Task Every", help="Repeat every (Days/Week/Month/Year)"),        
        "recurring_task_next":  fields.date("Date of Next Task(s)"),
        
        "src_order_id" : fields.many2one("sale.order", "Source Order", ondelete="set null", copy=False, select=True),
        "src_section_id": fields.related("src_order_id", "section_id", type="many2one", relation="crm.case.section", string="Source Sales Team"),
        "src_categ_ids" : fields.related("src_order_id", "categ_ids", type="many2many", relation="crm.case.categ", string="Source Tags",
                                     domain="['|', ('section_id', '=', src_section_id), ('section_id', '=', False), ('object_id.model', '=', 'crm.lead')]", context="{'object_name': 'crm.lead'}")
        
    }
    _defaults = {
        "recurring_task_interval": 1,
        "recurring_task_next": lambda *a: util.currentDate(),
        "recurring_task_rule": "monthly"
    }
예제 #28
0
class account_dunning_wizard(osv.osv_memory):
    def create_reminders(self, cr, uid, ids, context=None):
        invoice_obj = self.pool.get("account.invoice")
        reminder_obj = self.pool.get("account.reminder")
        profile_line_obj = self.pool.get("account.dunning_profile_line")
        profile_obj = self.pool.get("account.dunning_profile")
        partner_obj = self.pool.get("res.partner")
        reminder_line_obj = self.pool.get("account.reminder.line")
        user = self.pool.get("res.users").browse(cr, uid, uid)

        # get profiles for shop
        profiles = profile_obj.browse(cr,
                                      uid,
                                      profile_obj.search(cr, uid, []),
                                      context=context)
        all_shops = set([s.id for s in profiles.mapped('shop_ids')])

        for wizard in self.browse(cr, uid, ids):
            cr.execute(
                "SELECT inv.partner_id FROM account_invoice inv WHERE inv.state='open' "
                " UNION "
                " SELECT r.partner_id FROM account_reminder r")

            partner_ids = [r[0] for r in cr.fetchall()]
            reminder_ids = []

            # check if there any partner ids
            if not partner_ids:
                break

            # shop id
            shop_ids = set()
            if wizard.profile_id.shop_ids:
                for shop in wizard.profile_id.shop_ids:
                    shop_ids.add(shop.id)

            customers = partner_obj.browse(cr,
                                           uid,
                                           partner_ids,
                                           context=context)
            for customer in customers:
                # get active reminder id
                reminder_id = reminder_obj.search_id(
                    cr, uid, [("partner_id", "=", customer.id),
                              ("profile_id", "=", wizard.profile_id.id)])
                if not customer.noremind:
                    commercial_partner = customer.commercial_partner_id
                    # check balance
                    # not commercial_partner.credit (should never happen, but it happens)
                    if not commercial_partner.credit or commercial_partner.credit > commercial_partner.debit or reminder_id:

                        # check invoice
                        invoice_ids = invoice_obj.search(
                            cr, uid, [("partner_id", "=", customer.id),
                                      ("type", "=", "out_invoice"),
                                      ("noremind", "=", False)])
                        if not invoice_ids:
                            continue

                        lines = []
                        max_profile_line = None
                        profile_line = None

                        # check invoices
                        for inv in invoice_obj.browse(cr, uid, invoice_ids):
                            # check if shop specific reminder defined
                            if all_shops:
                                inv_shop_id = inv.shop_id and inv.shop_id.id or 0
                                # check profile is a general reminder
                                # or continue if not
                                if not shop_ids and inv_shop_id in all_shops:
                                    continue
                                # check if it is a shop specific reminder
                                # or continue if not
                                if shop_ids and not inv_shop_id in shop_ids:
                                    continue

                            if (user.company_id == inv.company_id
                                ) and inv.payment_term and not inv.noremind:
                                reminder_line_id = reminder_line_obj.search_id(
                                    cr, uid,
                                    [("reminder_id", "=", reminder_id),
                                     ("invoice_id", "=", inv.id)])
                                if inv.state == "open":
                                    profile_line = profile_line_obj.line_next(
                                        cr, uid, wizard.profile_id,
                                        inv.profile_line_id, wizard.date,
                                        inv.date_due)

                                    # check if no dunning option
                                    if profile_line and profile_line.payment_no_dunning and inv.residual > 0 and inv.residual < inv.amount_total:
                                        profile_line = None

                                    invoice_obj.write(
                                        cr, uid, inv.id, {
                                            "profile_line_id":
                                            profile_line and profile_line.id
                                            or None,
                                            "dunning_date":
                                            wizard.date
                                        }, context)

                                    # check next remind
                                    if profile_line and inv.residual:
                                        line_values = {
                                            "invoice_id":
                                            inv.id,
                                            "profile_line_id":
                                            profile_line and profile_line.id
                                            or None,
                                            "amount":
                                            inv.residual
                                        }

                                        # update remind
                                        if not reminder_line_id:
                                            lines.append((0, 0, line_values))
                                        else:
                                            lines.append((1, reminder_line_id,
                                                          line_values))

                                        # determine max profile
                                        if max_profile_line:
                                            if max_profile_line.sequence < profile_line.sequence:
                                                max_profile_line = profile_line
                                        else:
                                            max_profile_line = profile_line

                        #update or create reminder
                        if max_profile_line:
                            values = {
                                "date": wizard.date,
                                "partner_id": customer.id,
                                "profile_id": wizard.profile_id.id,
                                "max_profile_line_id": max_profile_line.id,
                                "line_ids": lines,
                                "state": "validated"
                            }

                            # create or update reminder
                            if reminder_id:
                                reminder_obj.write(cr, uid, reminder_id,
                                                   values, context)
                            else:
                                reminder_id = reminder_obj.create(
                                    cr, uid, values, context)

                            # update lines
                            reminder_line_ids = []
                            for line in lines:
                                values = line[2]
                                values["reminder_id"] = reminder_id
                                line_id = line[1]
                                if not line_id:
                                    line_id = reminder_line_obj.create(
                                        cr, uid, values, context)
                                else:
                                    reminder_line_obj.write(
                                        cr, uid, line_id, values, context)
                                # add line
                                reminder_line_ids.append(line_id)

                            # only add if there are lines
                            if reminder_line_ids:
                                # delete unused lines
                                unused_line_ids = reminder_line_obj.search(
                                    cr,
                                    uid, [("reminder_id", "=", reminder_id),
                                          ("id", "not in", reminder_line_ids)],
                                    context=context)
                                reminder_line_obj.unlink(cr,
                                                         uid,
                                                         unused_line_ids,
                                                         context=context)
                                # add reminder
                                reminder_ids.append(reminder_id)

            # remove untouched, unused
            unused_reminder_ids = reminder_obj.search(
                cr, uid, [("id", "not in", reminder_ids),
                          ("profile_id", "=", wizard.profile_id.id)])
            reminder_obj.unlink(cr, uid, unused_reminder_ids, context=context)

        return {
            "name": _("Reminders"),
            "res_model": "account.reminder",
            "type": "ir.actions.act_window",
            "view_type": "form",
            "view_mode": "tree,form",
            "clear_breadcrumbs": True
        }

    def _default_profile_id(self, cr, uid, context=None):
        company_id = self.pool.get('res.users')._get_company(cr,
                                                             uid,
                                                             context=context)
        return self.pool.get("account.dunning_profile").search_id(
            cr, uid, [("company_id", "=", company_id)], context=context)

    _name = "account.dunning_wizard"
    _columns = {
        "date":
        fields.date("Reminder date", required=True),
        "profile_id":
        fields.many2one("account.dunning_profile", "Profile", required=True),
    }
    _defaults = {
        "date": lambda *a: util.currentDate(),
        "profile_id": _default_profile_id
    }