Use origin Reference on Invoice Line and Stock Move

issue2642
review717002
This commit is contained in:
Cédric Krier
2013-03-23 15:40:22 +01:00
parent 3b201c51d1
commit 044d4da36b
4 changed files with 82 additions and 54 deletions
+2
View File
@@ -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)
+1 -2
View File
@@ -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,
+24 -8
View File
@@ -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
+55 -44
View File
@@ -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 ''