import io import zipfile from odoo import _ from odoo.exceptions import AccessError, UserError from odoo.http import Controller, content_disposition, request, route class EmployeePayslipDownloadController(Controller): @route('/employee_it_declaration/my_payslips/', type='http', auth='user') def download_my_payslips(self, wizard_id, **kwargs): wizard = request.env['employee.payslip.download.wizard'].browse(wizard_id) if not wizard.exists() or wizard.create_uid != request.env.user: return request.not_found() try: payslips = wizard._get_payslips_for_download() except (AccessError, UserError): return request.not_found() if wizard.download_type == 'single': payslip = payslips[:1] report, pdf_content = wizard._get_pdf_content(payslip) headers = [ ('Content-Type', 'application/pdf'), ('Content-Length', len(pdf_content)), ('Content-Disposition', content_disposition(wizard._get_pdf_filename(payslip, report))), ] return request.make_response(pdf_content, headers=headers) zip_buffer = io.BytesIO() used_filenames = set() with zipfile.ZipFile(zip_buffer, 'w', compression=zipfile.ZIP_DEFLATED) as payslip_zip: for payslip in payslips: report, pdf_content = wizard._get_pdf_content(payslip) filename = self._deduplicate_filename(wizard._get_pdf_filename(payslip, report), used_filenames) payslip_zip.writestr(filename, pdf_content) zip_content = zip_buffer.getvalue() headers = [ ('Content-Type', 'application/zip'), ('Content-Length', len(zip_content)), ('Content-Disposition', content_disposition(wizard._get_zip_filename())), ] return request.make_response(zip_content, headers=headers) @staticmethod def _deduplicate_filename(filename, used_filenames): if filename not in used_filenames: used_filenames.add(filename) return filename stem, extension = filename.rsplit('.', 1) if '.' in filename else (filename, '') counter = 2 while True: candidate = _('%(stem)s (%(counter)s)', stem=stem, counter=counter) if extension: candidate = '%s.%s' % (candidate, extension) if candidate not in used_filenames: used_filenames.add(candidate) return candidate counter += 1