Ejemplo n.º 1
0
class AccountCode(models.Model):
    _name = 'budget.opex.account.code'
    _rec_name = 'account_code'
    _description = 'Account Code'
    _inherit = ['mail.thread']

    # CHOICES
    # ----------------------------------------------------------
    year_now = fields.Datetime.from_string(fields.Date.today()).year
    YEARS = [(year, year) for year in range(year_now - 10, year_now + 10)]
    STATES = choices_tuple(['draft', 'under process', 'authorized', 'closed'], is_sorted=False)

    # BASIC FIELDS
    # ----------------------------------------------------------
    state = fields.Selection(STATES, default='draft')

    year = fields.Selection(string='Year', selection=YEARS, default=year_now)
    account_code = fields.Char(string="Account Code", required=True)
    start_date = fields.Date(string="Start Date")
    expenditure_amount = fields.Monetary(currency_field='company_currency_id',
                                         string='Expenditure Amount')

    description = fields.Text(string="Description")
    grouping = fields.Text(string="Grouping")
    remarks = fields.Text(string="Remarks")

    # RELATIONSHIPS
    # ----------------------------------------------------------
    company_currency_id = fields.Many2one('res.currency', readonly=True,
                                          default=lambda self: self.env.user.company_id.currency_id)
    operation_id = fields.Many2one('budget.core.budget',
                                 domain=[('is_operation', '=', True),
                                         ('state', 'not in', ['draft'])],
                                 string='Cost Center'
                                 )
Ejemplo n.º 2
0
class Contract(models.Model):
    _name = 'budget.contractor.contract'
    _rec_name = 'contract_ref'
    _description = 'Contract'

    # CHOICES
    # ----------------------------------------------------------
    CATEGORIES = choices_tuple(
        ['consultancy', 'license', 'service', 'supply', 'support', 'turnkey'])
    STATES = choices_tuple(['active', 'closed'], is_sorted=False)
    CHANGE_TYPES = choices_tuple(['principal', 'amendment', 'addendum'],
                                 is_sorted=False)
    VERSIONS = [(i, '%d - %s' % (i, int_to_roman(i))) for i in range(1, 100)]
    SICET_TYPES = choices_tuple(['2a', 'a2/2b', '2b', '3'], is_sorted=False)
    SUB_SICET_TYPES = choices_tuple(['test1', 'test2', 'test3'],
                                    is_sorted=False)
    SYSTEM_TYPES = choices_tuple(['test1', 'test2', 'test3'], is_sorted=False)
    NETWORK_TYPES = choices_tuple(['test1', 'test2', 'test3'], is_sorted=False)

    # BASIC FIELDS
    # ----------------------------------------------------------
    state = fields.Selection(STATES, default='active')

    contract_no = fields.Char(string="Contract No")
    sicet_type = fields.Selection(SICET_TYPES)
    change_type = fields.Selection(CHANGE_TYPES, default='principal')
    version = fields.Selection(VERSIONS)

    amount = fields.Monetary(string='Contract Amount',
                             currency_field='company_currency_id')
    service_amount = fields.Monetary(string='Service Amount',
                                     currency_field='company_currency_id')
    material_amount = fields.Monetary(string='Material Amount',
                                      currency_field='company_currency_id')

    category = fields.Selection(CATEGORIES)
    # sub_sicet_type = fields.Selection(SUB_SICET_TYPES)
    # system_type = fields.Selection(SYSTEM_TYPES)
    # network_type = fields.Selection(NETWORK_TYPES)

    sign_date = fields.Date(string='Sign Date')
    commencement_date = fields.Date(string='Commencement Date')
    end_date = fields.Date(string='End Date')
    remarks = fields.Text(string='Remarks')

    # RELATIONSHIPS
    # ----------------------------------------------------------
    company_currency_id = fields.Many2one(
        'res.currency',
        readonly=True,
        default=lambda self: self.env.user.company_id.currency_id)
    budget_id = fields.Many2one('budget.core.budget', string='Budget No')
    contractor_id = fields.Many2one('res.partner',
                                    string='Contractor',
                                    domain=[('is_budget_contractor', '=', True)
                                            ])
    section_ids = fields.Many2many('res.partner',
                                   'section_contract_rel',
                                   'contract_id',
                                   'section_id',
                                   string="Sections",
                                   domain="[('is_budget_section','=',True)]")

    # COMPUTE FIELDS
    # ----------------------------------------------------------
    contract_ref = fields.Char(string="Contract Reference",
                               compute='_compute_contract_ref',
                               store=True)

    @api.one
    @api.depends('contract_no', 'change_type', 'version',
                 'contractor_id.alias')
    def _compute_contract_ref(self):
        change_type = '' if self.change_type == 'principal' and not self.change_type else self.change_type
        self.contract_ref = "{}/{} {} {}".format(
            self.contract_no or '', self.contractor_id.alias or '',
            change_type, self.version or '').upper()

    # CONSTRAINS FIELDS
    # ----------------------------------------------------------
    _sql_constraints = [
        ('contract_ref_uniq', 'unique(contract_ref)', 'Already Exist'),
    ]

    # BUTTON ACTIONS / TRANSITIONS
    # ----------------------------------------------------------
    @api.one
    def set2active(self):
        self.state = 'active'

    @api.one
    def set2close(self):
        self.state = 'closed'
