mirror of
https://gitlab.com/datalifeit/trytond-stock_product_category_location
synced 2023-12-14 04:33:11 +01:00
parent
163e43fe05
commit
c1086ae4b6
|
@ -62,10 +62,6 @@ msgctxt "model:stock.product.category.location,name:"
|
||||||
msgid "Product Category Location"
|
msgid "Product Category Location"
|
||||||
msgstr "Ubicación de categoría de producto"
|
msgstr "Ubicación de categoría de producto"
|
||||||
|
|
||||||
msgctxt "selection:stock.product.category.location,process:"
|
|
||||||
msgid "All"
|
|
||||||
msgstr "Todos"
|
|
||||||
|
|
||||||
msgctxt "view:product.category:"
|
msgctxt "view:product.category:"
|
||||||
msgid "Locations"
|
msgid "Locations"
|
||||||
msgstr "Ubicaciones"
|
msgstr "Ubicaciones"
|
||||||
|
|
37
location.py
37
location.py
|
@ -30,16 +30,15 @@ class ProductCategoryLocation(ModelSQL, ModelView):
|
||||||
domain=[
|
domain=[
|
||||||
('type', '=', 'storage'), ('parent', 'child_of', Eval('warehouse'))],
|
('type', '=', 'storage'), ('parent', 'child_of', Eval('warehouse'))],
|
||||||
depends=['warehouse'])
|
depends=['warehouse'])
|
||||||
process = fields.Selection(
|
process = fields.Many2One('business.process', 'Process',
|
||||||
[('all', 'All')], 'Process', required=True, select=True, translate=True)
|
ondelete='RESTRICT', select=True)
|
||||||
sequence = fields.Integer('Sequence')
|
sequence = fields.Integer('Sequence')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __setup__(cls):
|
def __setup__(cls):
|
||||||
super(ProductCategoryLocation, cls).__setup__()
|
super(ProductCategoryLocation, cls).__setup__()
|
||||||
cls._sql_constraints = [('_uk1',
|
cls._error_messages.update({
|
||||||
'UNIQUE(category, location, process)',
|
'unique_key': 'Category, location and process must be unique.'})
|
||||||
'Category, location and process must be unique.')]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _compute_sequence(table, record):
|
def _compute_sequence(table, record):
|
||||||
|
@ -78,7 +77,33 @@ class ProductCategoryLocation(ModelSQL, ModelView):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default_process():
|
def default_process():
|
||||||
return "all"
|
return None
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def order_process(tables):
|
||||||
|
table, _ = tables[None]
|
||||||
|
return [table.process != None, table.process]
|
||||||
|
|
||||||
|
def _get_unique_key(self):
|
||||||
|
return (self.category.id, self.location.id,
|
||||||
|
self.process.id if self.process else None)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate(cls, records):
|
||||||
|
values = {}
|
||||||
|
for record in records:
|
||||||
|
_uq = record._get_unique_key()
|
||||||
|
if values.get(_uq):
|
||||||
|
cls.raise_user_error('unique_key')
|
||||||
|
values.setdefault(_uq, 1)
|
||||||
|
|
||||||
|
others = cls.search([('id', 'not in', map(int, records))])
|
||||||
|
for other in others:
|
||||||
|
_uq = other._get_unique_key()
|
||||||
|
if values.get(_uq):
|
||||||
|
cls.raise_user_error('unique_key')
|
||||||
|
|
||||||
|
super(ProductCategoryLocation, cls).validate(records)
|
||||||
|
|
||||||
|
|
||||||
class Location:
|
class Location:
|
||||||
|
|
18
product.py
18
product.py
|
@ -16,18 +16,24 @@ class Category:
|
||||||
default_location = fields.Function(fields.Many2One('stock.location', 'Default location'),
|
default_location = fields.Function(fields.Many2One('stock.location', 'Default location'),
|
||||||
'get_default_location')
|
'get_default_location')
|
||||||
|
|
||||||
def get_default_location(self, warehouse=None, process='all'):
|
def get_default_location(self, warehouse=None,
|
||||||
|
process=None,
|
||||||
|
location_type='storage'):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Location = pool.get('stock.product.category.location')
|
Location = pool.get('stock.product.category.location')
|
||||||
|
|
||||||
|
process_ids = [None]
|
||||||
|
if process:
|
||||||
|
process_ids.append(process.id)
|
||||||
_domain = [('category', '=', self.id),
|
_domain = [('category', '=', self.id),
|
||||||
('process', 'in', [process, 'all'])]
|
('location.type', '=', location_type),
|
||||||
|
('process', 'in', process_ids)]
|
||||||
if warehouse:
|
if warehouse:
|
||||||
_domain.append(('warehouse', '=', warehouse.id))
|
_domain.append(('warehouse', '=', warehouse.id))
|
||||||
locations = Location.search(_domain, order=[('sequence', 'ASC')])
|
locations = Location.search(_domain,
|
||||||
|
order=[('process', 'DESC'),
|
||||||
|
('sequence', 'ASC')],
|
||||||
|
limit=2)
|
||||||
if locations:
|
if locations:
|
||||||
for location in locations:
|
|
||||||
if location.process == process:
|
|
||||||
return location.location.id
|
|
||||||
return locations[0].location.id
|
return locations[0].location.id
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -54,4 +54,4 @@ Check sequence compute in locations form::
|
||||||
>>> test_storage.save()
|
>>> test_storage.save()
|
||||||
>>> test_storage.reload()
|
>>> test_storage.reload()
|
||||||
>>> test_storage.categories[0].sequence
|
>>> test_storage.categories[0].sequence
|
||||||
2
|
2
|
||||||
|
|
|
@ -19,6 +19,7 @@ class StockProductCategoryLocationTestCase(ModuleTestCase):
|
||||||
self.location = POOL.get('stock.location')
|
self.location = POOL.get('stock.location')
|
||||||
self.category = POOL.get('product.category')
|
self.category = POOL.get('product.category')
|
||||||
self.cat_loc = POOL.get('stock.product.category.location')
|
self.cat_loc = POOL.get('stock.product.category.location')
|
||||||
|
self.process = POOL.get('business.process')
|
||||||
|
|
||||||
def test0010_add_category_default_location(self):
|
def test0010_add_category_default_location(self):
|
||||||
"""Add the category default location for a warehouse"""
|
"""Add the category default location for a warehouse"""
|
||||||
|
@ -30,7 +31,7 @@ class StockProductCategoryLocationTestCase(ModuleTestCase):
|
||||||
'category': new_cat.id,
|
'category': new_cat.id,
|
||||||
'warehouse': storage.parent.id,
|
'warehouse': storage.parent.id,
|
||||||
'location': storage.id,
|
'location': storage.id,
|
||||||
'process': 'all'
|
'process': None
|
||||||
}
|
}
|
||||||
self.cat_loc.create([cat_loc_rec])
|
self.cat_loc.create([cat_loc_rec])
|
||||||
transaction.cursor.commit()
|
transaction.cursor.commit()
|
||||||
|
@ -45,13 +46,12 @@ class StockProductCategoryLocationTestCase(ModuleTestCase):
|
||||||
'category': new_cat.id,
|
'category': new_cat.id,
|
||||||
'warehouse': storage.parent.id,
|
'warehouse': storage.parent.id,
|
||||||
'location': storage.id,
|
'location': storage.id,
|
||||||
'process': 'all'
|
'process': None
|
||||||
}
|
}
|
||||||
with self.assertRaises(UserError) as cm:
|
with self.assertRaises(UserError) as cm:
|
||||||
self.cat_loc.create([cat_loc_rec])
|
self.cat_loc.create([cat_loc_rec])
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
cm.exception.message, 'Category, location and process must be unique.')
|
cm.exception.message, 'Category, location and process must be unique.')
|
||||||
transaction.cursor.commit()
|
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[tryton]
|
[tryton]
|
||||||
version=3.6.1
|
version=3.6.1
|
||||||
depends:
|
depends:
|
||||||
|
business_process
|
||||||
ir
|
ir
|
||||||
res
|
res
|
||||||
stock_location_notebook
|
stock_location_notebook
|
||||||
|
|
|
@ -9,5 +9,5 @@
|
||||||
<label name="location"/>
|
<label name="location"/>
|
||||||
<field name="location"/>
|
<field name="location"/>
|
||||||
<label name="process"/>
|
<label name="process"/>
|
||||||
<field name="process"/>
|
<field name="process" widget="selection"/>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
<tree string="Category Locations" editable="bottom">
|
<tree string="Category Locations" editable="bottom">
|
||||||
<field name="category"/>
|
<field name="category"/>
|
||||||
<field name="location"/>
|
<field name="location"/>
|
||||||
<field name="process"/>
|
<field name="process" widget="selection"/>
|
||||||
</tree>
|
</tree>
|
|
@ -5,6 +5,6 @@
|
||||||
<field name="category"/>
|
<field name="category"/>
|
||||||
<field name="warehouse"/>
|
<field name="warehouse"/>
|
||||||
<field name="location"/>
|
<field name="location"/>
|
||||||
<field name="process"/>
|
<field name="process" widget="selection"/>
|
||||||
<field name="sequence" tree_invisible="1"/>
|
<field name="sequence" tree_invisible="1"/>
|
||||||
</tree>
|
</tree>
|
||||||
|
|
Loading…
Reference in a new issue