示例#1
0
 def action_cancel(self):
     '''  This action_cancel overidden to avoid the cascading cancellation
     @param self : Object Pointer
     @param cr : Database Cursor
     @param uid : Current Logged in User
     @param ids : Current Records
     @param context : standard Dictionary
     @return : True
     '''
     if not len(self.ids):
         return True
     pickings = {}
     for move in self:
         if move.state in ('confirmed', 'waiting', 'assigned', 'draft'):
             if move.picking_id:
                 pickings[move.picking_id.id] = True
     self.write({'state': 'cancel'})
     for pick_id in pickings:
         workflow.trg_validate(self._uid, 'stock.picking', pick_id,
                               'button_cancel', self._cr)
     ids2 = []
     for res in self.read(['move_dest_id']):
         if res['move_dest_id']:
             ids2.append(res['move_dest_id'][0])
     for stock_id in self.ids:
         workflow.trg_trigger(self._uid, 'stock.move', stock_id, self._cr)
     # self.action_cancel(cr,uid, ids2, context) # $$
     # [removed to avoid cascading cancellation]
     return True
示例#2
0
 def write(self, cr, uid, ids, vals, context=None):
     if isinstance(ids, (int, long)):
         ids = [ids]
     res = super(StockMove, self).write(cr, uid, ids, vals, context=context)
     from openerp import workflow
     for move in self.browse(cr, uid, ids, context=context):
         if move.raw_material_production_id and move.raw_material_production_id.state == 'confirmed':
             workflow.trg_trigger(uid, 'stock.move', move.id, cr)
     return res
示例#3
0
    def debit_reconcile(self, cr, uid, payment_line_id, context=None):
        """
        Reconcile a debit order's payment line with the the move line
        that it is based on. Called from payment_order.action_sent().
        As the amount is derived directly from the counterpart move line,
        we do not expect a write off. Take partial reconciliations into
        account though.

        :param payment_line_id: the single id of the canceled payment line
        """

        if isinstance(payment_line_id, (list, tuple)):
            payment_line_id = payment_line_id[0]
        reconcile_obj = self.pool.get("account.move.reconcile")
        move_line_obj = self.pool.get("account.move.line")
        payment_line = self.browse(cr, uid, payment_line_id, context=context)

        transit_move_line = payment_line.transit_move_line_id
        torec_move_line = payment_line.move_line_id

        if not transit_move_line or not torec_move_line:
            raise orm.except_orm(_("Can not reconcile"), _("No move line for line %s") % payment_line.name)
        if torec_move_line.reconcile_id:
            raise orm.except_orm(_("Error"), _("Move line %s has already been reconciled") % torec_move_line.name)
        if transit_move_line.reconcile_id or transit_move_line.reconcile_partial_id:
            raise orm.except_orm(_("Error"), _("Move line %s has already been reconciled") % transit_move_line.name)

        def is_zero(total):
            return self.pool.get("res.currency").is_zero(cr, uid, transit_move_line.company_id.currency_id, total)

        line_ids = [transit_move_line.id, torec_move_line.id]
        if torec_move_line.reconcile_partial_id:
            line_ids = [x.id for x in torec_move_line.reconcile_partial_id.line_partial_ids] + [transit_move_line.id]

        total = move_line_obj.get_balance(cr, uid, line_ids)
        vals = {
            "type": "auto",
            "line_id": is_zero(total) and [(6, 0, line_ids)] or [(6, 0, [])],
            "line_partial_ids": (is_zero(total) and [(6, 0, [])] or [(6, 0, line_ids)]),
        }

        if torec_move_line.reconcile_partial_id:
            reconcile_obj.write(cr, uid, [torec_move_line.reconcile_partial_id.id], vals, context=context)
        else:
            reconcile_obj.create(cr, uid, vals, context=context)
        for line_id in line_ids:
            workflow.trg_trigger(uid, "account.move.line", line_id, cr)

        # If a bank transaction of a storno was first confirmed
        # and now canceled (the invoice is now in state 'debit_denied'
        if torec_move_line.invoice:
            workflow.trg_validate(uid, "account.invoice", torec_move_line.invoice.id, "undo_debit_denied", cr)
 def action_done(self, cr, uid, ids):
     """ Changes procurement state to Done and writes Closed date.
     @return: True
     """
     move_obj = self.pool.get('stock.move')
     for procurement in self.browse(cr, uid, ids):
         if procurement.move_id:
             if procurement.close_move and (procurement.move_id.state <> 'done'):
                 move_obj.action_done(cr, uid, [procurement.move_id.id])
     res = self.write(cr, uid, ids, {'state': 'done', 'date_close': time.strftime('%Y-%m-%d')})
     for id in ids:
         workflow.trg_trigger(uid, 'procurement.order', id, cr)
     return res
 def action_done(self, cr, uid, ids):
     """ Changes procurement state to Done and writes Closed date.
     @return: True
     """
     move_obj = self.pool.get("stock.move")
     for procurement in self.browse(cr, uid, ids):
         if procurement.move_id:
             if procurement.close_move and (procurement.move_id.state <> "done"):
                 move_obj.action_done(cr, uid, [procurement.move_id.id])
     res = self.write(cr, uid, ids, {"state": "done", "date_close": time.strftime("%Y-%m-%d")})
     for id in ids:
         workflow.trg_trigger(uid, "procurement.order", id, cr)
     return res
 def unlink(self):
     """
     Workflow triggers upon unreconcile. This should go into the core.
     """
     line_ids = []
     for reconcile in self:
         for move_line in reconcile.line_id:
             line_ids.append(move_line.id)
     res = super(AccountMoveReconcile, self).unlink()
     for line_id in line_ids:
         workflow.trg_trigger(
             self._uid, 'account.move.line', line_id, self._cr)
     return res
