From d917fabb1f786e7e89c6c6fe9b936e57dc372b6d Mon Sep 17 00:00:00 2001 From: juanjo-nan <57089222+juanjo-nan@users.noreply.github.com> Date: Thu, 13 Jan 2022 14:46:39 +0100 Subject: [PATCH] Add materials to location. (#8) Add news validations in stock.move (uom and quantity). Task #046344 --- __init__.py | 5 ++++ locale/ca.po | 52 +++++++++++++++++++++++++++++++++++++++++ locale/es.po | 53 ++++++++++++++++++++++++++++++++++++++++++ location.py | 50 +++++++++++++++++++++++++++++++++++++++ location.xml | 43 ++++++++++++++++++++++++++++++++++ message.xml | 7 +++++- move.py | 30 ++++++++++++++++++++++++ tryton.cfg | 4 +++- view/location_form.xml | 18 ++++++++++++++ view/material_form.xml | 7 ++++++ view/material_tree.xml | 6 +++++ 11 files changed, 273 insertions(+), 2 deletions(-) create mode 100644 location.py create mode 100644 location.xml create mode 100644 move.py create mode 100644 view/location_form.xml create mode 100644 view/material_form.xml create mode 100644 view/material_tree.xml diff --git a/__init__.py b/__init__.py index 83518be..4f3b92b 100644 --- a/__init__.py +++ b/__init__.py @@ -8,6 +8,8 @@ from . import product from . import weighing from . import quality from . import production +from . import location +from . import move def register(): Pool.register( @@ -52,6 +54,9 @@ def register(): # production.ProductionProductionCostPriceDistribution, production.ProductionCostPriceDistributionTemplate, production.ProductionCostPriceDistributionTemplateProductionTemplateAsk, + location.LocationMaterial, + location.Location, + move.Move, module='agronomics', type_='model') Pool.register( production.ProductionCostPriceDistributionTemplateProductionTemplate, diff --git a/locale/ca.po b/locale/ca.po index 6eb7e83..7588f91 100644 --- a/locale/ca.po +++ b/locale/ca.po @@ -1051,6 +1051,30 @@ msgctxt "field:quality.quantitative.test.line,product:" msgid "Product" msgstr "Productes" +msgctxt "field:stock.location,material:" +msgid "Material" +msgstr "Material" + +msgctxt "field:stock.location,max_capacity:" +msgid "Maximum capacity" +msgstr "Capacitat màxima" + +msgctxt "field:stock.location,tank:" +msgid "Tank" +msgstr "Dipòsit" + +msgctxt "field:stock.location,unit_digits:" +msgid "Unit Digits" +msgstr "Dígits de la unitat" + +msgctxt "field:stock.location,uom:" +msgid "Uom" +msgstr "UdM" + +msgctxt "field:stock.location.material,name:" +msgid "Name" +msgstr "Nom" + msgctxt "model:agronomics.beneficiary,name:" msgid "Beneficiaries" msgstr "Beneficiaris" @@ -1195,6 +1219,10 @@ msgctxt "model:ir.action,name:act_production_template_tree" msgid "Production Template" msgstr "Plantilla de producció" +msgctxt "model:ir.action,name:act_stock_location_material" +msgid "Materials" +msgstr "" + msgctxt "model:ir.action,name:act_weighing_action" msgid "Weighing" msgstr "Pesada" @@ -1264,6 +1292,22 @@ msgctxt "model:ir.message,text:msg_check_production_percentatge" msgid "Invalid percentatge \"%(percentatge)s\" in \"%(production)s\"." msgstr "Percentatge \"%(percentatge)s\" no vàlid a \"%(producció)s\"." +msgctxt "model:ir.message,text:msg_move_amount_exceed" +msgid "" +"The move cannot be done because the amount of the move exceeds the set " +"maximum amount." +msgstr "" +"No es pot finalitzar el moviment perquè la quantitat del moviment supera a " +"la quantitat màxima de la ubicació destí." + +msgctxt "model:ir.message,text:msg_move_unit_not_match" +msgid "" +"The movement cannot be done because the unit of measure of the movement not " +"matches the unit of mesure of the capacity in the destination location." +msgstr "" +"No es pot finalitzar el moviment perquè la unitat de mesura del moviment no " +"coincideix amb la unitat de mesura de la capacitat de la ubicació destí." + msgctxt "model:ir.message,text:msg_uom_not_fit" msgid "" "Inputs from Production template \"%(production)s\" must be of uom " @@ -1385,6 +1429,10 @@ msgctxt "model:ir.ui.menu,name:menu_weighing_list" msgid "Weighing" msgstr "Pesada" +msgctxt "model:ir.ui.menu,name:menuitem_stock_location_material" +msgid "Materials" +msgstr "" + msgctxt "model:product.product-agronomics.crop,name:" msgid "Product - Crop" msgstr "Producte - Collita" @@ -1642,6 +1690,10 @@ msgctxt "model:res.group,name:group_agronomics_admin" msgid "Agronomics Administration" msgstr "Administració Agronomics" +msgctxt "model:stock.location.material,name:" +msgid "Location Material" +msgstr "Material Ubicació" + msgctxt "selection:agronomics.weighing,state:" msgid "Cancelled" msgstr "Cancel·lat" diff --git a/locale/es.po b/locale/es.po index a5d9f53..a6953fb 100644 --- a/locale/es.po +++ b/locale/es.po @@ -1051,6 +1051,30 @@ msgctxt "field:quality.quantitative.test.line,product:" msgid "Product" msgstr "Productos" +msgctxt "field:stock.location,material:" +msgid "Material" +msgstr "Material" + +msgctxt "field:stock.location,max_capacity:" +msgid "Maximum capacity" +msgstr "Capacidad máxima" + +msgctxt "field:stock.location,tank:" +msgid "Tank" +msgstr "Depósito" + +msgctxt "field:stock.location,unit_digits:" +msgid "Unit Digits" +msgstr "Dígitos unidad" + +msgctxt "field:stock.location,uom:" +msgid "Uom" +msgstr "UdM" + +msgctxt "field:stock.location.material,name:" +msgid "Name" +msgstr "Nombre" + msgctxt "model:agronomics.beneficiary,name:" msgid "Beneficiaries" msgstr "Beneficiarios" @@ -1195,6 +1219,10 @@ msgctxt "model:ir.action,name:act_production_template_tree" msgid "Production Template" msgstr "Plantilla producción" +msgctxt "model:ir.action,name:act_stock_location_material" +msgid "Materials" +msgstr "" + msgctxt "model:ir.action,name:act_weighing_action" msgid "Weighing" msgstr "Pesada" @@ -1264,6 +1292,23 @@ msgctxt "model:ir.message,text:msg_check_production_percentatge" msgid "Invalid percentatge \"%(percentatge)s\" in \"%(production)s\"." msgstr "Porcentaje no válido \"%(porcentaje)s\" en \"% (distribución) s\"." +msgctxt "model:ir.message,text:msg_move_amount_exceed" +msgid "" +"The move cannot be done because the amount of the move exceeds the set " +"maximum amount." +msgstr "" +"No se puede finalizar el movimiento porque la cantidad del movimiento supera" +" la cantidad máxima de la ubicación destino." + +msgctxt "model:ir.message,text:msg_move_unit_not_match" +msgid "" +"The movement cannot be done because the unit of measure of the movement not " +"matches the unit of mesure of the capacity in the destination location." +msgstr "" +"No se puede finalizar el movimiento porque la unidad de medida del " +"movimiento no coincide con la unidad de medida de capacidad de la de la " +"ubicación destino." + msgctxt "model:ir.message,text:msg_uom_not_fit" msgid "" "Inputs from Production template \"%(production)s\" must be of uom " @@ -1385,6 +1430,10 @@ msgctxt "model:ir.ui.menu,name:menu_weighing_list" msgid "Weighing" msgstr "Pesada" +msgctxt "model:ir.ui.menu,name:menuitem_stock_location_material" +msgid "Materials" +msgstr "" + msgctxt "model:product.product-agronomics.crop,name:" msgid "Product - Crop" msgstr "Producto - Cosecha" @@ -1642,6 +1691,10 @@ msgctxt "model:res.group,name:group_agronomics_admin" msgid "Agronomics Administration" msgstr "Agronomics Administración" +msgctxt "model:stock.location.material,name:" +msgid "Location Material" +msgstr "Material Ubicación" + msgctxt "selection:agronomics.weighing,state:" msgid "Cancelled" msgstr "Cancelado" diff --git a/location.py b/location.py new file mode 100644 index 0000000..62ea0e4 --- /dev/null +++ b/location.py @@ -0,0 +1,50 @@ +# The COPYRIGHT file at the top level of this repository contains the full +# copyright notices and license terms. +from trytond.model import fields, ModelSQL, ModelView +from trytond.pool import PoolMeta, Pool +from trytond.pyson import Eval, Bool + + +tank_states = {'invisible': ~Bool(Eval('tank'))} +tank_depends = ['tank'] + +class LocationMaterial(ModelSQL, ModelView): + "Location Material" + __name__ = 'stock.location.material' + + name = fields.Char("Name", required=True) + + +class Location(metaclass=PoolMeta): + __name__ = 'stock.location' + + tank = fields.Boolean("Tank", + states={ + 'invisible': Eval('type') != 'storage', + }, + depends=['type']) + material = fields.Selection('get_materials', "Material", + states=tank_states, depends=tank_depends) + uom = fields.Many2One('product.uom', 'Uom', + states=tank_states, depends=tank_depends) + unit_digits = fields.Function(fields.Integer("Unit Digits", + states=tank_states, depends=tank_depends), + 'on_change_with_unit_digits') + max_capacity = fields.Float("Maximum capacity", + digits=(16, Eval('unit_digits', 2)), + states=tank_states, depends=['unit_digits', 'tank']) + + @classmethod + def get_materials(field_name): + pool = Pool() + LocationMaterial = pool.get('stock.location.material') + materials = [(None, "")] + for material in LocationMaterial.search([]): + materials.append((material.name, material.name)) + return materials + + @fields.depends('uom') + def on_change_with_unit_digits(self, name=None): + if self.uom: + return self.uom.digits + return 2 diff --git a/location.xml b/location.xml new file mode 100644 index 0000000..4773d8c --- /dev/null +++ b/location.xml @@ -0,0 +1,43 @@ + + + + + + + stock.location.material + form + material_form + + + stock.location.material + tree + material_tree + + + + Materials + stock.location.material + + + + + + + + + + + + + + + + + stock.location + + location_form + + + \ No newline at end of file diff --git a/message.xml b/message.xml index 5a5a648..4f54a39 100644 --- a/message.xml +++ b/message.xml @@ -30,7 +30,12 @@ this repository contains the full copyright notices and license terms. --> Cost "%(cost)s" has template "%(template)s" not present in Production Template Outputs". - + + The movement cannot be done because the unit of measure of the movement not matches the unit of mesure of the capacity in the destination location. + + + The move cannot be done because the amount of the move exceeds the set maximum amount. + diff --git a/move.py b/move.py new file mode 100644 index 0000000..693e168 --- /dev/null +++ b/move.py @@ -0,0 +1,30 @@ +# The COPYRIGHT file at the top level of this repository contains the full +# copyright notices and license terms. +from trytond.pool import PoolMeta, Pool +from trytond.i18n import gettext +from trytond.exceptions import UserError +from trytond.transaction import Transaction + + +class Move(metaclass=PoolMeta): + __name__ = 'stock.move' + + @classmethod + def validate(cls, moves): + pool = Pool() + Product = pool.get('product.product') + super(Move, cls).validate(moves) + for move in moves: + if move.to_location.tank: + #Same unit move and to location + if move.uom != move.to_location.uom: + raise UserError(gettext( + 'agronomics.msg_move_unit_not_match')) + #Do not exceed the amount + context = Transaction().context + with Transaction().set_context(context): + location_quantity = sum(Product.products_by_location( + [move.to_location.id]).values()) + if (location_quantity > move.to_location.max_capacity): + raise UserError(gettext( + 'agronomics.msg_move_amount_exceed')) diff --git a/tryton.cfg b/tryton.cfg index 0492564..31f6ff4 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -10,6 +10,7 @@ depends: quality_control purchase_contract production + stock xml: plot.xml party.xml @@ -18,4 +19,5 @@ xml: wine.xml message.xml production.xml - quality.xml \ No newline at end of file + location.xml + quality.xml diff --git a/view/location_form.xml b/view/location_form.xml new file mode 100644 index 0000000..57c30ae --- /dev/null +++ b/view/location_form.xml @@ -0,0 +1,18 @@ + + + + + + + + \ No newline at end of file diff --git a/view/material_form.xml b/view/material_form.xml new file mode 100644 index 0000000..5037817 --- /dev/null +++ b/view/material_form.xml @@ -0,0 +1,7 @@ + + +
+