diff --git a/stock_delivery_route/README.rst b/stock_delivery_route/README.rst
new file mode 100644
index 00000000..77695d27
--- /dev/null
+++ b/stock_delivery_route/README.rst
@@ -0,0 +1,18 @@
+********************************
+Hibou - Warehouse Delivery Route
+********************************
+
+Define delivery routes per warehouse. Pick the delivery route on the sale order or delivery order.
+
+Optionally define warehouse routes on the Customer or Customer's Delivery address to pre-select
+the delivery route.
+
+For more information and add-ons, visit `Hibou.io `_.
+
+
+=======
+License
+=======
+
+Please see `LICENSE `_.
+Copyright Hibou Corp. 2018
\ No newline at end of file
diff --git a/stock_delivery_route/__init__.py b/stock_delivery_route/__init__.py
new file mode 100644
index 00000000..0650744f
--- /dev/null
+++ b/stock_delivery_route/__init__.py
@@ -0,0 +1 @@
+from . import models
diff --git a/stock_delivery_route/__manifest__.py b/stock_delivery_route/__manifest__.py
new file mode 100644
index 00000000..4ae65bc2
--- /dev/null
+++ b/stock_delivery_route/__manifest__.py
@@ -0,0 +1,32 @@
+{
+ 'name': 'Warehouse Delivery Routes',
+ 'summary': 'Assign a delivery route to a sale order or picking.',
+ 'version': '15.0.1.0.0',
+ 'author': "Hibou Corp. ",
+ 'category': 'Warehouse',
+ 'license': 'LGPL-3',
+ 'complexity': 'expert',
+ 'images': [],
+ 'website': "https://hibou.io",
+ 'description': """
+Warehouse Delivery Routes
+=========================
+
+Assign a delivery route at the time of sale order.
+Additionally, set a default route on the customer level.
+
+""",
+ 'depends': [
+ 'sale_stock',
+ 'stock_picking_batch',
+ ],
+ 'demo': [],
+ 'data': [
+ 'views/partner_views.xml',
+ 'views/sale_views.xml',
+ 'views/stock_views.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'auto_install': False,
+ 'installable': True,
+}
diff --git a/stock_delivery_route/models/__init__.py b/stock_delivery_route/models/__init__.py
new file mode 100644
index 00000000..920b3030
--- /dev/null
+++ b/stock_delivery_route/models/__init__.py
@@ -0,0 +1,3 @@
+from . import stock
+from . import partner
+from . import sale
diff --git a/stock_delivery_route/models/partner.py b/stock_delivery_route/models/partner.py
new file mode 100644
index 00000000..57a26abc
--- /dev/null
+++ b/stock_delivery_route/models/partner.py
@@ -0,0 +1,7 @@
+from odoo import fields, models
+
+
+class Partner(models.Model):
+ _inherit = 'res.partner'
+
+ delivery_route_ids = fields.Many2many('stock.warehouse.delivery.route', string="Delivery Routes")
diff --git a/stock_delivery_route/models/sale.py b/stock_delivery_route/models/sale.py
new file mode 100644
index 00000000..f9fd0d6d
--- /dev/null
+++ b/stock_delivery_route/models/sale.py
@@ -0,0 +1,30 @@
+from odoo import api, fields, models
+
+
+class SaleOrder(models.Model):
+ _inherit = 'sale.order'
+
+ delivery_route_id = fields.Many2one('stock.warehouse.delivery.route', string='Delivery Route')
+
+ @api.onchange('partner_id', 'partner_shipping_id', 'warehouse_id')
+ def _prefill_delivery_route(self):
+ for so in self:
+ if so.warehouse_id:
+ for route in so.partner_shipping_id.delivery_route_ids.filtered(lambda d: d.warehouse_id == so.warehouse_id):
+ so.delivery_route_id = route
+ break
+ else:
+ for route in so.partner_id.delivery_route_ids.filtered(lambda d: d.warehouse_id == so.warehouse_id):
+ so.delivery_route_id = route
+ break
+ else:
+ so.delivery_route_id = False
+ else:
+ so.delivery_route_id = False
+
+ def action_confirm(self):
+ val = super(SaleOrder, self).action_confirm()
+ for so in self:
+ if so.delivery_route_id and so.picking_ids:
+ so.picking_ids.write({'delivery_route_id': so.delivery_route_id.id})
+ return val
diff --git a/stock_delivery_route/models/stock.py b/stock_delivery_route/models/stock.py
new file mode 100644
index 00000000..e3fedf9f
--- /dev/null
+++ b/stock_delivery_route/models/stock.py
@@ -0,0 +1,41 @@
+from odoo import api, fields, models
+
+
+class Warehouse(models.Model):
+ _inherit = 'stock.warehouse'
+
+ delivery_route_ids = fields.One2many('stock.warehouse.delivery.route', 'warehouse_id', string='Delivery Routes')
+
+
+class Picking(models.Model):
+ _inherit = 'stock.picking'
+ _order = 'sequence asc, priority desc, date asc, id desc'
+
+ sequence = fields.Integer(string='Sequence')
+ warehouse_id = fields.Many2one('stock.warehouse', related='picking_type_id.warehouse_id')
+ delivery_route_id = fields.Many2one('stock.warehouse.delivery.route', string='Delivery Route')
+ partner_address = fields.Char(string='Address', compute='_compute_partner_address')
+
+ def _compute_partner_address(self):
+ for pick in self:
+ if pick.partner_id:
+ pick.partner_address = '%s: %s, %s' % (pick.partner_id.name or '', pick.partner_id.street or '', pick.partner_id.city or '')
+ else:
+ pick.partner_address = ''
+
+
+class WarehouseDeliveryRoute(models.Model):
+ _name = 'stock.warehouse.delivery.route'
+
+ name = fields.Char(string='Name')
+ warehouse_id = fields.Many2one('stock.warehouse', string='Warehouse')
+ note = fields.Text(string='Note')
+
+ def name_get(self):
+ res = []
+ for route in self:
+ res.append((route.id, '[%s] %s' % (route.warehouse_id.code, route.name)))
+ return res
+
+
+
diff --git a/stock_delivery_route/security/ir.model.access.csv b/stock_delivery_route/security/ir.model.access.csv
new file mode 100644
index 00000000..e30455da
--- /dev/null
+++ b/stock_delivery_route/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+"user_stock_warehouse_delivery_route","user stock_warehouse_delivery_route","model_stock_warehouse_delivery_route","base.group_user",1,1,1,1
\ No newline at end of file
diff --git a/stock_delivery_route/tests/__init__.py b/stock_delivery_route/tests/__init__.py
new file mode 100644
index 00000000..91e10996
--- /dev/null
+++ b/stock_delivery_route/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_sale_routes
diff --git a/stock_delivery_route/tests/test_sale_routes.py b/stock_delivery_route/tests/test_sale_routes.py
new file mode 100644
index 00000000..a06c6057
--- /dev/null
+++ b/stock_delivery_route/tests/test_sale_routes.py
@@ -0,0 +1,22 @@
+from odoo.tests import common
+
+
+class TestSaleRoutes(common.TransactionCase):
+
+ def test_plan_two_warehouses(self):
+ partner = self.env.ref('base.res_partner_2')
+ product_1 = self.env.ref('product.product_product_24_product_template')
+ wh_1 = self.env.ref('stock.warehouse0')
+ delivery_route = self.env['stock.warehouse.delivery.route'].create({
+ 'name': 'Test',
+ 'warehouse_id': wh_1.id,
+ })
+ so = self.env['sale.order'].create({
+ 'warehouse_id': wh_1.id,
+ 'partner_id': partner.id,
+ 'order_line': [(0, 0, {'product_id': product_1.product_variant_id.id})],
+ 'delivery_route_id': delivery_route.id,
+ })
+ so.action_confirm()
+ self.assertTrue(so.state in ('sale', 'done'))
+ self.assertEqual(so.picking_ids[0].delivery_route_id, delivery_route)
diff --git a/stock_delivery_route/views/partner_views.xml b/stock_delivery_route/views/partner_views.xml
new file mode 100644
index 00000000..2583db73
--- /dev/null
+++ b/stock_delivery_route/views/partner_views.xml
@@ -0,0 +1,17 @@
+
+
+
+ res.partner.form.inherit
+ res.partner
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stock_delivery_route/views/sale_views.xml b/stock_delivery_route/views/sale_views.xml
new file mode 100644
index 00000000..3fa4d46d
--- /dev/null
+++ b/stock_delivery_route/views/sale_views.xml
@@ -0,0 +1,13 @@
+
+
+
+ sale.order.form.sale.stock.inherit
+ sale.order
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stock_delivery_route/views/stock_views.xml b/stock_delivery_route/views/stock_views.xml
new file mode 100644
index 00000000..cd8aa8d1
--- /dev/null
+++ b/stock_delivery_route/views/stock_views.xml
@@ -0,0 +1,87 @@
+
+
+
+
+ stock.warehouse.inherit
+ stock.warehouse
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.picking.internal.search.inherit
+ stock.picking
+
+
+
+
+
+
+
+
+
+
+
+ stock.picking.tree.search.inherit
+ stock.picking
+
+
+
+
+
+
+
+
+
+
+
+ stock.picking.form.inherit
+ stock.picking
+
+
+
+
+
+
+
+
+
+
+
+ stock_picking_batch.picking.tree.batch.inherit
+ stock.picking
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file