示例#7
0
 def action_cancel(self, cr, uid, ids):
     """Cancel Procurements and either cancel or assign the related Stock Moves, depending on the procurement configuration.
     
     @return: True
     """
     to_assign = []
     to_cancel = []
     move_obj = self.pool.get('stock.move')
     for proc in self.browse(cr, uid, ids):
         if proc.close_move and proc.move_id:
             if proc.move_id.state not in ('done', 'cancel'):
                 to_cancel.append(proc.move_id.id)
         else:
             if proc.move_id and proc.move_id.state == 'waiting':
                 to_assign.append(proc.move_id.id)
     if len(to_cancel):
         move_obj.action_cancel(cr, uid, to_cancel)
     if len(to_assign):
         move_obj.write(cr, uid, to_assign, {'state': 'assigned'})
     self.write(cr, uid, ids, {'state': 'cancel'})
     for id in ids:
         workflow.trg_trigger(uid, 'procurement.order', id, cr)
     return True
 def action_cancel(self, cr, uid, ids):
     """Cancel Procurements and either cancel or assign the related Stock Moves, depending on the procurement configuration.
     
     @return: True
     """
     to_assign = []
     to_cancel = []
     move_obj = self.pool.get("stock.move")
     for proc in self.browse(cr, uid, ids):
         if proc.close_move and proc.move_id:
             if proc.move_id.state not in ("done", "cancel"):
                 to_cancel.append(proc.move_id.id)
         else:
             if proc.move_id and proc.move_id.state == "waiting":
                 to_assign.append(proc.move_id.id)
     if len(to_cancel):
         move_obj.action_cancel(cr, uid, to_cancel)
     if len(to_assign):
         move_obj.write(cr, uid, to_assign, {"state": "confirmed"})
         move_obj.action_assign(cr, uid, to_assign)
     self.write(cr, uid, ids, {"state": "cancel"})
     for id in ids:
         workflow.trg_trigger(uid, "procurement.order", id, cr)
     return True
