diff --git a/stock_batch_picking_ux/models/stock_batch_picking.py b/stock_batch_picking_ux/models/stock_batch_picking.py
index 6d5184ed1..5b4ba7ab5 100644
--- a/stock_batch_picking_ux/models/stock_batch_picking.py
+++ b/stock_batch_picking_ux/models/stock_batch_picking.py
@@ -141,7 +141,6 @@ def action_done(self):
'picking_id': picking.id,
'name': rec.voucher_number,
})
-
return super(StockPickingBatch, self.with_context(do_not_assign_numbers=True)).action_done()
def action_view_stock_picking(self):
diff --git a/stock_batch_picking_ux/views/stock_batch_picking_views.xml b/stock_batch_picking_ux/views/stock_batch_picking_views.xml
index 43adad0da..1268e813d 100644
--- a/stock_batch_picking_ux/views/stock_batch_picking_views.xml
+++ b/stock_batch_picking_ux/views/stock_batch_picking_views.xml
@@ -42,25 +42,17 @@
-
-
diff --git a/stock_batch_picking_voucher/README.rst b/stock_batch_picking_voucher/README.rst
new file mode 100644
index 000000000..44be64e94
--- /dev/null
+++ b/stock_batch_picking_voucher/README.rst
@@ -0,0 +1,65 @@
+.. |company| replace:: ADHOC SA
+
+.. |company_logo| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-logo.png
+ :alt: ADHOC SA
+ :target: https://www.adhoc.com.ar
+
+.. |icon| image:: https://raw.githubusercontent.com/ingadhoc/maintainer-tools/master/resources/adhoc-icon.png
+
+.. image:: https://img.shields.io/badge/license-AGPL--3-blue.png
+ :target: https://www.gnu.org/licenses/agpl
+ :alt: License: AGPL-3
+
+====================================
+Pre-printed report in batch pickings
+====================================
+
+This module add the following features:
+#. Add aeroo report to print Pre-printed from batch pickings
+
+Installation
+============
+
+To install this module, you need to:
+
+#. Only need to install the module
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Nothing to configure
+
+
+.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
+ :alt: Try me on Runbot
+ :target: http://runbot.adhoc.com.ar/
+
+Bug Tracker
+===========
+
+Bugs are tracked on `GitHub Issues
+`_. In case of trouble, please
+check there if your issue has already been reported. If you spotted it first,
+help us smashing it by providing a detailed and welcomed feedback.
+
+Credits
+=======
+
+Images
+------
+
+* |company| |icon|
+
+Contributors
+------------
+
+Maintainer
+----------
+
+|company_logo|
+
+This module is maintained by the |company|.
+
+To contribute to this module, please visit https://www.adhoc.com.ar.
diff --git a/stock_batch_picking_voucher/__init__.py b/stock_batch_picking_voucher/__init__.py
new file mode 100644
index 000000000..bc704a047
--- /dev/null
+++ b/stock_batch_picking_voucher/__init__.py
@@ -0,0 +1,6 @@
+##############################################################################
+# For copyright and license notices, see __manifest__.py file in module root
+# directory
+##############################################################################
+from . import models
+from . import controllers
diff --git a/stock_batch_picking_voucher/__manifest__.py b/stock_batch_picking_voucher/__manifest__.py
new file mode 100644
index 000000000..ef48b7cda
--- /dev/null
+++ b/stock_batch_picking_voucher/__manifest__.py
@@ -0,0 +1,48 @@
+##############################################################################
+#
+# Copyright (C) 2015 ADHOC SA (http://www.adhoc.com.ar)
+# All Rights Reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+{
+ 'name': 'Preprinted report in batch pickings',
+ 'version': "17.0.1.0.0",
+ 'category': 'Warehouse Management',
+ 'sequence': 14,
+ 'summary': '',
+ 'author': 'ADHOC SA',
+ 'website': 'www.adhoc.com.ar',
+ 'license': 'AGPL-3',
+ 'images': [
+ ],
+ 'depends': [
+ 'stock_batch_picking_ux',
+ 'report_aeroo',
+ 'l10n_latam_base',
+ 'delivery_ux',
+ 'stock_voucher',
+ ],
+ 'data': [
+ 'views/stock_batch_picking_views.xml',
+ 'views/stock_picking_views.xml',
+
+ ],
+ 'demo': [
+ ],
+ 'installable': False,
+ 'auto_install': False,
+ 'application': False,
+}
diff --git a/stock_batch_picking_voucher/controllers/__init__.py b/stock_batch_picking_voucher/controllers/__init__.py
new file mode 100644
index 000000000..12a7e529b
--- /dev/null
+++ b/stock_batch_picking_voucher/controllers/__init__.py
@@ -0,0 +1 @@
+from . import main
diff --git a/stock_batch_picking_voucher/controllers/main.py b/stock_batch_picking_voucher/controllers/main.py
new file mode 100644
index 000000000..f9a85fc7b
--- /dev/null
+++ b/stock_batch_picking_voucher/controllers/main.py
@@ -0,0 +1,41 @@
+import io
+import json
+import urllib.parse
+
+from odoo.http import route, request
+from odoo.addons.web.controllers import report
+from PyPDF2 import PdfFileReader
+
+
+class ReportController(report.ReportController):
+
+ @route()
+ def report_download(self, data, context=None):
+ """This function is used by 'qwebactionmanager.js' in order to trigger
+ the download of a py3o/controller report.
+ :param data: a javascript array JSON.stringified containg report
+ internal url ([0]) and type [1]
+ :returns: Response with a filetoken cookie and an attachment header
+ """
+ response = super().report_download(data, context)
+ #NTH detect if the binary is a PDF, no matter ifn it was generated by a QWeb or Aeroo
+ requestcontent = json.loads(data)
+ url, type = requestcontent[0], requestcontent[1]
+ if type != 'aeroo':
+ return response
+ json_string = json.loads(data)[0]
+ context_part = json_string.split('context=')[1]
+ decoded_context = urllib.parse.unquote(context_part)
+ context_dict = json.loads(decoded_context)
+ batch_id = context_dict.get('active_id')
+ batch = context_dict.get('batch')
+ book_id = request.env['stock.picking.batch'].browse(batch_id).book_id
+ if batch and 'batch_picking_preprinted' in data:
+ if batch_id:
+ pdf_response = response.response[0]
+ reader = PdfFileReader(io.BytesIO(pdf_response))
+ number_pages = reader.getNumPages()
+ if not request.env['stock.picking.batch'].browse(batch_id).voucher_ids:
+ request.env['stock.picking.batch'].browse(batch_id).assign_numbers(number_pages, book_id)
+
+ return response
diff --git a/stock_batch_picking_voucher/models/__init__.py b/stock_batch_picking_voucher/models/__init__.py
new file mode 100644
index 000000000..f9dc4d14c
--- /dev/null
+++ b/stock_batch_picking_voucher/models/__init__.py
@@ -0,0 +1,2 @@
+from . import stock_picking_voucher
+from . import stock_picking_batch
diff --git a/stock_batch_picking_voucher/models/stock_picking_batch.py b/stock_batch_picking_voucher/models/stock_picking_batch.py
new file mode 100644
index 000000000..62f385dc0
--- /dev/null
+++ b/stock_batch_picking_voucher/models/stock_picking_batch.py
@@ -0,0 +1,95 @@
+##############################################################################
+# For copyright and license notices, see __manifest__.py file in module root
+# directory
+##############################################################################
+from odoo import fields, api, models, _
+from odoo.exceptions import UserError
+
+class StockPickingBatch(models.Model):
+ _inherit = 'stock.picking.batch'
+
+ voucher_ids = fields.One2many(
+ 'stock.picking.voucher',
+ 'batch_id',
+ 'Remitos',
+ copy=False,
+ )
+
+ book_id = fields.Many2one(
+ 'stock.book',
+ 'Talonario',
+ copy=False,
+ ondelete='restrict',
+ check_company=True
+ )
+
+ next_number = fields.Integer(
+ related='book_id.next_number',
+ )
+
+ def assign_numbers(self, estimated_number_of_pages, book):
+ self.ensure_one()
+ list_of_vouchers = []
+ for page in range(estimated_number_of_pages):
+ list_of_vouchers.append({
+ 'name': book.sequence_id.next_by_id(),
+ 'book_id': book.id,
+ 'batch_id' : self.id,
+ })
+ self.env['stock.picking.voucher'].sudo().create(list_of_vouchers)
+ self.message_post(body=_(
+ 'Números de remitos asignados: %s') % (self.voucher_ids.mapped("display_name")))
+ self.write({'book_id': book.id})
+
+ ############# Cambios post wizard, posible abstract #############
+
+ printed = fields.Boolean(
+ )
+
+ with_vouchers = fields.Boolean(
+ compute='_compute_with_vouchers',
+ )
+
+ book_id = fields.Many2one(
+ 'stock.book',
+ 'Book',
+ default=lambda self: self._get_book(),
+ )
+
+ next_voucher_number = fields.Integer(
+ 'Next Voucher Number',
+ related='book_id.sequence_id.number_next_actual',
+ )
+
+ estimated_number_of_pages = fields.Integer(
+ 'Number of Pages',
+ )
+
+ @api.model
+ def _get_book(self):
+ return self.book_id or self.env['stock.book'].search([('company_id', '=', self.picking_ids[:1].company_id.id)], limit=1)
+
+ @api.depends('picking_ids', 'picking_ids.voucher_ids')
+ def _compute_with_vouchers(self):
+ for rec in self:
+ rec.with_vouchers = bool(self.voucher_ids)
+
+ def do_print_and_assign(self):
+ # We override the method to avoid assignation
+ if not self.book_id:
+ raise UserError("Primero debe setear un talonario")
+ if not self.book_id.autoprinted:
+ self.printed = True
+ return self.with_context(batch=True).do_print_batch_vouchers()
+ self.assign_numbers(1,self.book_id)
+ return self.do_print_batch_vouchers()
+
+ def do_print_batch_vouchers(self):
+ '''This function prints the voucher'''
+ # self.env.ref('stock_batch_picking_voucher.batch_picking_preprinted').report_action(self)
+ return self.env.ref('stock_batch_picking_voucher.batch_picking_preprinted').report_action(self)
+
+ def do_clean(self):
+ self.voucher_ids.unlink()
+ # self.book_id = False
+ self.message_post(body=_('The assigned voucher were deleted'))
diff --git a/stock_batch_picking_voucher/models/stock_picking_voucher.py b/stock_batch_picking_voucher/models/stock_picking_voucher.py
new file mode 100644
index 000000000..c0cd3204f
--- /dev/null
+++ b/stock_batch_picking_voucher/models/stock_picking_voucher.py
@@ -0,0 +1,31 @@
+##############################################################################
+# For copyright and license notices, see __manifest__.py file in module root
+# directory
+##############################################################################
+from odoo import fields, models, api, _
+from odoo.exceptions import ValidationError
+
+
+class StockPickingVoucher(models.Model):
+ _inherit = 'stock.picking.voucher'
+
+ batch_id = fields.Many2one(
+ 'stock.picking.batch',
+ 'Batch',
+ ondelete='cascade',
+ index=True,
+ )
+
+ picking_id = fields.Many2one(
+ 'stock.picking',
+ 'Picking',
+ ondelete='cascade',
+ required=False,
+ index=True,
+ )
+
+ @api.constrains('picking_id', 'batch_id')
+ def _check_picking_id_required(self):
+ for record in self:
+ if not record.batch_id and not record.picking_id:
+ raise ValidationError("Al crear un voucher debe estar ligado a una trasnferencia o lote de transferencias")
diff --git a/stock_batch_picking_voucher/views/stock_batch_picking_views.xml b/stock_batch_picking_voucher/views/stock_batch_picking_views.xml
new file mode 100644
index 000000000..96f6aaba3
--- /dev/null
+++ b/stock_batch_picking_voucher/views/stock_batch_picking_views.xml
@@ -0,0 +1,55 @@
+
+
+
+ stock.picking.batch.form
+ stock.picking.batch
+
+ 99
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ stock.picking.tree.inherited
+ stock.picking
+
+ 99
+
+
+
+
+
+
+
+
+ stock.picking.tree.inherited2
+ stock.picking
+
+ 99
+
+
+
+
+
+
+
+
+
+
diff --git a/stock_batch_picking_voucher/views/stock_picking_views.xml b/stock_batch_picking_voucher/views/stock_picking_views.xml
new file mode 100644
index 000000000..cbf60e872
--- /dev/null
+++ b/stock_batch_picking_voucher/views/stock_picking_views.xml
@@ -0,0 +1,35 @@
+
+
+ stock.picking.form.exception
+ stock.picking
+ 99
+
+
+
+
+
+ Advertencia: La asignación de remitos se hace desde el lote de traslados, si quiere hacerlos desde este traslado cancele el lote o separe el traslado del mismo
+