diff --git a/stock_picklist/README.rst b/stock_picklist/README.rst
new file mode 100644
index 00000000..af019c78
--- /dev/null
+++ b/stock_picklist/README.rst
@@ -0,0 +1,16 @@
+**********************
+Hibou - Stock Picklist
+**********************
+
+Adds a `Picklist` button to picking batches (waves) that provides a summary grouped by location
+and product for all of the pickings in the batch.
+
+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_picklist/__init__.py b/stock_picklist/__init__.py
new file mode 100644
index 00000000..59b4cb50
--- /dev/null
+++ b/stock_picklist/__init__.py
@@ -0,0 +1,2 @@
+from . import report
+from . import models
diff --git a/stock_picklist/__manifest__.py b/stock_picklist/__manifest__.py
new file mode 100644
index 00000000..a9773b1c
--- /dev/null
+++ b/stock_picklist/__manifest__.py
@@ -0,0 +1,24 @@
+{
+ 'name': 'Stock Picklist',
+ 'version': '11.0.1.0.0',
+ 'category': 'Tools',
+ 'depends': [
+ 'stock_picking_batch',
+ ],
+ 'description': """
+Stock Picklist
+==============
+
+Adds a `Picklist` button to picking batches (waves) that provides a summary grouped by location
+and product for all of the pickings in the batch.
+ """,
+ 'author': 'Hibou Corp.',
+ 'license': 'AGPL-3',
+ 'website': 'https://hibou.io/',
+ 'data': [
+ 'report/stock_picklist.xml',
+ 'views/stock_views.xml',
+ ],
+ 'installable': True,
+ 'application': False,
+}
diff --git a/stock_picklist/models/__init__.py b/stock_picklist/models/__init__.py
new file mode 100644
index 00000000..07b5490f
--- /dev/null
+++ b/stock_picklist/models/__init__.py
@@ -0,0 +1 @@
+from . import stock_picking_batch
diff --git a/stock_picklist/models/stock_picking_batch.py b/stock_picklist/models/stock_picking_batch.py
new file mode 100644
index 00000000..9dfd37ff
--- /dev/null
+++ b/stock_picklist/models/stock_picking_batch.py
@@ -0,0 +1,13 @@
+from odoo import api, fields, models, _
+from odoo.exceptions import UserError
+
+
+class StockPickingBatch(models.Model):
+ _inherit = 'stock.picking.batch'
+
+ @api.multi
+ def print_pick_list(self):
+ pickings = self.mapped('picking_ids')
+ if not pickings:
+ raise UserError(_('Nothing to print.'))
+ return self.env.ref('stock_picklist.picklist').report_action(pickings, data=None, config=False)
diff --git a/stock_picklist/report/__init__.py b/stock_picklist/report/__init__.py
new file mode 100644
index 00000000..4927808c
--- /dev/null
+++ b/stock_picklist/report/__init__.py
@@ -0,0 +1 @@
+from . import stock_picklist
diff --git a/stock_picklist/report/stock_picklist.py b/stock_picklist/report/stock_picklist.py
new file mode 100644
index 00000000..0ad44148
--- /dev/null
+++ b/stock_picklist/report/stock_picklist.py
@@ -0,0 +1,36 @@
+from odoo import api, models
+from collections import namedtuple
+
+LocationGroup = namedtuple('LocationGroup', ('location_id', 'lines'))
+ProductGroup = namedtuple('ProductGroup', ('product_id', 'qty'))
+
+
+class StockPicklist(models.AbstractModel):
+ _name = 'report.stock_picklist.report_picklist'
+ _template = 'stock_picklist.report_picklist'
+
+ @api.model
+ def get_report_values(self, docids, data=None):
+ report_name = 'stock_picklist.report_picklist'
+ report = self.env['ir.actions.report']._get_report_from_name(report_name)
+ stock_pickings = self.env['stock.picking'].browse(docids)
+ stock_pack_operations = stock_pickings.mapped(lambda o: o.move_lines).mapped(lambda l: l.move_line_ids)
+
+ locations = stock_pack_operations.mapped(lambda o: o.location_id)
+ _l = []
+ for location in locations:
+ operations = stock_pack_operations.filtered(lambda o: o.location_id.id == location.id)
+ products = operations.mapped(lambda o: o.product_id)
+ _p = []
+ for product in products:
+ qty = sum(operations.filtered(lambda o: o.product_id.id == product.id).mapped(lambda o: o.product_qty))
+ _p.append(ProductGroup(product_id=product, qty=int(qty)))
+ _p = sorted(_p, key=lambda p: -p.qty)
+ _l.append(LocationGroup(location_id=location, lines=_p))
+
+ _l = sorted(_l, key=lambda l: l.location_id.name)
+ return {
+ 'doc_ids': docids,
+ 'doc_model': report.model,
+ 'docs': _l,
+ }
diff --git a/stock_picklist/report/stock_picklist.xml b/stock_picklist/report/stock_picklist.xml
new file mode 100644
index 00000000..6803e0bd
--- /dev/null
+++ b/stock_picklist/report/stock_picklist.xml
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+
+
+
+ |
+ Qty |
+ Product |
+ Barcode |
+ Location |
+
+
+
+
+
+ ![]() |
+ |
+
+ -
+ :
+
+
+
+ |
+
+
+
+
+ |
+ |
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/stock_picklist/views/stock_views.xml b/stock_picklist/views/stock_views.xml
new file mode 100644
index 00000000..16f009c2
--- /dev/null
+++ b/stock_picklist/views/stock_views.xml
@@ -0,0 +1,13 @@
+
+
+
+ stock.picking.batch.form.form
+ stock.picking.batch
+
+
+
+
+
+
+
+
\ No newline at end of file