From 8aa61d4939e9c2c15e5b85ae153460cb226e3f3c Mon Sep 17 00:00:00 2001 From: Filoquin Date: Wed, 13 Sep 2023 00:57:04 -0300 Subject: [PATCH 1/2] [IMP] add module supply_order --- supply_order/__init__.py | 4 + supply_order/__manifest__.py | 32 +++ supply_order/data/ir_sequence.xml | 14 ++ supply_order/models/__init__.py | 6 + supply_order/models/procurement_group.py | 13 ++ supply_order/models/product_category.py | 38 ++++ supply_order/models/product_product.py | 100 +++++++++ supply_order/models/stock_picking_type.py | 15 ++ supply_order/models/stock_supply_calendar.py | 66 ++++++ supply_order/models/stock_supply_request.py | 209 +++++++++++++++++++ supply_order/models/stock_supply_rule.py | 130 ++++++++++++ supply_order/security/ir.model.access.csv | 6 + supply_order/views/stock_picking_type.xml | 15 ++ supply_order/views/stock_supply_calendar.xml | 82 ++++++++ supply_order/views/stock_supply_request.xml | 93 +++++++++ supply_order/views/stock_supply_rule.xml | 74 +++++++ supply_order/views/templates.xml | 112 ++++++++++ supply_order/wizard/__init__.py | 1 + supply_order/wizard/stock_supply_wizard.py | 80 +++++++ supply_order/wizard/stock_supply_wizard.xml | 46 ++++ 20 files changed, 1136 insertions(+) create mode 100644 supply_order/__init__.py create mode 100644 supply_order/__manifest__.py create mode 100644 supply_order/data/ir_sequence.xml create mode 100644 supply_order/models/__init__.py create mode 100644 supply_order/models/procurement_group.py create mode 100644 supply_order/models/product_category.py create mode 100644 supply_order/models/product_product.py create mode 100644 supply_order/models/stock_picking_type.py create mode 100644 supply_order/models/stock_supply_calendar.py create mode 100644 supply_order/models/stock_supply_request.py create mode 100644 supply_order/models/stock_supply_rule.py create mode 100644 supply_order/security/ir.model.access.csv create mode 100644 supply_order/views/stock_picking_type.xml create mode 100644 supply_order/views/stock_supply_calendar.xml create mode 100644 supply_order/views/stock_supply_request.xml create mode 100644 supply_order/views/stock_supply_rule.xml create mode 100644 supply_order/views/templates.xml create mode 100644 supply_order/wizard/__init__.py create mode 100644 supply_order/wizard/stock_supply_wizard.py create mode 100644 supply_order/wizard/stock_supply_wizard.xml diff --git a/supply_order/__init__.py b/supply_order/__init__.py new file mode 100644 index 0000000..35e7c96 --- /dev/null +++ b/supply_order/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import models +from . import wizard diff --git a/supply_order/__manifest__.py b/supply_order/__manifest__.py new file mode 100644 index 0000000..b9e9e8d --- /dev/null +++ b/supply_order/__manifest__.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +{ + 'name': "supply orders", + + 'summary': """ + Crea reglas especiales para abastecimiento""", + + 'description': """ + Crea reglas especiales para abastecimiento + """, + + 'author': "filoquin", + 'website': "xx", + + 'category': 'stock', + 'version': '13.0.0.0.1', + + # any module necessary for this one to work correctly + 'depends': ['stock', 'product'], + + # always loaded + 'data': [ + 'security/ir.model.access.csv', + 'data/ir_sequence.xml', + 'views/templates.xml', + 'views/stock_supply_calendar.xml', + 'views/stock_supply_request.xml', + 'views/stock_supply_rule.xml', + 'views/stock_picking_type.xml', + 'wizard/stock_supply_wizard.xml', + ], +} diff --git a/supply_order/data/ir_sequence.xml b/supply_order/data/ir_sequence.xml new file mode 100644 index 0000000..a984df5 --- /dev/null +++ b/supply_order/data/ir_sequence.xml @@ -0,0 +1,14 @@ + + + + + supply req + supply.req + SU/ + 5 + 1 + 1 + + + + diff --git a/supply_order/models/__init__.py b/supply_order/models/__init__.py new file mode 100644 index 0000000..1eac94f --- /dev/null +++ b/supply_order/models/__init__.py @@ -0,0 +1,6 @@ +from . import stock_supply_calendar +from . import stock_supply_rule +from . import stock_supply_request +from . import product_product +from . import procurement_group +from . import stock_picking_type diff --git a/supply_order/models/procurement_group.py b/supply_order/models/procurement_group.py new file mode 100644 index 0000000..24eec6b --- /dev/null +++ b/supply_order/models/procurement_group.py @@ -0,0 +1,13 @@ +from odoo import fields, models, api + +class ProcurementGroup(models.Model): + + _inherit = 'procurement.group' + + def _get_orderpoint_domain(self, company_id=False): + domain = super()._get_orderpoint_domain(company_id) + procurement_id = self.env.context.get('only_procurement', False) + if procurement_id: + domain += [('id', '=', procurement_id)] + return domain + diff --git a/supply_order/models/product_category.py b/supply_order/models/product_category.py new file mode 100644 index 0000000..e081f45 --- /dev/null +++ b/supply_order/models/product_category.py @@ -0,0 +1,38 @@ +from odoo import fields, models, api + + +class ProductCategory(models.Model): + + + _inherit = "product.category" + + supply_categ_id = fields.Many2one( + 'product.category', + string='Third level', + compute='_compute_supply_categ', + inverse='_compute_supply_categ_inverse', + store=True, + ) + + def _compute_supply_categ_inverse(self): + pass + + @api.depends('parent_id') + def _compute_supply_categ(self): + for categ in self: + parent = categ + childs = [] + childs.append(parent.parent_id.id) + while len(parent): + parent = self.search( + [('id', '=', parent.parent_id.id)], limit=1) + if len(parent) and parent.parent_id.id != False: + childs.append(parent.parent_id.id) + + if len(childs) > 3: + categ.supply_categ_id = childs[-4] + + elif len(childs) > 2: + categ.supply_categ_id = childs[-3] + else: + categ.supply_categ_id = categ.id diff --git a/supply_order/models/product_product.py b/supply_order/models/product_product.py new file mode 100644 index 0000000..a3a59bd --- /dev/null +++ b/supply_order/models/product_product.py @@ -0,0 +1,100 @@ +from requests import request +from odoo import fields, models, api + +class ProductPackaging(models.Model): + _inherit = "product.packaging" + + def add_to_request(self): + request = self._context.get('request', False) + factor = self._context.get('factor', 1.0) + if request: + request_id = self.env['stock.supply.request'].browse(request) + line = request_id.line_ids.filtered( + lambda r: r.product_id.id == self.product_id.id) + if len(line): + line.quantity += self.qty * factor + else: + vals = { + 'quantity': self.qty * factor, + 'request_id': request_id.id, + 'product_id': self.product_id.id, + } + self.env['stock.supply.request.line'].create(vals) + + def drop_form_request(self, qty=1): + request = self._context.get('request', False) + if request: + request_id = self.env['stock.supply.request'].browse(request) + line = request_id.line_ids.filtered( + lambda r: r.product_id.id == self.product_id.id) + if len(line) and line.quantity > 0: + line.quantity -= qty + else: + line.unlink() + + +class ProductProduct(models.Model): + + _inherit = "product.product" + + supply_qty = fields.Float( + 'qty', + compute="_compute_supply_qty", + digits='Product Unit of Measure', + ) + + def _compute_supply_qty(self): + request = self._context.get('request', False) + if request: + request_id = self.env['stock.supply.request'].browse(request) + lines = request_id.line_ids.filtered( + lambda r: r.product_id.id in self.ids) + qtys = {x.product_id.id: x.quantity for x in lines} + for product in self: + product.supply_qty = qtys.get(product.id, 0) + else: + self.supply_qty = 0 + + def add_to_request(self, qty=1): + request = self._context.get('request', False) + if request: + request_id = self.env['stock.supply.request'].browse(request) + line = request_id.line_ids.filtered( + lambda r: r.product_id.id == self.id) + if len(line): + line.quantity += qty + else: + vals = { + 'quantity': qty, + 'request_id': request_id.id, + 'product_id': self.id, + } + self.env['stock.supply.request.line'].create(vals) + + def drop_form_request(self, qty=1): + request = self._context.get('request', False) + if request: + request_id = self.env['stock.supply.request'].browse(request) + line = request_id.line_ids.filtered( + lambda r: r.product_id.id == self.id) + if len(line) and line.quantity > 0: + line.quantity -= qty + else: + line.unlink() + + def popup_request(self): + self.ensure_one() + view_id = self.env.ref('supply_order.product_packaging_pop_view_tree') + domain = [('product_id', '=', self.id)] + + view = { + 'name': self.display_name, + 'view_mode': 'tree', + 'view_id': view_id.id, + 'res_model': 'product.packaging', + 'type': 'ir.actions.act_window', + 'context':{'request':self._context.get('request')}, + 'domain': domain, + 'target': 'new', + } + return view diff --git a/supply_order/models/stock_picking_type.py b/supply_order/models/stock_picking_type.py new file mode 100644 index 0000000..7e7c224 --- /dev/null +++ b/supply_order/models/stock_picking_type.py @@ -0,0 +1,15 @@ +from odoo import fields, models, api + + +class StockPickingType(models.Model): + + + _inherit = "stock.picking.type" + + def new_supply_request(self): + self.ensure_one() + active_ids = self.ids + active_model = 'stock.picking.type' + + return self.env['stock.supply.wizard'].with_context(active_ids = active_ids, active_model=active_model).action_open_wizard() + diff --git a/supply_order/models/stock_supply_calendar.py b/supply_order/models/stock_supply_calendar.py new file mode 100644 index 0000000..a347672 --- /dev/null +++ b/supply_order/models/stock_supply_calendar.py @@ -0,0 +1,66 @@ +from odoo import fields, models, api + +class StockSupplyCalendar(models.Model): + _name = 'stock.supply.calendar' + _description = 'supply calendar' + + rule_id = fields.Many2one( + 'stock.supply.rule', + ) + name = fields.Char( + 'Name', + compute='_compute_name', + store=True + ) + deadline = fields.Datetime( + string='Date', + required=True + ) + request_deadline = fields.Datetime( + string='Request deadline' + ) + preparation_deadline = fields.Datetime( + string='Preparation deadline' + ) + warehouse_id = fields.Many2one( + 'stock.warehouse', + required=True, + related='rule_id.warehouse_id' + ) + request_ids = fields.One2many( + 'stock.supply.request', + 'calendar_id', + string='request', + ) + orig_warehouse_id = fields.Many2one( + 'stock.warehouse', + string='From Warehouse', + required=True, + related='rule_id.orig_warehouse_id' + ) + route_ids = fields.Many2many(related='rule_id.route_ids') + company_id = fields.Many2one( + 'res.company', + default= lambda self: self.env.company + ) + @api.depends( 'warehouse_id', 'deadline') + def _compute_name(self): + for calendar in self: + calendar.name = '%s %s' % (calendar.warehouse_id.name, fields.Datetime.to_string(calendar.deadline)) + + def action_new_request(self): + self.ensure_one() + request_id = self.env['stock.supply.request'].create( + {'calendar_id': self.id, 'rule_id': self.rule_id.id,'domain': self.rule_id.domain,}) + view_id = self.env.ref('supply_order.stock_supply_request_form') + view = { + 'name': "Abastecimiento", + 'view_mode': 'form', + 'view_id': view_id.id, + 'view_type': 'form', + 'res_id': request_id.id, + 'res_model': 'stock.supply.request', + 'type': 'ir.actions.act_window', + 'target': 'self', + } + return view diff --git a/supply_order/models/stock_supply_request.py b/supply_order/models/stock_supply_request.py new file mode 100644 index 0000000..39e86c9 --- /dev/null +++ b/supply_order/models/stock_supply_request.py @@ -0,0 +1,209 @@ +from odoo import fields, models, api +from odoo.exceptions import ValidationError +from datetime import datetime +from odoo.exceptions import UserError +from odoo.tools.misc import clean_context +from odoo.tools import safe_eval + + +class StockSupplyRequest(models.Model): + _name = 'stock.supply.request' + _description = 'warehouse supply request' + _inherit = ['mail.thread'] + + name = fields.Char( + string='Name', + default="supply" + ) + state = fields.Selection( + [('draft', 'Draft'), ('send', 'Send'), ('queued', 'Queued'), + ('done', 'Done'), ('cancel', 'Cancel')], + string='State', + default='draft', + ) + calendar_id = fields.Many2one( + 'stock.supply.calendar', + string='Calendar', + ) + rule_id = fields.Many2one( + 'stock.supply.rule', + ) + user_id = fields.Many2one( + 'res.users', + string='User', + default=lambda self: self.env.user.id, + ) + send_date = fields.Datetime( + string='Date', + ) + line_ids = fields.One2many( + 'stock.supply.request.line', + 'request_id', + string='lines', + ) + notes = fields.Text( + string='Notes', + ) + last_recompute_available = fields.Datetime( + string='last recompute available', + ) + request_picking_ids = fields.Many2many( + 'stock.picking', + compute="_compute_request_picking_ids" + ) + domain = fields.Char() + procurement_group_id = fields.Many2one('procurement.group') + filter_qty_available = fields.Boolean( + default=True + ) + + def _compute_request_picking_ids(self): + with_procurement = self.filtered('procurement_group_id') + for record in with_procurement: + record.request_picking_ids = self.env['stock.picking'].search([('group_id', '=', record.procurement_group_id.id)]) + + (self - with_procurement).request_picking_ids = False + + def action_send(self): + now = datetime.now() + request_limit = fields.Datetime.from_string( + self.calendar_id.request_deadline) + if now > request_limit: # and (not g1 or not g2): + raise ValidationError('Se vencio el limite de pedido') + + self.write({'state': 'send', 'send_date': fields.Datetime.now(), + 'user_id': self.env.user.id, + 'name': self.env['ir.sequence'].next_by_code('supply.req')}) + + def action_start_request(self): + self.ensure_one() + self.recompute_available() + view_id = self.env.ref('supply_order.product_supply_view_kanban') + search_view_id = self.env.ref('supply_order.product_supply_view_search') + domain = safe_eval(self.rule_id.domain or '[]') + if self.filter_qty_available: + domain += [('qty_available', '>', 0)] + product_ids = self.env['product.product'].with_context({'warehouse': self.calendar_id.orig_warehouse_id}).search(domain) + + view = { + 'name': self.calendar_id.display_name, + 'view_mode': 'kanban', + 'view_id': view_id.id, + 'search_view_id':search_view_id.id, + 'res_model': 'product.product', + 'type': 'ir.actions.act_window', + 'context':{'warehouse': self.calendar_id.orig_warehouse_id, 'calendar_id': self.calendar_id.id, 'request':self.id}, + 'domain': [('id', 'in', product_ids.ids)], + 'target': 'self', + } + return view + + + def action_cancel(self): + self.state = 'cancel' + + def recompute_available(self): + self.line_ids._get_virtual_available() + self.last_recompute_available = fields.Datetime.now() + + def action_done(self): + for request_id in self: + if all([x in ['done','cancel'] for x in request_id.request_picking_ids.mapped('state')]): + request_id.state = 'done' + + def action_queue(self): + for request_id in self: + if len(request_id.line_ids) < 1: + request_id.state = 'cancel' + return + values = request_id._prepare_run_values() + for request_line in request_id.line_ids: + + uom_reference = request_line.product_id.uom_id + #self.quantity = self.product_uom_id._compute_quantity(self.quantity, uom_reference) + try: + self.env['procurement.group'].with_context(clean_context(self.env.context)).run([ + self.env['procurement.group'].Procurement( + request_line.product_id, + request_line.quantity, + uom_reference, + request_id.calendar_id.warehouse_id.lot_stock_id, # Location + request_id.calendar_id.name, # Name + request_id.name, # Origin + request_id.calendar_id.warehouse_id.company_id, + values + ) + ]) + request_id.procurement_group_id = values['group_id'].id + except UserError as error: + raise UserError(error) + request_id.state = 'queued' + scheduler = self.env['stock.scheduler.compute'].create({}) + scheduler.with_context(only_procurement=values['group_id'].id).procure_calculation() + + def _prepare_run_values(self): + replenishment = self.env['procurement.group'].with_context(force_company=self.calendar_id.company_id.id).create({ + 'partner_id': self.user_id.partner_id.id, + }) + + values = { + 'warehouse_id': self.calendar_id.warehouse_id, + 'route_ids': self.calendar_id.route_ids if self.calendar_id.route_ids else self.env['stock.location.route'].search([]), + 'date_planned': self.calendar_id.preparation_deadline, + 'group_id': replenishment, + } + return values + + +class StockSupplyRequestLine(models.Model): + _name = 'stock.supply.request.line' + _description = 'warehouse supply request line' + + quantity = fields.Float( + string='quantity', + default=1, + ) + request_id = fields.Many2one( + 'stock.supply.request', + string='request', + ) + + product_id = fields.Many2one( + 'product.product', + string='Product', + ) + categ_id = fields.Many2one( + 'product.category', + string='Category', + related='product_id.categ_id', + ) + + list_price = fields.Float( + string='list_price', + related='product_id.list_price' + ) + my_virtual_available = fields.Float( + compute="_get_virtual_available", + string="my Stock", + store=True, + ) + central_virtual_available = fields.Float( + compute="_get_virtual_available", + string="central Stock", + store=True, + ) + + + @api.onchange('product_id', 'request_id') + @api.depends('product_id', 'request_id') + def _get_virtual_available(self): + + for line in self: + warehouse_id = line.request_id.calendar_id.warehouse_id.id + orig_warehouse_id = line.request_id.calendar_id.orig_warehouse_id.id + line.my_virtual_available = line.product_id.with_context( + warehouse=warehouse_id).virtual_available + line.central_virtual_available = line.product_id.with_context( + warehouse=orig_warehouse_id).virtual_available + + diff --git a/supply_order/models/stock_supply_rule.py b/supply_order/models/stock_supply_rule.py new file mode 100644 index 0000000..0d45d0b --- /dev/null +++ b/supply_order/models/stock_supply_rule.py @@ -0,0 +1,130 @@ +from odoo import fields, models, api +from datetime import datetime, timedelta + + +DAYS = [('0', 'Monday'), + ('1', 'Tuesday'), + ('2', 'Wednesday'), + ('3', 'Thursday'), + ('4', 'Friday'), + ('5', 'Saturday'), + ('6', 'Sunday')] + +DAYS_NAMES = {'0': 'Lunes', + '1': 'Martes', + '2': 'Miercoles', + '3': 'Jueves', + '4': 'Viernes', + '5': 'Sabado', + '6': 'Domingo'} + + +def next_weekday(d, weekday): + days_ahead = weekday - d.weekday() + if days_ahead <= 0: # Target day already happened this week + days_ahead += 7 + return d + timedelta(days_ahead) + + +class stock_supply_rule(models.Model): + _name = 'stock.supply.rule' + _description = 'warehouse supply rule' + + name = fields.Char( + compute="_compute_name", + store=True + ) + + orig_warehouse_id = fields.Many2one( + 'stock.warehouse', + string='From Warehouse', + required=True + ) + + warehouse_id = fields.Many2one( + 'stock.warehouse', + string='To Warehouse', + required=True + ) + route_ids = fields.Many2many( + 'stock.location.route', string='Preferred Routes', + help="Apply specific route(s) for the replenishment instead of product's default routes.", + domain="['|', ('company_id', '=', False), ('company_id', '=', company_id)]") + + domain = fields.Char() + company_id = fields.Many2one( + 'res.company', + default=lambda self: self.env.company + ) + + request_day = fields.Selection( + DAYS, + string='Limit request day', + required=True, + select=True + ) + request_hour = fields.Float( + string='Limit request hour', + ) + + recept_day = fields.Selection( + DAYS, + string='Limit recept day', + required=True, + select=True + ) + recept_hour = fields.Float( + string='Limit recept hour', + ) + + preparation_day = fields.Selection( + DAYS, + string='Limit preparation day', + required=True, + select=True + ) + preparation_hour = fields.Float( + string='Limit preparation hour', + ) + active = fields.Boolean( + default=True + ) + + + + def make_calendar(self): + date_from = datetime.now() + for rule in self: + recept_day = next_weekday(date_from, int( + rule.recept_day)).replace(hour=0, second=0, microsecond=0, minute=0) + timedelta(hours=(rule.recept_hour + 3.0)) + exists = self.env['stock.supply.calendar'].search_count([ + ('rule_id', '=', rule.id), + ('deadline', '=', fields.Datetime.to_string(recept_day))]) + if not exists: + request_day = next_weekday(date_from, int( + rule.request_day)).replace(hour=0, second=0, microsecond=0, minute=0) + timedelta(hours=(rule.request_hour + 3.0)) + preparation_day = next_weekday(date_from, int( + rule.preparation_day)).replace(hour=0, second=0, microsecond=0, minute=0) + timedelta(hours=(rule.preparation_hour + 3.0)) + + calendar = {} + + calendar['deadline'] = recept_day + calendar['request_deadline'] = request_day + calendar['preparation_deadline'] = preparation_day + calendar['rule_id'] = rule.id + calendar['company_id'] = rule.company_id.id + + calendar_id = self.env[ + 'stock.supply.calendar'].create(calendar) + # calendar_id.action_budget_lines() + # calendar_id.compute_used_amount() + + @api.model + def cron_create_calendar(self): + self.search([]).make_calendar() + + @api.depends('warehouse_id', 'recept_day') + def _compute_name(self): + for rule in self: + rule.name = '%s %s ' % ( + DAYS_NAMES[rule.recept_day], rule.warehouse_id.name) diff --git a/supply_order/security/ir.model.access.csv b/supply_order/security/ir.model.access.csv new file mode 100644 index 0000000..7b68030 --- /dev/null +++ b/supply_order/security/ir.model.access.csv @@ -0,0 +1,6 @@ +"id","name","model_id/id","group_id/id","perm_read","perm_write","perm_create","perm_unlink" +"stock_supply_request","stock.supply.request","supply_order.model_stock_supply_request","stock.group_stock_manager","True","True","True","True" +"stock_supply_calendar","stock.supply.calendar","supply_order.model_stock_supply_calendar","stock.group_stock_manager","True","True","True","True" +"stock_supply_request_line","stock.supply.request.line","supply_order.model_stock_supply_request_line","stock.group_stock_manager","True","True","True","True" +"stock_supply_rule","stock.supply.rule","supply_order.model_stock_supply_rule","stock.group_stock_manager","True","True","True","True" +"stock_supply_wizard","stock.supply.wizard","supply_order.model_stock_supply_wizard","stock.group_stock_manager","True","True","True","True" diff --git a/supply_order/views/stock_picking_type.xml b/supply_order/views/stock_picking_type.xml new file mode 100644 index 0000000..995af6a --- /dev/null +++ b/supply_order/views/stock_picking_type.xml @@ -0,0 +1,15 @@ + + + + + stock.picking.type.kanban + stock.picking.type + + + + + + + + diff --git a/supply_order/views/stock_supply_calendar.xml b/supply_order/views/stock_supply_calendar.xml new file mode 100644 index 0000000..c67103b --- /dev/null +++ b/supply_order/views/stock_supply_calendar.xml @@ -0,0 +1,82 @@ + + + + + stock_supply_calendar.calendar + stock.supply.calendar + + + + + + + + + stock_supply_calendar.tree + stock.supply.calendar + + + + + + + + + + + stock_supply_calendar.form + stock.supply.calendar + + +
+ +
+
+ +

+ +

+ + + + + + + + + + + + + + + + + + + +
+
+ + + + +
+
+ + product_supply.view.search + product.product + + + + + + + + + + + + + + + + + + + + + + + + product_supply + product.product + kanban + + + [] + + + +
+
diff --git a/supply_order/wizard/__init__.py b/supply_order/wizard/__init__.py new file mode 100644 index 0000000..cc82950 --- /dev/null +++ b/supply_order/wizard/__init__.py @@ -0,0 +1 @@ +from . import stock_supply_wizard diff --git a/supply_order/wizard/stock_supply_wizard.py b/supply_order/wizard/stock_supply_wizard.py new file mode 100644 index 0000000..53e1360 --- /dev/null +++ b/supply_order/wizard/stock_supply_wizard.py @@ -0,0 +1,80 @@ +from odoo import fields, models, api, _ + + +class StockSupplyWizard(models.Model): + _name = 'stock.supply.wizard' + _description = 'warehouse supply wizard' + + @api.model + def default_get(self, default_fields): + rec = super(StockSupplyWizard, self).default_get(default_fields) + active_ids = self._context.get('active_ids') or self._context.get('active_id') + active_model = self._context.get('active_model') + if active_model == 'stock.picking': + pickings = self.env[active_model].browse(active_ids) + rec['filter_qty_available'] = all([x == 'done' for x in pickings.mapped('state')]) + rec['product_ids'] = [(6, 0, pickings.mapped('move_lines.product_id').ids)] + rec['warehouse_id'] = pickings.mapped('warehouse_id')[0].id + rec['direction'] = 'outgoing' + elif active_model == 'purchase.order': + purchases = self.env[active_model].browse(active_ids) + rec['filter_qty_available'] = all([x == 'done' for x in purchases.mapped('state')]) + rec['product_ids'] =[(6, 0, purchases.mapped('order_line.product_id').ids)] + rec['warehouse_id'] = pickings.mapped('pickings_type_id.warehouse_id')[0].id + rec['direction'] = 'outgoing' + elif active_model == 'stock.picking.type': + picking_type = self.env[active_model].browse(active_ids)[0] + rec['filter_qty_available'] = True + rec['direction'] = picking_type.code + rec['warehouse_id'] = picking_type.warehouse_id.id + + return rec + + name = fields.Char() + warehouse_id = fields.Many2one('stock.warehouse') + direction = fields.Selection([('incoming', 'Receipt'),('outgoing','Delivery')]) + rule_id = fields.Many2one('stock.supply.rule') + calendar_id = fields.Many2one('stock.supply.calendar') + product_ids = fields.Many2many('product.product') + filter_qty_available = fields.Boolean() + filter_autocomplete = fields.Boolean() + + def action_create_request(self): + domain = [] + if len(self.product_ids): + domain += [('id', 'in', self.product_ids.ids)] + request_id = self.env['stock.supply.request'].create({ + 'calendar_id':self.calendar_id.id, + 'rule_id':self.rule_id.id, + 'filter_qty_available': self.filter_qty_available, + 'domain': str(domain), + }) + view_id = self.env.ref('supply_order.stock_supply_request_form') + view = { + 'name': "Abastecimiento", + 'view_mode': 'form', + 'view_id': view_id.id, + 'view_type': 'form', + 'res_id': request_id.id, + 'res_model': 'stock.supply.request', + 'type': 'ir.actions.act_window', + 'target': 'self', + } + return view + + + def action_open_wizard(self): + + active_ids = self.env.context.get('active_ids') + if not active_ids: + return '' + + return { + 'name': _('new supply request'), + 'res_model': 'stock.supply.wizard', + 'view_mode': 'form', + 'view_id': self.env.ref('supply_order.stock_supply_wizard_view_form').id, + 'context': self.env.context, + 'target': 'new', + 'type': 'ir.actions.act_window', + } \ No newline at end of file diff --git a/supply_order/wizard/stock_supply_wizard.xml b/supply_order/wizard/stock_supply_wizard.xml new file mode 100644 index 0000000..b60aa52 --- /dev/null +++ b/supply_order/wizard/stock_supply_wizard.xml @@ -0,0 +1,46 @@ + + + + stock_supply_wizard.view.form + stock.supply.wizard + +
+ + + + + + + + + + + + +
+
+
+
+
+ + new Supply request + + + list + code + + action = model.open_wizard() + + + + new Supply request + + + code + + action = model.open_wizard() + + + +
From 3ef6e0c0d801c341a26370cea35db124b146379b Mon Sep 17 00:00:00 2001 From: Gabriela Rivero Date: Tue, 19 Sep 2023 18:13:13 -0300 Subject: [PATCH 2/2] [FIX] root menuitem not found --- supply_order/__manifest__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supply_order/__manifest__.py b/supply_order/__manifest__.py index b9e9e8d..dd5a9d7 100644 --- a/supply_order/__manifest__.py +++ b/supply_order/__manifest__.py @@ -23,9 +23,9 @@ 'security/ir.model.access.csv', 'data/ir_sequence.xml', 'views/templates.xml', - 'views/stock_supply_calendar.xml', - 'views/stock_supply_request.xml', 'views/stock_supply_rule.xml', + 'views/stock_supply_request.xml', + 'views/stock_supply_calendar.xml', 'views/stock_picking_type.xml', 'wizard/stock_supply_wizard.xml', ],