示例#9
0
    def reconcile(self, cr, uid, ids, type='auto', writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False, context=None):
        account_obj = self.pool.get('account.account')
        move_obj = self.pool.get('account.move')
        move_rec_obj = self.pool.get('account.move.reconcile')
        partner_obj = self.pool.get('res.partner')
        currency_obj = self.pool.get('res.currency')
        lines = self.browse(cr, uid, ids, context=context)
        unrec_lines = filter(lambda x: not x['reconcile_id'], lines)
        credit = debit = 0.0
        currency = 0.0
        account_id = False
        partner_id = False
        invoice_id = False
        tax_amount = False
        base_amount = False
        if context is None:
            context = {}
        company_list = []
        for line in self.browse(cr, uid, ids, context=context):
            if company_list and not line.company_id.id in company_list:
                raise osv.except_osv(_('Warning!'), _('To reconcile the entries company should be the same for all entries.'))
            company_list.append(line.company_id.id)
        for line in unrec_lines:
            if line.state <> 'valid':
                raise osv.except_osv(_('Error!'),
                        _('Entry "%s" is not valid !') % line.name)
            credit += line['credit']
            debit += line['debit']
            currency += line['amount_currency'] or 0.0
            account_id = line['account_id']['id']
            partner_id = (line['partner_id'] and line['partner_id']['id']) or False
            invoice_id = line.invoice_id.id or False
            tax_amount = line['tax_amount'] or 0.0
            base_amount = line['base_amount'] or 0.0
        writeoff = debit - credit

        # Ifdate_p in context => take this date
        if context.has_key('date_p') and context['date_p']:
            date=context['date_p']
        else:
            date = time.strftime('%Y-%m-%d')

        cr.execute('SELECT account_id, reconcile_id '\
                   'FROM account_move_line '\
                   'WHERE id IN %s '\
                   'GROUP BY account_id,reconcile_id',
                   (tuple(ids), ))
        r = cr.fetchall()
        #TODO: move this check to a constraint in the account_move_reconcile object
        if len(r) != 1:
            raise osv.except_osv(_('Error'), _('Entries are not of the same account or already reconciled ! '))
        if not unrec_lines:
            raise osv.except_osv(_('Error!'), _('Entry is already reconciled.'))
        account = account_obj.browse(cr, uid, account_id, context=context)
        if not account.reconcile:
            raise osv.except_osv(_('Error'), _('The account is not defined to be reconciled !'))
        if r[0][1] != None:
            raise osv.except_osv(_('Error!'), _('Some entries are already reconciled.'))

        if (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
           (account.currency_id and (not currency_obj.is_zero(cr, uid, account.currency_id, currency))):
            if not writeoff_acc_id:
                raise osv.except_osv(_('Warning!'), _('You have to provide an account for the write off/exchange difference entry.'))
            if writeoff > 0:
                debit = writeoff
                credit = 0.0
                self_credit = writeoff
                self_debit = 0.0
            else:
                debit = 0.0
                credit = -writeoff
                self_credit = 0.0
                self_debit = -writeoff
            # If comment exist in context, take it
            if 'comment' in context and context['comment']:
                libelle = context['comment']
            else:
                libelle = _('Write-Off')

            cur_obj = self.pool.get('res.currency')
            cur_id = False
            amount_currency_writeoff = 0.0
            if context.get('company_currency_id',False) != context.get('currency_id',False):
                cur_id = context.get('currency_id',False)
                for line in unrec_lines:
                    if line.currency_id and line.currency_id.id == context.get('currency_id',False):
                        amount_currency_writeoff += line.amount_currency
                    else:
                        tmp_amount = cur_obj.compute(cr, uid, line.account_id.company_id.currency_id.id, context.get('currency_id',False), abs(line.debit-line.credit), context={'date': line.date})
                        amount_currency_writeoff += (line.debit > 0) and tmp_amount or -tmp_amount

            writeoff_lines = [
                (0, 0, {
                    'name': libelle,
                    'debit': self_debit,
                    'credit': self_credit,
                    'account_id': account_id,
                    'date': date,
                    'partner_id': partner_id,
                    'currency_id': cur_id or (account.currency_id.id or False),
                    'amount_currency': amount_currency_writeoff and -1 * amount_currency_writeoff or (account.currency_id.id and -1 * currency or 0.0),
                    'invoice_id': invoice_id,
                    'tax_amount': tax_amount,
                    'base_amount': base_amount,
                }),
                (0, 0, {
                    'name': libelle,
                    'debit': debit,
                    'credit': credit,
                    'account_id': writeoff_acc_id,
                    'analytic_account_id': context.get('analytic_id', False),
                    'date': date,
                    'partner_id': partner_id,
                    'currency_id': cur_id or (account.currency_id.id or False),
                    'amount_currency': amount_currency_writeoff and amount_currency_writeoff or (account.currency_id.id and currency or 0.0),
                    'invoice_id': invoice_id,
                    'tax_amount': tax_amount,
                    'base_amount': base_amount,
                })
            ]

            #2015-06-22
            writeoff_lines = []
            for line in unrec_lines:
                if line.state <> 'valid':
                    raise osv.except_osv(_('Error!'),
                        _('Entry "%s" is not valid !') % line.name)
                writeoff_lines.append(
                    (0,0,{
                        'name': line.name,
                        'debit': line.credit,
                        'credit': line.debit,
                        'account_id': line.account_id.id,
                        'date': date,
                        'partner_id': partner_id,
                        'currency_id': cur_id or (account.currency_id.id or False),
                        'amount_currency': line.amount_currency or 0.0,
                        'invoice_id': line.invoice_id.id,
                        'tax_amount': line.tax_amount or 0.0,
                        'base_amount' : line.base_amount or 0.0
                    })
                )
            writeoff_lines.append(
                (0, 0, {
                    'name': libelle,
                    'debit': debit,
                    'credit': credit,
                    'account_id': writeoff_acc_id,
                    'analytic_account_id': context.get('analytic_id', False),
                    'date': date,
                    'partner_id': partner_id,
                    'currency_id': cur_id or (account.currency_id.id or False),
                    'amount_currency': amount_currency_writeoff and amount_currency_writeoff or (account.currency_id.id and currency or 0.0),
                    'invoice_id': False,
                })
            )

            writeoff_move_id = move_obj.create(cr, uid, {
                'period_id': writeoff_period_id,
                'journal_id': writeoff_journal_id,
                'date':date,
                'state': 'draft',
                'line_id': writeoff_lines
            })

            writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)])
            if account_id == writeoff_acc_id:
                writeoff_line_ids = [writeoff_line_ids[1]]
            ids += writeoff_line_ids

        # marking the lines as reconciled does not change their validity, so there is no need
        # to revalidate their moves completely.
        reconcile_context = dict(context, novalidate=True)
        r_id = move_rec_obj.create(cr, uid, {
            'type': type,
            'line_id': map(lambda x: (4, x, False), ids),
            'line_partial_ids': map(lambda x: (3, x, False), ids)
        }, context=reconcile_context)
        # the id of the move.reconcile is written in the move.line (self) by the create method above
        # because of the way the line_id are defined: (4, x, False)
        for id in ids:
            workflow.trg_trigger(uid, 'account.move.line', id, cr)

        if lines and lines[0]:
            partner_id = lines[0].partner_id and lines[0].partner_id.id or False
            if partner_id and not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
                partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
        return r_id
