mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
Merge pull request #52 from guewen/account_invoice_reference
Migration of account_invoice_reference
This commit is contained in:
@@ -1,101 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm
|
||||
|
||||
|
||||
class AccountMove(orm.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
# invoice from which the move is generated
|
||||
invoice = context.get('invoice')
|
||||
if invoice:
|
||||
assert isinstance(invoice, orm.browse_record)
|
||||
invoice_obj = self.pool['account.invoice']
|
||||
ref = invoice_obj._ref_from_invoice(
|
||||
cr, uid, invoice, context=context)
|
||||
vals = vals.copy()
|
||||
vals['ref'] = ref
|
||||
move_id = super(AccountMove, self).create(cr, uid, vals,
|
||||
context=context)
|
||||
return move_id
|
||||
|
||||
|
||||
class AccountInvoice(orm.Model):
|
||||
_inherit = 'account.invoice'
|
||||
|
||||
def _ref_from_invoice(self, cr, uid, invoice, context=None):
|
||||
if invoice.type in ('out_invoice', 'out_refund'):
|
||||
return invoice.origin
|
||||
elif invoice.type in ('in_invoice', 'in_refund'):
|
||||
return invoice.supplier_invoice_number
|
||||
|
||||
def action_number(self, cr, uid, ids, context=None):
|
||||
# force the number of the invoice to be updated for the
|
||||
# subsequent browse
|
||||
self.write(cr, uid, ids, {})
|
||||
|
||||
for invoice in self.browse(cr, uid, ids, context=context):
|
||||
ref = self._ref_from_invoice(cr, uid, invoice, context=context)
|
||||
if not ref:
|
||||
ref = invoice.number
|
||||
move_id = invoice.move_id.id if invoice.move_id else False
|
||||
|
||||
self.write(cr, uid, ids, {'internal_number': invoice.number},
|
||||
context=context)
|
||||
cr.execute('UPDATE account_move SET ref=%s '
|
||||
'WHERE id=%s AND (ref is null OR ref = \'\')',
|
||||
(ref, move_id))
|
||||
cr.execute('UPDATE account_move_line SET ref=%s '
|
||||
'WHERE move_id=%s AND (ref is null OR ref = \'\')',
|
||||
(ref, move_id))
|
||||
cr.execute(
|
||||
'UPDATE account_analytic_line SET ref=%s '
|
||||
'FROM account_move_line '
|
||||
'WHERE account_move_line.move_id = %s '
|
||||
'AND account_analytic_line.move_id = account_move_line.id',
|
||||
(ref, move_id))
|
||||
return True
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if (vals.get('supplier_invoice_reference') and not
|
||||
vals.get('reference')):
|
||||
vals['reference'] = vals['supplier_invoice_reference']
|
||||
return super(AccountInvoice, self).create(cr, uid, vals,
|
||||
context=context)
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if vals.get('supplier_invoice_reference'):
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for invoice in self.browse(cr, uid, ids, context=context):
|
||||
if not invoice.reference:
|
||||
locvals = vals.copy()
|
||||
locvals['reference'] = vals['supplier_invoice_reference']
|
||||
super(AccountInvoice, self).write(cr, uid, [invoice.id],
|
||||
locvals, context=context)
|
||||
return True
|
||||
else:
|
||||
return super(AccountInvoice, self).write(cr, uid, ids, vals,
|
||||
context=context)
|
||||
@@ -20,3 +20,4 @@
|
||||
##############################################################################
|
||||
|
||||
from . import account_move
|
||||
from . import account_invoice
|
||||
@@ -39,10 +39,10 @@ origin, free reference) and above all, to understand which field will be
|
||||
copied in the reference field of the move and move lines.
|
||||
|
||||
The approach here is to state simple rules with one concern: consistency.
|
||||
The reference of the move lines must be the number of the document at their very
|
||||
origin (number of a sales order, of an external document like a supplier
|
||||
invoice, ...). The goal is for the accountant to be able to trace to the
|
||||
source document from a ledger).
|
||||
The reference of the move lines must be the number of the document at
|
||||
their very origin (number of a sales order, of an external document
|
||||
like a supplier invoice, ...). The goal is for the accountant to be
|
||||
able to trace to the source document from a ledger).
|
||||
The description of a line should always be... well, a description. Not a number
|
||||
or a cryptic reference.
|
||||
|
||||
@@ -141,8 +141,9 @@ Information propagated to the move lines:
|
||||
'test/out_refund_without_origin.yml',
|
||||
'test/in_refund_with_supplier_number.yml',
|
||||
'test/in_refund_without_supplier_number.yml',
|
||||
'test/supplier_invoice_number.yml',
|
||||
|
||||
],
|
||||
'installable': False,
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
}
|
||||
90
account_invoice_reference/account_invoice.py
Normal file
90
account_invoice_reference/account_invoice.py
Normal file
@@ -0,0 +1,90 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp import models, api
|
||||
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_inherit = 'account.invoice'
|
||||
|
||||
@api.v8
|
||||
def _ref_from_invoice(self):
|
||||
self.ensure_one()
|
||||
if self.type in ('out_invoice', 'out_refund'):
|
||||
return self.origin
|
||||
elif self.type in ('in_invoice', 'in_refund'):
|
||||
return self.supplier_invoice_number
|
||||
|
||||
@api.v7
|
||||
def _ref_from_invoice(self, cr, uid, invoice, context=None):
|
||||
return invoice._ref_from_invoice()
|
||||
|
||||
@api.multi
|
||||
def action_number(self):
|
||||
# force the number of the invoice to be updated for the
|
||||
# subsequent browse
|
||||
self.write({})
|
||||
|
||||
for invoice in self:
|
||||
ref = invoice._ref_from_invoice()
|
||||
if not ref:
|
||||
ref = invoice.number
|
||||
move_id = invoice.move_id.id if invoice.move_id else False
|
||||
|
||||
invoice.write({'internal_number': invoice.number})
|
||||
|
||||
cr = self._cr
|
||||
cr.execute("UPDATE account_move SET ref=%s "
|
||||
"WHERE id=%s AND (ref is null OR ref = '')",
|
||||
(ref, move_id))
|
||||
cr.execute("UPDATE account_move_line SET ref=%s "
|
||||
"WHERE move_id=%s AND (ref is null OR ref = '')",
|
||||
(ref, move_id))
|
||||
cr.execute(
|
||||
"UPDATE account_analytic_line SET ref=%s "
|
||||
"FROM account_move_line "
|
||||
"WHERE account_move_line.move_id = %s "
|
||||
"AND account_analytic_line.move_id = account_move_line.id",
|
||||
(ref, move_id))
|
||||
self.invalidate_cache()
|
||||
return True
|
||||
|
||||
@api.model
|
||||
@api.returns('self', lambda value: value.id)
|
||||
def create(self, vals):
|
||||
if (vals.get('supplier_invoice_number') and not
|
||||
vals.get('reference')):
|
||||
vals = vals.copy()
|
||||
vals['reference'] = vals['supplier_invoice_number']
|
||||
return super(AccountInvoice, self).create(vals)
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
if vals.get('supplier_invoice_number'):
|
||||
for invoice in self:
|
||||
loc_vals = None
|
||||
if not invoice.reference:
|
||||
loc_vals = vals.copy()
|
||||
loc_vals['reference'] = vals['supplier_invoice_number']
|
||||
super(AccountInvoice, invoice).write(loc_vals or vals)
|
||||
return True
|
||||
else:
|
||||
return super(AccountInvoice, self).write(vals)
|
||||
42
account_invoice_reference/account_move.py
Normal file
42
account_invoice_reference/account_move.py
Normal file
@@ -0,0 +1,42 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Author: Guewen Baconnier
|
||||
# Copyright 2014 Camptocamp SA
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.osv import orm
|
||||
|
||||
|
||||
class AccountMove(orm.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
# invoice from which the move is generated
|
||||
invoice = context.get('invoice')
|
||||
if invoice:
|
||||
assert isinstance(invoice, orm.browse_record)
|
||||
invoice_obj = self.pool['account.invoice']
|
||||
ref = invoice_obj._ref_from_invoice(
|
||||
cr, uid, invoice, context=context)
|
||||
vals = vals.copy()
|
||||
vals['ref'] = ref
|
||||
move_id = super(AccountMove, self).create(cr, uid, vals,
|
||||
context=context)
|
||||
return move_id
|
||||
47
account_invoice_reference/test/supplier_invoice_number.yml
Normal file
47
account_invoice_reference/test/supplier_invoice_number.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
-
|
||||
In order to check if the reference is populated from the supplier_invoice_number
|
||||
I create an invoice.
|
||||
-
|
||||
!record {model: account.invoice, id: invoice_supplier_invoice_number, view: account.invoice_supplier_form}:
|
||||
account_id: account.a_pay
|
||||
check_total: 3000.0
|
||||
company_id: base.main_company
|
||||
currency_id: base.EUR
|
||||
invoice_line:
|
||||
- account_id: account.a_expense
|
||||
name: '[PCSC234] PC Assemble SC234'
|
||||
price_unit: 300.0
|
||||
product_id: product.product_product_3
|
||||
quantity: 10.0
|
||||
uos_id: product.product_uom_unit
|
||||
journal_id: account.expenses_journal
|
||||
partner_id: base.res_partner_12
|
||||
reference_type: none
|
||||
supplier_invoice_number: ZZZ246
|
||||
type: in_invoice
|
||||
-
|
||||
Set again the type of the invoice (not set on the first one...)
|
||||
-
|
||||
!record {model: account.invoice, id: invoice_supplier_invoice_number, view: account.invoice_supplier_form}:
|
||||
type: in_invoice
|
||||
-
|
||||
Ensure that the reference is the same than the supplier_invoice_number
|
||||
-
|
||||
!assert {model: account.invoice, id: invoice_supplier_invoice_number}:
|
||||
- reference == 'ZZZ246'
|
||||
-
|
||||
In order to check if the supplier_invoice_number is copied to the supplier_invoice_number
|
||||
when the reference is empty, I empty the reference
|
||||
-
|
||||
!record {model: account.invoice, id: invoice_supplier_invoice_number, view: account.invoice_supplier_form}:
|
||||
reference:
|
||||
-
|
||||
And I write a new supplier_invoice_number
|
||||
-
|
||||
!record {model: account.invoice, id: invoice_supplier_invoice_number, view: account.invoice_supplier_form}:
|
||||
supplier_invoice_number: ABC789
|
||||
-
|
||||
Ensure that the reference is the same than the supplier_invoice_number
|
||||
-
|
||||
!assert {model: account.invoice, id: invoice_supplier_invoice_number}:
|
||||
- reference == 'ABC789'
|
||||
Reference in New Issue
Block a user