Ejemplo n.º 3
0
class Invoice(models.Model):
    _name = 'budget.invoice.invoice'
    _rec_name = 'invoice_no'
    _description = 'Invoice'
    _order = 'id desc'
    _inherit = ['mail.thread']

    # CHOICES
    # ----------------------------------------------------------
    STATES = choices_tuple([
        'draft', 'verified', 'summary generated', 'under certification',
        'sent to finance', 'closed', 'on hold', 'rejected', 'amount hold'
    ],
                           is_sorted=False)
    INVOICE_TYPES = choices_tuple([
        'access network', 'supply of materials', 'civil works', 'cable works',
        'damage case', 'development', 'fdh uplifting', 'fttm activities',
        'maintenance work', 'man power', 'mega project', 'migration',
        'on demand activities', 'provisioning', 'recharge', 'recovery'
    ],
                                  is_sorted=False)
    PAYMENT_TYPES = choices_tuple(['ready for service', 'interim'],
                                  is_sorted=False)

    # BASIC FIELDS
    # ----------------------------------------------------------
    state = fields.Selection(STATES, default='draft')

    invoice_no = fields.Char(string="Invoice No")
    invoice_type = fields.Selection(INVOICE_TYPES)
    payment_type = fields.Selection(PAYMENT_TYPES)

    revenue_amount = fields.Monetary(string='Revenue Amount',
                                     currency_field='company_currency_id')
    opex_amount = fields.Monetary(string='OPEX Amount',
                                  currency_field='company_currency_id')
    capex_amount = fields.Monetary(string='CAPEX Amount',
                                   currency_field='company_currency_id')
    # TODO TRANSFER PENALTY TO PENALTY AMOUNT
    penalty = fields.Monetary(string='Penalty Amount',
                              currency_field='company_currency_id')
    penalty_amount = fields.Monetary(string='Penalty Amount',
                                     currency_field='company_currency_id')

    on_hold_amount = fields.Monetary(string='On Hold Amount',
                                     currency_field='company_currency_id')
    # TODO Make Validation for max 100%
    on_hold_percentage = fields.Float(string='On Hold Percent (%)',
                                      digits=(5, 2))

    invoice_date = fields.Date(string='Invoice Date')
    invoice_cert_date = fields.Date(string='Inv Certification Date')
    received_date = fields.Date(string='Received Date')
    signed_date = fields.Date(string='Signed Date')
    start_date = fields.Date(string='Start Date')
    end_date = fields.Date(string='End Date')
    rfs_date = fields.Date(string='RFS Date')
    reject_date = fields.Date(string='Reject Date')
    sent_finance_date = fields.Date(string='Sent to Finance Date')
    closed_date = fields.Date(string='Closed Date')
    cost_center = fields.Char(string="Cost Center")
    expense_code = fields.Char(string="Expense Code")
    remarks = fields.Text(string='Remarks')
    description = fields.Text(string='Description')
    # TODO proj_no to pec_no
    proj_no = fields.Char(string="Project No")
    pec_no = fields.Char(string="PEC No")

    # Used for Invoice Summary sequence
    sequence = fields.Integer('Display order')

    # RELATIONSHIPS
    # ----------------------------------------------------------
    company_currency_id = fields.Many2one(
        'res.currency',
        readonly=True,
        default=lambda self: self.env.user.company_id.currency_id)
    contract_id = fields.Many2one('budget.contractor.contract',
                                  string='Contract')
    task_id = fields.Many2one('budget.capex.task', string='Task')
    account_code_id = fields.Many2one('budget.opex.account.code',
                                      string='Account Code')
    summary_ids = fields.Many2many('budget.invoice.invoice.summary',
                                   'budget_invoice_summary_invoice',
                                   'invoice_id',
                                   'summary_id',
                                   string='Summaries')
    region_id = fields.Many2one('budget.enduser.region', string="Region")
    section_id = fields.Many2one('res.partner',
                                 string="Section",
                                 domain=[('is_budget_section', '=', True)])
    sub_section_id = fields.Many2one('res.partner',
                                     string="Sub Section",
                                     domain=[('is_budget_sub_section', '=',
                                              True)])

    # RELATED FIELDS
    # ----------------------------------------------------------
    related_contractor_id = fields.Many2one(
        string='Contractor', related='contract_id.contractor_id', store=True)
    related_authorized_amount = fields.Monetary(
        string='Authorized Amount', related='task_id.authorized_amount')
    related_utilized_amount = fields.Monetary(
        string='Utilized Amount (IM)', related='task_id.utilized_amount')
    related_total_amount = fields.Monetary(string='Utilized Amount (FN)',
                                           related='task_id.total_amount')
    # COMPUTE FIELDS
    # ----------------------------------------------------------
    problem = fields.Char(string='Problem',
                          compute='_compute_problem',
                          store=True)
    invoice_amount = fields.Monetary(string='Invoice Amount',
                                     currency_field='company_currency_id',
                                     compute='_compute_invoice_amount',
                                     store=True)
    certified_invoice_amount = fields.Monetary(
        string='Certified Amount',
        currency_field='company_currency_id',
        compute='_compute_certified_invoice_amount',
        inverse='_set_certified_invoice_amount',
        store=True)

    @api.one
    @api.depends('certified_invoice_amount', 'task_id.problem', 'invoice_no')
    def _compute_problem(self):
        # Checks Duplicate
        count = self.env['budget.invoice.invoice'].search_count([
            ('invoice_no', '=', self.invoice_no), ('state', '!=', 'rejected')
        ])
        if count > 1:
            self.problem = 'duplicate'

        elif self.task_id.problem != 'ok':
            self.problem = self.task_id.problem

        # TODO USE CATEGORY ALSO TO IGNORE Y
        elif self.state == 'draft':
            if self.task_id.authorized_amount < self.certified_invoice_amount + self.task_id.utilized_amount:
                self.problem = 'overrun'

        # TODO MUST BE PLACED IN ACTUALS
            if self.state == 'draft' and self.task_id.authorized_amount < self.certified_invoice_amount + self.task_id.total_amount:
                self.problem = 'overrun'

        else:
            self.problem = 'ok'

    @api.one
    @api.depends('revenue_amount', 'opex_amount', 'capex_amount')
    def _compute_invoice_amount(self):
        self.invoice_amount = self.opex_amount + \
                              self.capex_amount + \
                              self.revenue_amount

    @api.one
    def _set_certified_invoice_amount(self):
        if self.certified_invoice_amount != self.opex_amount + self.capex_amount + self.revenue_amount:
            self._compute_certified_invoice_amount()

    @api.one
    @api.depends('revenue_amount', 'opex_amount', 'capex_amount',
                 'penalty_amount', 'on_hold_amount')
    def _compute_certified_invoice_amount(self):
        self.certified_invoice_amount = self.opex_amount + \
                                        self.capex_amount + \
                                        self.revenue_amount - \
                                        self.penalty_amount - \
                                        self.on_hold_amount

    # ONCHANGE
    # ----------------------------------------------------------
    # certified_invoice_amount
    # on_hold_amount = certified_invoice_amount * on_hold_percentage / 100.00
    # on_hold_percentage = on_hold_amount / certified_invoice_amount * 100.00

    @api.onchange('on_hold_amount')
    def onchange_on_hold_percentage(self):
        total_amount = self.opex_amount + self.capex_amount + self.revenue_amount - self.penalty_amount
        # if self.on_hold_amount != total_amount * self.on_hold_percentage / 100.00:
        if total_amount > 0.00:
            self.on_hold_percentage = self.on_hold_amount / total_amount * 100.00

    @api.onchange('on_hold_percentage')
    def onchange_on_hold_amount(self):
        total_amount = self.opex_amount + self.capex_amount + self.revenue_amount - self.penalty_amount
        # if self.on_hold_percentage != self.on_hold_amount / total_amount * 100.00:
        self.on_hold_amount = total_amount * self.on_hold_percentage / 100.00

    # BUTTONS/TRANSITIONS
    # ----------------------------------------------------------
    @api.one
    def set2draft(self):
        self.state = 'draft'

    @api.one
    def set2verified(self):
        self.state = 'verified'

    @api.one
    def set2summary_generated(self):
        self.state = 'summary generated'

    @api.one
    def set2under_certification(self):
        self.state = 'under certification'

    @api.one
    def set2sent_to_finance(self):
        self.state = 'sent to finance'

    @api.one
    def set2closed(self):
        self.state = 'closed'

    @api.one
    def set2on_hold(self):
        self.state = 'on hold'

    @api.one
    def set2rejected(self):
        self.state = 'rejected'

    @api.one
    def set2amount_hold(self):
        self.state = 'amount hold'
