trytond-stock_move_relation/move.py
Juanjo Garcia 6c4240ff11 Add order function in "document_origin_planned_date" field.
FIX "document_origin_planned_date" search field.

Task #162376
2023-12-11 13:47:16 +01:00

240 lines
10 KiB
Python

# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from sql.functions import Substring, Position
from sql.conditionals import Coalesce
from sql import Cast, Literal
from trytond.model import fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
__all__ = ['Move']
class Move(metaclass=PoolMeta):
__name__ = 'stock.move'
document_origin = fields.Function(fields.Reference('Document Origin',
selection='get_document_origin'), 'get_relation')
document = fields.Function(fields.Reference('Document',
selection='get_document'), 'get_relation')
document_origin_date = fields.Function(fields.Date(
'Document Origin Date'), 'get_relation',)
document_origin_planned_date = fields.Function(fields.Date(
'Document Origin Planned Date'), 'get_relation',
searcher='search_document_origin_planned_date')
from_warehouse = fields.Function(fields.Many2One('stock.location',
'From Warehouse', domain=[('type', '=', 'warehouse')]),
'get_relation', searcher='search_from_warehouse')
to_warehouse = fields.Function(fields.Many2One('stock.location',
'To Warehouse', domain=[('type', '=', 'warehouse')]),
'get_relation', searcher='search_to_warehouse')
document_origin_party = fields.Function(
fields.Many2One('party.party', 'Party', context={
'company': Eval('company'),
},
depends=['company']), 'get_relation',
searcher='search_document_origin_party')
@classmethod
def _get_document_origin(cls):
'Return list of Model names for origin Reference'
return [
'purchase.purchase',
'sale.sale',
]
@classmethod
def get_document_origin(cls):
Model = Pool().get('ir.model')
models = cls._get_document_origin()
models = Model.search([
('model', 'in', models),
])
return [(None, '')] + [(m.model, m.name) for m in models]
@classmethod
def _get_document(cls):
'Return list of Model names for origin Reference'
return [
'stock.shipment.in',
'stock.shipment.out',
'stock.shipment.out.return',
'stock.shipment.in.return',
'stock.shipment.internal',
'production',
]
@classmethod
def get_document(cls):
Model = Pool().get('ir.model')
models = cls._get_document()
models = Model.search([
('model', 'in', models),
])
return [(None, '')] + [(m.model, m.name) for m in models]
@classmethod
def get_relation(cls, moves, names):
res = {n: {m.id: None for m in moves} for n in names}
for move in moves:
document_origin = None
if move.origin and not isinstance(move.origin, str):
if (move.origin.__name__ == 'sale.line'
and move.origin.sale):
document_origin = move.origin.sale
if (move.origin.__name__ == 'purchase.line'
and move.origin.purchase):
document_origin = move.origin.purchase
if (getattr(move, 'production_input', None)
and move.production_input.origin):
document_origin = move.production_input.origin.sale
if (getattr(move, 'production_output', None)
and move.production_output.origin):
document_origin = move.production_output.origin.sale
if 'document_origin' in names and document_origin:
res['document_origin'][move.id] = str(document_origin)
if 'document' in names:
if move.shipment:
res['document'][move.id] = str(move.shipment)
if getattr(move, 'production_input', None):
res['document'][move.id] = str(move.production_input)
if getattr(move, 'production_output', None):
res['document'][move.id] = str(move.production_output)
if ('document_origin_date' in names and document_origin
and not isinstance(document_origin, str)):
res['document_origin_date'][move.id] = (
document_origin.sale_date
if document_origin.__name__ == 'sale.sale'
else document_origin.purchase_date)
if ('document_origin_planned_date' in names and move.origin
and not isinstance(move.origin, str)):
if move.origin.__name__ == 'sale.line':
delivery_date = getattr(move.origin,
'manual_delivery_date', None)
if not delivery_date:
delivery_date = getattr(move.origin,
'shipping_date', None)
res['document_origin_planned_date'][move.id] = delivery_date
elif move.origin.__name__ == 'purchase.line':
planned_date = None
if move.origin.delivery_date_store:
planned_date = move.origin.delivery_date_store
elif (move.origin.purchase
and move.origin.purchase.delivery_date):
planned_date = move.origin.purchase.delivery_date
else:
planned_date = move.planned_date
res['document_origin_planned_date'][move.id] = planned_date
if 'from_warehouse' in names and move.from_location.warehouse:
res['from_warehouse'][move.id] = move.from_location.warehouse.id
if 'to_warehouse' in names and move.to_location.warehouse:
res['to_warehouse'][move.id] = move.to_location.warehouse.id
if ('document_origin_party' in names
and document_origin
and document_origin.party):
res['document_origin_party'][move.id] = document_origin.party.id
return res
@classmethod
def search_to_warehouse(cls, name, clause):
return [('to_location.warehouse',) + tuple(clause[1:])]
@classmethod
def search_from_warehouse(cls, name, clause):
return [('from_location.warehouse',) + tuple(clause[1:])]
@classmethod
def search_document_origin_party(cls, name, clause):
return ['OR',
('shipment.customer' + clause[0].lstrip(name),)
+ tuple(clause[1:3]) + ('stock.shipment.out.return',)
+ tuple(clause[3:]),
('shipment.customer' + clause[0].lstrip(name),)
+ tuple(clause[1:3]) + ('stock.shipment.out',)
+ tuple(clause[3:]),
('sale.party',) + tuple(clause[1:]),
('shipment.supplier' + clause[0].lstrip(name),)
+ tuple(clause[1:3]) + ('stock.shipment.in.return',)
+ tuple(clause[3:]),
('shipment.supplier' + clause[0].lstrip(name),)
+ tuple(clause[1:3]) + ('stock.shipment.in',)
+ tuple(clause[3:]),
('purchase.party',) + tuple(clause[1:]),
]
@classmethod
def search_document_origin_planned_date(cls, name, clause):
Line = Pool().get('sale.line')
domain = ['OR',
[('origin', '!=', None),
('planned_date',) + tuple(clause[1:])],
('purchase.delivery_date',) + tuple(clause[1:]),
('origin.delivery_date_store',) + tuple(clause[1:3])
+ ('purchase.line',) + tuple(clause[3:])
]
if hasattr(Line, 'manual_delivery_date'):
domain.append(('origin.manual_delivery_date',) + tuple(clause[1:3])
+ ('sale.line',) + tuple(clause[3:]),)
return domain
@classmethod
def _document_origin_planned_date_query(cls):
pool = Pool()
Move = pool.get('stock.move')
PurchaseLine = pool.get('purchase.line')
Purchase = pool.get('purchase.purchase')
SaleLine = pool.get('sale.line')
Sale = pool.get('sale.sale')
move = Move.__table__()
purchase_line = PurchaseLine.__table__()
purchase = Purchase.__table__()
sale_line = SaleLine.__table__()
sale = Sale.__table__()
return move.join(purchase_line, 'LEFT', condition=(
(Cast(Substring(move.origin,
Position(',', move.origin) + Literal(1)),
cls.id.sql_type().base) == purchase_line.id)
& move.origin.ilike('purchase.line,%'))).join(
purchase, 'LEFT', condition=(
purchase_line.purchase == purchase.id)
).join(sale_line, 'LEFT', condition=(
(Cast(Substring(
move.origin, Position(',', move.origin) + Literal(1)),
cls.id.sql_type().base) == sale_line.id)
& move.origin.ilike('sale.line,%'))).join(
sale, 'LEFT', condition=(sale_line.sale == sale.id)
).select(move.id.as_('move'),
purchase_line.delivery_date_store.as_(
'delivery_date_store'),
purchase.delivery_date.as_('delivery_date'),
sale.shipping_date.as_('shipping_date'),
move.planned_date.as_('planned_date'),
where=(move.origin != None))
@classmethod
def order_document_origin_planned_date(cls, tables):
table, _ = tables[None]
key = 'document_origin_planned_date'
if key not in tables:
query = cls._document_origin_planned_date_query()
join = table.join(
query, type_='LEFT',
condition=(query.move == table.id)
)
tables[key] = {
None: (join.right, join.condition),
}
else:
query, _ = tables[key][None]
return [Coalesce(query.delivery_date_store, query.delivery_date,
query.shipping_date, query.planned_date)]