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..dd5a9d7
--- /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_rule.xml',
+ 'views/stock_supply_request.xml',
+ 'views/stock_supply_calendar.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
+
+
+
+
+
+
+ Supply calendar
+ stock.supply.calendar
+ calendar,tree,form
+
+
+
+
diff --git a/supply_order/views/stock_supply_request.xml b/supply_order/views/stock_supply_request.xml
new file mode 100644
index 0000000..b6f6e23
--- /dev/null
+++ b/supply_order/views/stock_supply_request.xml
@@ -0,0 +1,93 @@
+
+
+
+
+ stock_supply_request.tree
+ stock.supply.request
+
+
+
+
+
+
+
+
+
+
+ stock_supply_request.form
+ stock.supply.request
+
+
+
+
+
+ stock.supply.request.view.search
+ stock.supply.request
+
+
+
+
+
+
+
+
+
+
+
+ Request
+ stock.supply.request
+ tree,form
+ {'search_default_request_active':True}
+
+
+
+
diff --git a/supply_order/views/stock_supply_rule.xml b/supply_order/views/stock_supply_rule.xml
new file mode 100644
index 0000000..73330c2
--- /dev/null
+++ b/supply_order/views/stock_supply_rule.xml
@@ -0,0 +1,74 @@
+
+
+
+
+ stock_supply_rule.tree
+ stock.supply.rule
+
+
+
+
+
+
+
+
+
+
+ stock_supply_rule.form
+ stock.supply.rule
+
+
+
+
+
+ stock_supply_rule.search
+ stock.supply.rule
+
+
+
+
+
+
+
+
+ Supply Rule
+ stock.supply.rule
+ tree,form
+
+
+
+
+
diff --git a/supply_order/views/templates.xml b/supply_order/views/templates.xml
new file mode 100644
index 0000000..c63cde2
--- /dev/null
+++ b/supply_order/views/templates.xml
@@ -0,0 +1,112 @@
+
+
+
+ product_packaging.view.tree
+ product.packaging
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ product_product.view.kanban
+ product.product
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![Product]()
+
+
+
+
+ [
+
+ ]
+
+
+
+
+
+
+ -
+ Price:
+
+
+
+ -
+ Available:
+
+
+
+ -
+
+
+ -
+ -2
+ +1
+ +/-
+
+
+
+
+
+
+
+
+
+
+ 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()
+
+
+
+