Use MultiSelection for lot_required

issue7851
review249911002
This commit is contained in:
Cédric Krier committed 2019-09-20 11:32:02 +02:00
1 parent 7d76c8cb2c
commit 57032ecb96
7 files changed
+64 -66

No files matched your search

+1
View File
@@ -1,3 +1,4 @@
* Use MultiSelection for lot_required
* Synchronize lot on internal shipment
Version 5.2.0 - 2019-05-06
-2
View File
@@ -10,7 +10,6 @@ def register():
Pool.register(
stock.Lot,
stock.LotByLocationContext,
stock.LotType,
stock.Move,
stock.ShipmentIn,
stock.ShipmentOut,
@@ -23,7 +22,6 @@ def register():
stock.InventoryCountSearch,
product.Template,
product.Product,
product.TemplateLotType,
module='stock_lot', type_='model')
Pool.register(
stock.InventoryCount,
+54 -20
View File
@@ -1,41 +1,75 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.model import ModelSQL, fields
from sql import Table
from trytond.config import config
from trytond.model import fields
from trytond.pyson import Eval
from trytond.pool import PoolMeta
__all__ = ['Template', 'Product', 'TemplateLotType']
from trytond.transaction import Transaction
class Template(metaclass=PoolMeta):
__name__ = 'product.template'
# TODO to replace with a Multiple Selection
lot_required = fields.Many2Many('product.template-stock.lot.type',
'template', 'type', 'Lot Required',
lot_required = fields.MultiSelection([
('supplier', "Supplier"),
('customer', "Customer"),
('lost_found', "Lost and Found"),
('storage', "Storage"),
('production', "Production"),
], "Lot Required",
help='The type of location for which lot is required',
states={
'invisible': ~Eval('type').in_(['goods', 'assets']),
},
depends=['type'])
@classmethod
def __register__(cls, module):
connection = Transaction().connection
cursor = connection.cursor()
super().__register__(module)
table_h = cls.__table_handler__(module)
template_lot_type_table_name = config.get(
'table', 'product.template-stock.lot.type',
default='product.template-stock.lot.type' .replace('.', '_'))
lot_type_table_name = config.get(
'table', 'stock.lot.type',
default='stock.lot.type'.replace('.', '_'))
# Migration from 5.2: fill lot_required
if (table_h.table_exist(template_lot_type_table_name)
and table_h.table_exist(lot_type_table_name)):
table = cls.__table__()
template_lot_type = Table(template_lot_type_table_name)
lot_type = Table(lot_type_table_name)
cursor_select = connection.cursor()
cursor_select.execute(*template_lot_type.select(
template_lot_type.template,
distinct_on=template_lot_type.template))
for template_id, in cursor_select:
cursor.execute(*template_lot_type
.join(lot_type,
condition=template_lot_type.type == lot_type.id)
.select(
lot_type.code,
where=template_lot_type.template == template_id))
value = cls.lot_required.sql_format([t for t, in cursor])
cursor.execute(*table.update(
[table.lot_required], [value],
where=table.id == template_id))
table_h.drop_table('product.template-stock.lot.type',
template_lot_type_table_name)
table_h.drop_table('stock.lot.type', lot_type_table_name)
class Product(metaclass=PoolMeta):
__name__ = 'product.product'
def lot_is_required(self, from_, to):
'Is product lot required for move with "from_" and "to" location ?'
lot_required = [t.code for t in self.lot_required]
for location in (from_, to):
if location.type in lot_required:
return True
class TemplateLotType(ModelSQL):
'Template - Stock Lot Type'
__name__ = 'product.template-stock.lot.type'
template = fields.Many2One('product.template', 'Template', required=True,
select=True, ondelete='CASCADE')
type = fields.Many2One('stock.lot.type', 'Type', required=True,
ondelete='CASCADE')
return any(l.type in (self.lot_required or []) for l in [from_, to])
-13
View File
@@ -12,12 +12,6 @@ from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from trytond.modules.stock import StockMixin
__all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut',
'LotByLocationContext', 'ShipmentOutReturn',
'Period', 'PeriodCacheLot',
'Inventory', 'InventoryLine', 'InventoryCount', 'InventoryCountSearch',
'LotByLocationContext']
def check_no_move(func):
def find_moves(cls, records, state=None):
@@ -111,13 +105,6 @@ class LotByLocationContext(ModelView):
return self.forecast_date
class LotType(ModelSQL, ModelView):
"Stock Lot Type"
__name__ = 'stock.lot.type'
name = fields.Char('Name', required=True, translate=True)
code = fields.Char('Code', required=True)
class Move(metaclass=PoolMeta):
__name__ = 'stock.move'
lot = fields.Many2One('stock.lot', 'Lot',
-30
View File
@@ -112,36 +112,6 @@ this repository contains the full copyright notices and license terms. -->
<field name="action" ref="act_move_form_relate_lot"/>
</record>
<record model="stock.lot.type" id="type_supplier">
<field name="code">supplier</field>
<field name="name">Supplier</field>
</record>
<record model="stock.lot.type" id="type_customer">
<field name="code">customer</field>
<field name="name">Customer</field>
</record>
<record model="stock.lot.type" id="type_lost_found">
<field name="code">lost_found</field>
<field name="name">Lost and Found</field>
</record>
<record model="stock.lot.type" id="type_storage">
<field name="code">storage</field>
<field name="name">Storage</field>
</record>
<record model="stock.lot.type" id="type_production">
<field name="code">production</field>
<field name="name">Production</field>
</record>
<record model="ir.model.access" id="access_lot_type">
<field name="model" search="[('model', '=', 'stock.lot.type')]"/>
<field name="perm_read" eval="True"/>
<field name="perm_write" eval="False"/>
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<record model="ir.ui.view" id="move_view_form">
<field name="model">stock.move</field>
<field name="inherit" ref="stock.move_view_form"/>
@@ -39,6 +39,7 @@ Create product::
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.list_price = Decimal('20')
>>> template.lot_required = ['storage']
>>> template.save()
>>> product, = template.products
@@ -95,6 +96,13 @@ Assign the shipment::
>>> len(shipment_out.outgoing_moves)
1
Try to pack without lot::
>>> shipment_out.click('pack') # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
RequiredValidationError: ...
Set 2 lots::
>>> Lot = Model.get('stock.lot')
+1 -1
View File
@@ -5,7 +5,7 @@ this repository contains the full copyright notices and license terms. -->
<xpath expr="/form/notebook/page[@id='general']" position="after">
<page string="Lots" name="lot_required">
<label name="lot_required"/>
<field name="lot_required" widget="multiselection" yexpand="0"/>
<field name="lot_required" yexpand="0"/>
</page>
</xpath>
</data>