Ejemplo n.º 4
0
class Task(models.Model):
    _name = 'budget.capex.task'
    _rec_name = 'no'
    _description = 'Task'
    _inherit = ['mail.thread']

    # CHOICES
    # ----------------------------------------------------------
    year_now = fields.Datetime.from_string(fields.Date.today()).year
    YEARS = [(year, year) for year in range(year_now - 10, year_now + 10)]
    STATES = choices_tuple(['draft', 'under process', 'authorized', 'closed'], is_sorted=False)

    # BASIC FIELDS
    # ----------------------------------------------------------
    state = fields.Selection(STATES, default='draft')
    category = fields.Char(string="Category")
    year = fields.Selection(string='Year', selection=YEARS, default=year_now)

    no = fields.Char(string="Task No", required=True)
    description = fields.Text(string="Task Description")
    start_date = fields.Date(string="Task Start Date")
    expenditure_amount = fields.Monetary(currency_field='company_currency_id',
                                         string='Expenditure Amount')
    commitment_amount = fields.Monetary(currency_field='company_currency_id',
                                        string='Commitment Amount')
    initial_progress = fields.Float(string='Initial Progress')
    pec_no = fields.Char(string="Pec No")
    remarks = fields.Text(string="Remarks")

    # TODO ACTUAL
    total_amount = fields.Monetary(currency_field='company_currency_id',
                                   string='Utilized Amount (FN)')
    # TODO ACTUAL
    authorized_amount = fields.Monetary(currency_field='company_currency_id',
                                        string='Authorized Amount (FN)')
    # TODO NEED TO BE REVIEW IF TO BE REMOVE OR NOT
    gmo_no = fields.Char(string='GMO No')
    po_no = fields.Char(string='PO No')
    is_modernization = fields.Boolean(string='Is Modernization')
    # RELATIONSHIPS
    # ----------------------------------------------------------
    company_currency_id = fields.Many2one('res.currency', readonly=True,
                                          default=lambda self: self.env.user.company_id.currency_id)
    child_ids = fields.One2many('budget.capex.task',
                                'parent_id',
                                domain=[('is_child', '=', True)],
                                string="Child Tasks")

    progress_ids = fields.One2many('budget.capex.task.progress',
                                   'id',
                                   string="Individual Progress")

    investment_area_id = fields.Many2one('budget.capex.task.investment.area', string="Investment Area")
    region_id = fields.Many2one('budget.enduser.region', string="Region")
    project_id = fields.Many2one('budget.core.budget',
                                 domain=[('is_project', '=', True),
                                         ('state', 'not in', ['draft'])],
                                 string='Project No'
                                 )

    # COMPUTE FIELDS
    # ----------------------------------------------------------
    total_expenditure_amount = fields.Monetary(compute='_compute_total_expenditure_amount',
                                               currency_field='company_currency_id',
                                               string='Total Expenditure Amount',
                                               store=True)
    total_commitment_amount = fields.Monetary(compute='_compute_total_commitment_amount',
                                              currency_field='company_currency_id',
                                              string='Total Commitment Amount',
                                              store=True)
    accrual_amount = fields.Monetary(compute='_compute_accrual_amount',
                                     currency_field='company_currency_id',
                                     string='Accrual Amount',
                                     store=True)
    progress = fields.Float(compute='_compute_progress',
                            string='Progress',
                            store=True)

    @api.one
    @api.depends('child_ids', 'child_ids.expenditure_amount', 'child_ids.state', 'state')
    def _compute_total_expenditure_amount(self):
        self.total_expenditure_amount = sum(self.child_ids. \
                                            filtered(lambda r: r.state not in ['draft']). \
                                            mapped('expenditure_amount'))
        if self.state not in ['draft']:
            self.total_expenditure_amount += self.expenditure_amount

    @api.one
    @api.depends('child_ids', 'child_ids.commitment_amount', 'child_ids.state', 'state')
    def _compute_total_commitment_amount(self):
        self.total_commitment_amount = sum(self.child_ids. \
                                            filtered(lambda r: r.state not in ['draft']). \
                                            mapped('commitment_amount'))
        if self.state not in ['draft']:
            self.total_commitment_amount += self.commitment_amount

    @api.one
    @api.depends('progress_ids', 'progress_ids.accrual_amount')
    def _compute_accrual_amount(self):
        self.accrual_amount = sum(self.progress_ids.mapped('accrual_amount'))

    @api.one
    @api.depends('progress_ids', 'progress_ids.progress')
    def _compute_progress(self):
        self.progress = sum(self.progress_ids.mapped('progress'))

    # TRANSITIONS
    # ----------------------------------------------------------
    def set2draft(self):
        self.state = 'draft'

    def set2under_process(self):
        self.state = 'under process'

    def set2authorize(self):
        self.state = 'authorized'

    def set2close(self):
        self.state = 'closed'

    # CONSTRAINS
    # ----------------------------------------------------------
    _sql_constraints = [
        ('uniq_no', 'UNIQUE (no)', 'Task No Must Be unique')
    ]

    # OVERRIDE METHODS
    # ----------------------------------------------------------
    @api.model
    @api.returns('self', lambda rec: rec.id)
    def create(self, values):
        if not values.get('progress_ids', False):
            initial_progress = values.get('initial_progress', 0.00)
            name = values.get('name', '')
            start_date = values.get('start_date', False)

            progress = {
                'name': 'INITIAL: %s' % name,
                'remarks': 'initial progress',
                'progress': initial_progress,
                'change_date': start_date,
                'is_initial': True
            }

            values.update(progress_ids=[(0, 0, progress)])

        return super(Task, self).create(values)
