diff --git a/custom_mrp_descarga/__manifest__.py b/custom_mrp_descarga/__manifest__.py index d85393f4..c4913762 100644 --- a/custom_mrp_descarga/__manifest__.py +++ b/custom_mrp_descarga/__manifest__.py @@ -22,6 +22,9 @@ "stock_move_in_out_qty", "mrp_production_date", "stock_inventory_import_cost", + "product_expiry", + "stock_move_line_product_lot_reader", + "product_multi_company_usability", ], "data": [ "data/quartering_product.xml", diff --git a/custom_mrp_descarga/models/stock_inventory_line.py b/custom_mrp_descarga/models/stock_inventory_line.py index c9c64f5e..486a329f 100644 --- a/custom_mrp_descarga/models/stock_inventory_line.py +++ b/custom_mrp_descarga/models/stock_inventory_line.py @@ -31,9 +31,13 @@ def onchange_cost(self): if entry_line and sum(entry_line.mapped("qty_done")) != 0: dev_line_amount = sum(dev_line.mapped("amount")) or 0 dev_line_qty = sum(dev_line.mapped("qty_done")) or 0 - self.cost = (sum(entry_line.mapped("amount")) - dev_line_amount) / ( - sum(entry_line.mapped("qty_done")) - dev_line_qty - ) + if sum(entry_line.mapped("qty_done")) - dev_line_qty != 0: + cost = (sum(entry_line.mapped("amount")) - dev_line_amount) / ( + sum(entry_line.mapped("qty_done")) - dev_line_qty + ) + else: + cost = 0 + self.cost = cost elif self.product_id: entry_line = self.inventory_id.batch_id.move_line_ids.filtered( lambda c: c.product_id == self.product_id diff --git a/custom_mrp_descarga/models/stock_move_line.py b/custom_mrp_descarga/models/stock_move_line.py index 2f29a730..07eb1ecd 100644 --- a/custom_mrp_descarga/models/stock_move_line.py +++ b/custom_mrp_descarga/models/stock_move_line.py @@ -1,5 +1,8 @@ # Copyright 2022 Berezi Amubieta - AvanzOSC # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). +from datetime import datetime + +import pytz from odoo import _, api, fields, models from odoo.exceptions import ValidationError @@ -52,6 +55,115 @@ def _compute_performance(self): performance = (line.qty_done * 100) / line.production_id.consume_qty line.performance = performance + @api.onchange("reader") + def onchange_reader(self): + if self.reader: + if ( + len(self.reader) == 44 + and self.reader[16] == "1" + and self.reader[17] == "5" + ): + self.reader_44_15(reader=self.reader) + elif ( + len(self.reader) == 46 + and self.reader[16] == "3" + and self.reader[17] == "1" + ): + self.reader_46_31(reader=self.reader) + else: + message = _("Unidentified barcode format : %(reader)s") % { + "reader": self.reader, + } + raise ValidationError(message) + + def reader_44_15(self, reader): + self.ensure_one() + if reader and len(reader) == 44 and reader[16] == "1" and reader[17] == "5": + product_code = reader[2:16] + product_domain = [("default_code", "=", product_code)] + product = ( + self.env["product.product"] + .search(product_domain) + .filtered( + lambda c: c.company_id == self.company_id + or self.company_id in c.company_ids + ) + ) + if not product: + message = _( + "Product not found, reader information for product code: %(reader)s" + ) % { + "reader": product_code, + } + raise ValidationError(message) + self.product_id = product.id + expiration_date = reader[18:24] + timezone = pytz.timezone(self._context.get("tz") or "UTC") + expiration_date = datetime.strptime(expiration_date, "%y%m%d") + expiration_date = timezone.localize(expiration_date).astimezone(pytz.UTC) + expiration_date = expiration_date.replace(tzinfo=None) + qty_done = reader[28:31] + qty_done_decimal = reader[31:34] + qty_done = qty_done + "." + qty_done_decimal + qty_done = float(qty_done) + lot_name = reader[36:44] + lot_domain = [ + ("name", "=", lot_name), + ("company_id", "=", self.company_id.id), + ("product_id", "=", product.id), + ] + lot = self.env["stock.production.lot"].search(lot_domain) + if not lot: + lot = self.env["stock.production.lot"].action_create_lot( + product, lot_name, self.company_id + ) + self.write( + { + "expiration_date": expiration_date, + "qty_done": qty_done, + "lot_id": lot.id, + } + ) + + def reader_46_31(self, reader): + self.ensure_one() + if reader and len(reader) == 46 and reader[16] == "3" and reader[17] == "1": + product_code = reader[2:16] + product_domain = [("default_code", "=", product_code)] + product = ( + self.env["product.product"] + .search(product_domain) + .filtered( + lambda c: c.company_id == self.company_id + or self.company_id in c.company_ids + ) + ) + if not product: + message = _( + "Product not found, reader information for product code: %(reader)s" + ) % { + "reader": product_code, + } + raise ValidationError(message) + self.product_id = product.id + qty_done = reader[20:23] + qty_done_decimal = reader[23:26] + qty_done = qty_done + "." + qty_done_decimal + container = int(reader[28:36]) + lot_name = reader[38:46] + lot_domain = [ + ("name", "=", lot_name), + ("company_id", "=", self.company_id.id), + ("product_id", "=", product.id), + ] + lot = self.env["stock.production.lot"].search(lot_domain) + if not lot: + lot = self.env["stock.production.lot"].action_create_lot( + product, lot_name, self.company_id + ) + vals = {"container": container, "qty_done": qty_done, "lot_id": lot.id} + self.write(vals) + @api.onchange("unit") def onchange_unit(self): super(StockMoveLine, self).onchange_unit() diff --git a/custom_mrp_descarga/views/stock_move_line_view.xml b/custom_mrp_descarga/views/stock_move_line_view.xml index 133030d7..81e29153 100644 --- a/custom_mrp_descarga/views/stock_move_line_view.xml +++ b/custom_mrp_descarga/views/stock_move_line_view.xml @@ -64,6 +64,12 @@ + +