From 044d4da36b070ac5aca017c77ba24890e9cfdacf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Sat, 23 Mar 2013 15:40:22 +0100 Subject: [PATCH] Use origin Reference on Invoice Line and Stock Move issue2642 review717002 --- CHANGELOG | 2 ++ __init__.py | 3 +- invoice.py | 32 ++++++++++++----- sale.py | 99 +++++++++++++++++++++++++++++------------------------ 4 files changed, 82 insertions(+), 54 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 27d27c7ad3..d664b92156 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,5 @@ +* Use origin Reference on Invoice Line and Stock Move + Version 2.6.0 - 2012-10-22 * Bug fixes (see mercurial logs for details) diff --git a/__init__.py b/__init__.py index 8e71455bf4..fdf41cbbd3 100644 --- a/__init__.py +++ b/__init__.py @@ -9,20 +9,19 @@ from .invoice import * def register(): Pool.register( + Move, Sale, SaleInvoice, SaleIgnoredInvoice, SaleRecreatedInvoice, SaleLine, SaleLineTax, - SaleLineInvoiceLine, SaleLineIgnoredMove, SaleLineRecreatedMove, Template, Product, ShipmentOut, ShipmentOutReturn, - Move, HandleShipmentExceptionAsk, HandleInvoiceExceptionAsk, Configuration, diff --git a/invoice.py b/invoice.py index 1b2877ffda..442c4d11fc 100644 --- a/invoice.py +++ b/invoice.py @@ -3,6 +3,7 @@ from trytond.model import Workflow, fields from trytond.pool import Pool, PoolMeta from trytond.transaction import Transaction +from trytond.backend import TableHandler __all__ = ['Invoice', 'InvoiceLine'] __metaclass__ = PoolMeta @@ -98,13 +99,28 @@ class Invoice: class InvoiceLine: __name__ = 'account.invoice.line' - sale_lines = fields.Many2Many('sale.line-account.invoice.line', - 'invoice_line', 'sale_line', 'Sale Lines', readonly=True) @classmethod - def copy(cls, lines, default=None): - if default is None: - default = {} - default = default.copy() - default.setdefault('sale_lines', None) - return super(InvoiceLine, cls).copy(lines, default=default) + def __register__(cls, module_name): + cursor = Transaction().cursor + + super(InvoiceLine, cls).__register__(module_name) + + # Migration from 2.6: remove sale_lines + rel_table = 'sale_line_invoice_lines_rel' + if TableHandler.table_exist(cursor, rel_table): + cursor.execute('SELECT sale_line, invoice_line ' + 'FROM "' + rel_table + '"') + for sale_line, invoice_line in cursor.fetchall(): + cursor.execute('UPDATE "' + cls._table + '" ' + 'SET origin = %s ' + 'WHERE id = %s', + ('sale.line,%s' % sale_line, invoice_line)) + TableHandler.drop_table(cursor, + 'sale.line-account.invoice.line', rel_table) + + @classmethod + def _get_origin(cls): + models = super(InvoiceLine, cls)._get_origin() + models.append('sale.line') + return models diff --git a/sale.py b/sale.py index b634fdef44..3d58e5e237 100644 --- a/sale.py +++ b/sale.py @@ -14,7 +14,7 @@ from trytond.transaction import Transaction from trytond.pool import Pool, PoolMeta __all__ = ['Sale', 'SaleInvoice', 'SaleIgnoredInvoice', 'SaleRecreatedInvoice', - 'SaleLine', 'SaleLineTax', 'SaleLineInvoiceLine', 'SaleLineIgnoredMove', + 'SaleLine', 'SaleLineTax', 'SaleLineIgnoredMove', 'SaleLineRecreatedMove', 'SaleReport', 'Template', 'Product', 'ShipmentOut', 'ShipmentOutReturn', 'Move', 'OpenCustomer', 'HandleShipmentExceptionAsk', 'HandleShipmentException', @@ -227,7 +227,7 @@ class Sale(Workflow, ModelSQL, ModelView): def __register__(cls, module_name): pool = Pool() SaleLine = pool.get('sale.line') - SaleLine_InvoiceLine = pool.get('sale.line-account.invoice.line') + sale_line_invoice_line_table = 'sale_line_invoice_lines_rel' Move = pool.get('stock.move') cursor = Transaction().cursor # Migration from 1.2: packing renamed into shipment @@ -260,7 +260,7 @@ class Sale(Workflow, ModelSQL, ModelView): # state confirmed splitted into confirmed and processing if (TableHandler.table_exist(cursor, SaleLine._table) and TableHandler.table_exist(cursor, - SaleLine_InvoiceLine._table) + sale_line_invoice_line_table) and TableHandler.table_exist(cursor, Move._table)): # Wrap subquery inside an other inner subquery because MySQL syntax # doesn't allow update a table and select from the same table in a @@ -274,12 +274,13 @@ class Sale(Workflow, ModelSQL, ModelView): 'FROM "%s" AS s ' 'INNER JOIN "%s" AS l ON l.sale = s.id ' 'LEFT JOIN "%s" AS li ON li.sale_line = l.id ' - 'LEFT JOIN "%s" AS m ON m.sale_line = l.id ' + 'LEFT JOIN "%s" AS m ON m.origin = \'%s,\' || l.id ' "WHERE s.state = 'confirmed' " 'AND (li.id IS NOT NULL ' 'OR m.id IS NOT NULL)) AS foo)' % (cls._table, cls._table, SaleLine._table, - SaleLine_InvoiceLine._table, Move._table)) + sale_line_invoice_line_table, Move._table, + SaleLine.__name__)) # Add index on create_date table = TableHandler(cursor, cls, module_name) @@ -493,21 +494,20 @@ class Sale(Workflow, ModelSQL, ModelView): 'invoice_state': state, }) - def get_shipments_returns(attribute): + def get_shipments_returns(model_name): "Computes the returns or shipments" def method(self, name): - shipments = [] + Model = Pool().get(model_name) + shipments = set() for line in self.lines: for move in line.moves: - ship_or_return = getattr(move, attribute) - if bool(ship_or_return): - if ship_or_return.id not in shipments: - shipments.append(ship_or_return.id) - return shipments + if isinstance(move.shipment, Model): + shipments.add(move.shipment.id) + return list(shipments) return method - get_shipments = get_shipments_returns('shipment_out') - get_shipment_returns = get_shipments_returns('shipment_out_return') + get_shipments = get_shipments_returns('stock.shipment.out') + get_shipment_returns = get_shipments_returns('stock.shipment.out.return') def get_moves(self, name): return [m.id for l in self.lines for m in l.moves] @@ -954,10 +954,9 @@ class SaleLine(ModelSQL, ModelView): states={ 'invisible': Eval('type') != 'line', }, depends=['type']) - invoice_lines = fields.Many2Many('sale.line-account.invoice.line', - 'sale_line', 'invoice_line', 'Invoice Lines', readonly=True) - moves = fields.One2Many('stock.move', 'sale_line', 'Moves', - readonly=True) + invoice_lines = fields.One2Many('account.invoice.line', 'origin', + 'Invoice Lines', readonly=True) + moves = fields.One2Many('stock.move', 'origin', 'Moves', readonly=True) moves_ignored = fields.Many2Many('sale.line-ignored-stock.move', 'sale_line', 'move', 'Ignored Moves', readonly=True) moves_recreated = fields.Many2Many('sale.line-recreated-stock.move', @@ -1263,7 +1262,7 @@ class SaleLine(ModelSQL, ModelView): if not invoice_line.account: self.raise_user_error('missing_account_revenue_property', (self.sale.rec_name,)) - invoice_line.sale_lines = [self] + invoice_line.origin = self return [invoice_line] @classmethod @@ -1327,7 +1326,7 @@ class SaleLine(ModelSQL, ModelView): move.unit_price = self.unit_price move.currency = self.sale.currency move.planned_date = self.delivery_date - move.sale_line = self + move.origin = self return move @@ -1341,16 +1340,6 @@ class SaleLineTax(ModelSQL): select=True, required=True) -class SaleLineInvoiceLine(ModelSQL): - 'Sale Line - Invoice Line' - __name__ = 'sale.line-account.invoice.line' - _table = 'sale_line_invoice_lines_rel' - sale_line = fields.Many2One('sale.line', 'Sale Line', ondelete='CASCADE', - select=True, required=True) - invoice_line = fields.Many2One('account.invoice.line', 'Invoice Line', - ondelete='RESTRICT', select=True, required=True) - - class SaleLineIgnoredMove(ModelSQL): 'Sale Line - Ignored Move' __name__ = 'sale.line-ignored-stock.move' @@ -1523,9 +1512,11 @@ class ShipmentOut: @ModelView.button @Workflow.transition('draft') def draft(cls, shipments): + SaleLine = Pool().get('sale.line') for shipment in shipments: for move in shipment.outgoing_moves: - if move.state == 'cancel' and move.sale_line: + if (move.state == 'cancel' + and isinstance(move.origin, SaleLine)): cls.raise_user_error('reset_move') return super(ShipmentOut, cls).draft(shipments) @@ -1572,9 +1563,11 @@ class ShipmentOutReturn: @ModelView.button @Workflow.transition('draft') def draft(cls, shipments): + SaleLine = Pool().get('sale.line') for shipment in shipments: for move in shipment.incoming_moves: - if move.state == 'cancel' and move.sale_line: + if (move.state == 'cancel' + and isinstance(move.origin, SaleLine)): cls.raise_user_error('reset_move') return super(ShipmentOutReturn, cls).draft(shipments) @@ -1582,33 +1575,51 @@ class ShipmentOutReturn: class Move: __name__ = 'stock.move' - sale_line = fields.Many2One('sale.line', 'Sale Line', select=True, - states={ - 'readonly': Eval('state') != 'draft', - }, - depends=['state']) sale = fields.Function(fields.Many2One('sale.sale', 'Sale', select=True), - 'get_sale', searcher='search_sale') + 'get_sale', searcher='search_sale') sale_exception_state = fields.Function(fields.Selection([ ('', ''), ('ignored', 'Ignored'), ('recreated', 'Recreated'), ], 'Exception State'), 'get_sale_exception_state') + @classmethod + def __register__(cls, module_name): + cursor = Transaction().cursor + + super(Move, cls).__register__(module_name) + + table = TableHandler(cursor, cls, module_name) + + # Migration from 2.6: remove sale_line + if table.column_exist('sale_line'): + cursor.execute('UPDATE "' + cls._table + '" ' + 'SET origin = \'sale.line,\' || sale_line ' + 'WHERE sale_line IS NOT NULL') + table.drop_column('sale_line') + + @classmethod + def _get_origin(cls): + models = super(Move, cls)._get_origin() + models.append('sale.line') + return models + def get_sale(self, name): - if self.sale_line: - return self.sale_line.sale.id + SaleLine = Pool().get('sale.line') + if isinstance(self.origin, SaleLine): + return self.origin.sale.id @classmethod def search_sale(cls, name, clause): - return [('sale_line.' + name,) + clause[1:]] + return [('origin.' + name,) + tuple(clause[1:]) + ('sale.line',)] def get_sale_exception_state(self, name): - if not self.sale_line: + SaleLine = Pool().get('sale.line') + if not isinstance(self.origin, SaleLine): return '' - if self in self.sale_line.moves_recreated: + if self in self.origin.moves_recreated: return 'recreated' - if self in self.sale_line.moves_ignored: + if self in self.origin.moves_ignored: return 'ignored' return ''