示例#10
0
    def mtd_reconcile(self,
                      cr,
                      uid,
                      ids,
                      type='auto',
                      writeoff_acc_id=False,
                      writeoff_period_id=False,
                      writeoff_journal_id=False,
                      context=None):
        account_obj = self.pool.get('account.account')
        move_obj = self.pool.get('account.move')
        move_rec_obj = self.pool.get('account.move.reconcile')
        partner_obj = self.pool.get('res.partner')
        currency_obj = self.pool.get('res.currency')
        lines = self.browse(cr, uid, ids, context=context)
        unrec_lines = filter(lambda x: not x['reconcile_id'], lines)
        credit = debit = 0.0
        currency = 0.0
        account_id = False
        partner_id = False
        if context is None:
            context = {}
        company_list = []
        for line in lines:
            if company_list and not line.company_id.id in company_list:
                raise osv.except_osv(
                    _('Warning!'),
                    _('To reconcile the entries company should be the same for all entries.'
                      ))
            company_list.append(line.company_id.id)
        for line in unrec_lines:
            if line.state != 'valid':
                raise osv.except_osv(
                    _('Error!'),
                    _('Entry "%s" is not valid !') % line.name)
            credit += line['credit']
            debit += line['debit']
            currency += line['amount_currency'] or 0.0
            account_id = line['account_id']['id']
            partner_id = (line['partner_id']
                          and line['partner_id']['id']) or False
        writeoff = debit - credit

        # Ifdate_p in context => take this date
        if context.has_key('date_p') and context['date_p']:
            date = context['date_p']
        else:
            date = time.strftime('%Y-%m-%d')

        cr.execute('SELECT account_id, reconcile_id '\
                   'FROM account_move_line '\
                   'WHERE id IN %s '\
                   'GROUP BY account_id,reconcile_id',
                   (tuple(ids), ))
        r = cr.fetchall()
        #TODO: move this check to a constraint in the account_move_reconcile object
        if len(r) != 1:
            raise osv.except_osv(
                _('Error'),
                _('Entries are not of the same account or already reconciled ! '
                  ))
        if not unrec_lines:
            raise osv.except_osv(_('Error!'),
                                 _('Entry is already reconciled.'))
        account = account_obj.browse(cr, uid, account_id, context=context)
        if r[0][1] != None:
            raise osv.except_osv(_('Error!'),
                                 _('Some entries are already reconciled.'))

        if (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \
           (account.currency_id and (not currency_obj.is_zero(cr, uid, account.currency_id, currency))):
            # DO NOT FORWARD PORT
            if not writeoff_acc_id:
                if writeoff > 0:
                    writeoff_acc_id = account.company_id.expense_currency_exchange_account_id.id
                else:
                    writeoff_acc_id = account.company_id.income_currency_exchange_account_id.id
            if not writeoff_acc_id:
                raise osv.except_osv(
                    _('Warning!'),
                    _('You have to provide an account for the write off/exchange difference entry.'
                      ))
            if writeoff > 0:
                debit = writeoff
                credit = 0.0
                self_credit = writeoff
                self_debit = 0.0
            else:
                debit = 0.0
                credit = -writeoff
                self_credit = 0.0
                self_debit = -writeoff
            # If comment exist in context, take it
            if 'comment' in context and context['comment']:
                libelle = context['comment']
            else:
                libelle = _('Write-Off')

            cur_obj = self.pool.get('res.currency')
            cur_id = False
            amount_currency_writeoff = 0.0
            if context.get('company_currency_id', False) != context.get(
                    'currency_id', False):
                cur_id = context.get('currency_id', False)
                for line in unrec_lines:
                    if line.currency_id and line.currency_id.id == context.get(
                            'currency_id', False):
                        amount_currency_writeoff += line.amount_currency
                    else:
                        tmp_amount = cur_obj.compute(
                            cr,
                            uid,
                            line.account_id.company_id.currency_id.id,
                            context.get('currency_id', False),
                            abs(line.debit - line.credit),
                            context={'date': line.date})
                        amount_currency_writeoff += (
                            line.debit > 0) and tmp_amount or -tmp_amount

            writeoff_lines = [
                (0, 0, {
                    'name':
                    libelle,
                    'debit':
                    self_debit,
                    'credit':
                    self_credit,
                    'account_id':
                    account_id,
                    'date':
                    date,
                    'partner_id':
                    partner_id,
                    'currency_id':
                    cur_id or (account.currency_id.id or False),
                    'amount_currency':
                    amount_currency_writeoff and -1 * amount_currency_writeoff
                    or (account.currency_id.id and -1 * currency or 0.0)
                }),
                (0, 0, {
                    'name':
                    libelle,
                    'debit':
                    debit,
                    'credit':
                    credit,
                    'account_id':
                    writeoff_acc_id,
                    'analytic_account_id':
                    context.get('analytic_id', False),
                    'date':
                    date,
                    'partner_id':
                    partner_id,
                    'currency_id':
                    cur_id or (account.currency_id.id or False),
                    'amount_currency':
                    amount_currency_writeoff and amount_currency_writeoff
                    or (account.currency_id.id and currency or 0.0)
                })
            ]
            # DO NOT FORWARD PORT
            # In some exceptional situations (partial payment from a bank statement in foreign
            # currency), a write-off can be introduced at the very last moment due to currency
            # conversion. We record it on the bank statement account move.
            if context.get('bs_move_id'):
                writeoff_move_id = context['bs_move_id']
                for l in writeoff_lines:
                    self.create(cr, uid, dict(l[2], move_id=writeoff_move_id),
                                dict(context, novalidate=True))
                if not move_obj.validate(
                        cr, uid, writeoff_move_id, context=context):
                    raise osv.except_osv(
                        _('Error!'),
                        _('You cannot validate a non-balanced entry.'))
            else:
                writeoff_move_id = move_obj.create(
                    cr, uid, {
                        'period_id': writeoff_period_id,
                        'journal_id': writeoff_journal_id,
                        'date': date,
                        'state': 'draft',
                        'line_id': writeoff_lines
                    })

            writeoff_line_ids = self.search(
                cr, uid, [('move_id', '=', writeoff_move_id),
                          ('account_id', '=', account_id)])
            if account_id == writeoff_acc_id:
                writeoff_line_ids = [writeoff_line_ids[1]]
            ids += writeoff_line_ids

        # marking the lines as reconciled does not change their validity, so there is no need
        # to revalidate their moves completely.
        reconcile_context = dict(context, novalidate=True)
        r_id = move_rec_obj.create(cr,
                                   uid, {'type': type},
                                   context=reconcile_context)
        self.write(cr,
                   uid,
                   ids, {
                       'reconcile_id': r_id,
                       'reconcile_partial_id': False
                   },
                   context=reconcile_context)

        # the id of the move.reconcile is written in the move.line (self) by the create method above
        # because of the way the line_id are defined: (4, x, False)
        for id in ids:
            workflow.trg_trigger(uid, 'account.move.line', id, cr)

        if lines and lines[0]:
            partner_id = lines[0].partner_id and lines[0].partner_id.id or False
            if partner_id and not partner_obj.has_something_to_reconcile(
                    cr, uid, partner_id, context=context):
                partner_obj.mark_as_reconciled(cr,
                                               uid, [partner_id],
                                               context=context)
        return r_id