Ejemplo n.º 5
0
class InvoiceSummary(models.Model):
    _name = 'budget.invoice.invoice.summary'
    _rec_name = 'summary_no'
    _description = 'Invoice Summary'
    _order = 'id desc'
    _inherit = ['mail.thread']

    # CHOICES
    # ----------------------------------------------------------
    STATES = choices_tuple([
        'draft', 'file generated', 'under certification', 'sent to finance',
        'closed', 'cancelled'
    ],
                           is_sorted=False)
    OBJECTIVES = choices_tuple(
        ['invoice certification', 'on hold certification'])

    # BASIC FIELDS
    # ----------------------------------------------------------
    # TODO CONSIDER MAKING SUMMARY NO AS NAME
    summary_no = fields.Char(
        string='Summary No',
        default=lambda self: self._get_default_summary_no())
    state = fields.Selection(STATES, default='draft')
    objective = fields.Selection(OBJECTIVES, default='invoice certification')

    signed_date = fields.Date(string='Signed Date')
    closed_date = fields.Date(string='Closed Date')
    sent_finance_date = fields.Date(string='Sent to Finance Date')
    sequence = fields.Integer(string='Sequence')

    # RELATIONSHIPS
    # ----------------------------------------------------------
    # TODO MUST NOT EDITABLE WHEN ON PROCESS, CHECK RULE ACCESS
    invoice_ids = fields.Many2many('budget.invoice.invoice',
                                   'budget_invoice_summary_invoice',
                                   'summary_id', 'invoice_id')
    section_id = fields.Many2one('res.partner',
                                 string='Section',
                                 domain=[('is_budget_section', '=', True)])

    # CONSTRAINTS
    # ----------------------------------------------------------
    _sql_constraints = [(
        '_uniq_summary_no',
        'UNIQUE(summary_no)',
        'summary must be unqiue!',
    )]

    @api.model
    def _get_default_summary_no(self):
        from datetime import datetime as dt
        from dateutil.relativedelta import relativedelta
        now = dt.utcnow()
        month = '{:%^b}'.format(now)
        year = '{:%y}'.format(now)
        start = dt(now.year, now.month, 1)
        end = dt(now.year, now.month, 1) + relativedelta(months=1)
        # end should be the first day next month to make time consider as 23:59:99
        domain = [('create_date', '>=', fields.Datetime.to_string(start)),
                  ('create_date', '<', fields.Datetime.to_string(end))]

        summaries = self.search(domain)
        if len(summaries) == 0:
            sr = 1
        else:
            sr = summaries[0].summary_no.split('-')[-1]
            sr = int(sr) + 1

        return 'IM-%s%s-%03d' % (month, year, sr)

    @api.one
    @api.returns('self', lambda value: value.id)
    def copy(self, default=None):
        default = dict(default or {})
        default.update(summary_no=self._get_default_summary_no())
        return super(InvoiceSummary, self).copy(default)

    @api.one
    def generate_file(self):
        """
        generate/create a invoice summary
        set STATE to GENERATED
        """
        from openpyxl.drawing.image import Image
        from ..xlsx_creator.creator import Creator
        import tempfile, shutil
        # OPEN FORM TEMPLATE

        creator = Creator(section=self.section_id.alias)
        wb, logo_img, signature_img = creator.get_context()

        # WORK SHEET MAIN
        # ----------------------------------------------------------
        row = 13
        column = 1
        sr = 1
        signature_coor = "B18"  # B18
        logo_coor = "J1"  # J1
        ws = wb.get_sheet_by_name('main')

        ws.cell("C4").value = self.summary_no
        ws.cell("C5").value = fields.Datetime.from_string(
            self.create_date).strftime('%d-%b-%Y')

        # Create Table
        ws.insert_rows(row, len(self.invoice_ids) - 1)
        #No, Reg, Contractor, Invoice No, Contract, Revenue, OpEx, CapEx, Total Amt, Budget/Yr.
        #1 , 2  , 3,        , 4         , 5  6    , 7      , 8   , 9    , 10       , 11
        for r in self.invoice_ids.sorted(key=lambda r: r.sequence):
            ws.cell(row=row, column=column).value = sr
            ws.cell(row=row,
                    column=column + 1).value = r.region_id.alias.upper() or ''
            ws.cell(row=row, column=column +
                    2).value = r.contract_id.contractor_id.name or ''
            ws.cell(row=row, column=column + 3).value = r.invoice_no or ''
            ws.cell(row=row,
                    column=column + 4).value = r.contract_id.contract_no or ''
            ws.cell(row=row, column=column + 5).value = r.revenue_amount or ''
            ws.cell(row=row, column=column + 6).value = r.opex_amount or ''
            ws.cell(row=row, column=column + 7).value = r.capex_amount or ''
            ws.cell(row=row,
                    column=column + 8).value = r.on_hold_percentage / 100 or ''
            ws.cell(row=row,
                    column=column + 9).value = r.certified_invoice_amount or ''
            ws.cell(row=row, column=column +
                    10).value = r.task_id.no or fields.Datetime.from_string(
                        r.rfs_date).strftime('%d-%b-%Y')

            row += 1
            sr += 1

        # INSERT HEADER LOGO AND SIGNATURE
        logo = Image(logo_img)
        signature = Image(signature_img)

        ws.add_image(logo, logo_coor)
        ws.add_image(
            signature,
            "%s" % signature_coor[0] + str(int(signature_coor[1:]) + sr))

        temp_dir = tempfile.mkdtemp()
        temp_file = os.path.join(temp_dir, '%s.xlsx' % self.summary_no)
        wb.save(temp_file)

        # Attach generated document to filestore
        ir_attach = self.env['ir.attachment']
        full_path = os.path.join(temp_file)

        with open(full_path, 'r') as fp:
            data = fp.read().encode('base64')
        filename = os.path.split(full_path)[1]
        values = dict(
            name=filename,
            datas_fname=filename,
            res_id=self.id,
            res_model='budget.invoice.invoice.summary',
            type='binary',
            datas=data,
        )
        ir_attach.create(values)

        # Clear
        shutil.rmtree(temp_dir)

    # ONCHANGE
    # ----------------------------------------------------------
    @api.onchange('objective')
    def _check_objective(self):
        if self.objective == 'invoice certification':
            return {'domain': {'invoice_ids': [('state', '=', 'verified')]}}
        elif self.objective == 'on hold certification':
            return {'domain': {'invoice_ids': [('state', '=', 'amount hold')]}}

    # BUTTONS/TRANSITIONS
    # ----------------------------------------------------------
    # TODO MUST DO A TRANSITION FOR RETURNING TO DRAFT

    @api.one
    def set2draft(self):
        self.state = 'draft'

    @api.one
    def set2file_generated(self):
        if not self.section_id:
            raise ValidationError('Section is required')

        elif len(self.invoice_ids) == 0:
            raise ValidationError('Empty Invoice List')

        self.generate_file()

        # Set related invoices state to "summary generated"
        for invoice in self.invoice_ids:
            invoice.signal_workflow('summary_generate')

        self.state = 'file generated'

    @api.one
    def set2under_certification(self):
        for invoice in self.invoice_ids:
            invoice.signal_workflow('certify')
        self.state = 'under certification'

    @api.one
    def set2sent_to_finance(self):
        if self.signed_date is False:
            raise ValidationError('Signed Date is Required')
        elif self.sent_finance_date is False:
            raise ValidationError('Sent to Finance Date is Required')

        for invoice in self.invoice_ids:
            invoice.sent_finance_date = self.sent_finance_date
            invoice.signed_date = self.signed_date
            invoice.signal_workflow('send_to_finance')
        self.state = 'sent to finance'

    @api.one
    def set2closed(self):
        if self.closed_date is False:
            raise ValidationError('Close Date is Required')
        for invoice in self.invoice_ids:
            invoice.closed_date = self.closed_date
            if invoice.on_hold_amount > 0 and invoice.state != 'amount hold':
                invoice.signal_workflow('amount_hold')
            else:
                invoice.signal_workflow('close')
        self.state = 'closed'

    @api.one
    def set2cancelled(self):
        for invoice in self.invoice_ids:
            invoice.signal_workflow('cancel')
        self.state = 'cancelled'