def create_pdf(self, doc_jasper_rc, res_id, wiz): today = fields.Datetime.now() xml_report_obj = self.env['ir.actions.report.xml'] context = self.env.context.copy() if not context: context = {} if doc_jasper_rc: xml_report_to_print_id = doc_jasper_rc.report_id or False if xml_report_to_print_id: report_data = xml_report_to_print_id.read(['model', 'report_name']) netsvc.LocalService('report.' + report_data[0]['report_name']) datas = {'ids': res_id, 'model': 'pricelist.supplierinfo'} if context and 'jasper' in context: datas['jasper'] = context['jasper'] (print_commands, format) = report.render_report(self.env.cr, self.env.user.id, res_id, report_data[0]['report_name'], datas, context=context) attachments = {} name_partner = wiz.partner_id and (wiz.partner_id.reference or wiz.partner_id.name) or doc_jasper_rc.name name_report = '%s_%s.%s'%(name_partner,today,format) attachments[name_report] = print_commands report_binary = False for fname, fcontent in attachments.iteritems(): report_binary = fcontent and fcontent.encode('base64') return (print_commands, format),report_data[0]['report_name'],report_binary,name_report return (False, False), False, False, ''
def export_zip_invoices(self, data, token): data = json.loads(data) in_memory_zip = StringIO.StringIO() zf = zipfile.ZipFile(in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) rows = data.get('rows', []) rows = [int(x) for x in rows] for row in rows: account_obj = request.env['account.invoice'].browse(row) (result, format) = render_report(request.cr, request.uid, [account_obj.id], 'fatturadiff', data) filename = account_obj.number.replace('/', '') if not filename: filename = 'invoice_' + str(row) zf.writestr(filename + '.' + format.encode("utf-8"), result) zf.close() in_memory_zip.seek(0) data = in_memory_zip.read() return request.make_response( data, headers=[('Content-Disposition', 'attachment; filename="%s"' % 'invoices.zip'), ('Content-Type', 'application/zip')], cookies={'fileToken': token})
def _compute_documents_list(self, cr, uid, invoice_ids, report_name=None, context=None): slip_model = self.pool['l10n_ch.payment_slip'] invoice_model = self.pool['account.invoice'] for inv in invoice_model.browse(cr, uid, invoice_ids, context=context): data, format = render_report( cr, uid, [inv.id], 'account.report_invoice', {}, context=context, ) yield data slips = slip_model.compute_pay_slips_from_invoices(cr, uid, inv, context=context) for slip in slips: yield slip._draw_payment_slip(a4=True, b64=False, report_name=report_name, out_format='PDF')
def get_pdf(self, cr, uid, ids, report_name, html=None, data=None, context=None): if context is None: context = {} if data is None: data = {} report = self._get_report_from_name(cr, SUPERUSER_ID, report_name) if report.report_type == 'aeroo': data.update({ 'report_type': 'aeroo', 'model': report.model, }) pdf = render_report(cr, SUPERUSER_ID, ids, report_name, data, context) if pdf: return pdf[0] return False else: return super(Report, self).get_pdf( cr, uid, ids, report_name, html=html, data=data, context=context )
def get_pdf_from_report(cr, uid, service_name, dictionary, context=None): ''' Returns a PDF encoded in base64. This is deprecated, and is provided only for backwards compatibility: use instead openerp.report.render_report() @param service_name: The name of the service that generates the PDF. @type service_name: string, e.g. 'report.invoice'. @param dictionary: Dictionary containing keys 'ids' and 'model'. @type dictionary: dict. @rtype: base64. PDF file encoded in base64. ''' logger.warning( 'get_pdf_from_report() is deprecated. Port your code to use render_report().' ) ids_list = dictionary['ids'] if not isinstance(dictionary['ids'], list): ids_list = [dictionary['ids']] pdf_data, _ = render_report(cr, uid, ids_list, service_name, {'model': dictionary['model']}, context=context) return base64.b64encode(pdf_data)
def get_public_cpe(self): self.ensure_one() res = {} (result_pdf, result_format)=report.render_report(self._cr, self._uid, self.ids, 'l10n_pe_einvoice.report_invoice', self._context) res['datas_sign'] =self.batch_pe_id.emessage_ids[0].xml_sign_datas res['datas_response'] =self.batch_pe_id.emessage_ids[0].zip_datas res['datas_invoice'] = result_pdf.encode('base64') res['name'] = "%s-%s" %(self.company_id and self.company_id.vat[2:] or "", self.batch_pe_id.name or "cpe") return res
def _process_wi_report(self, cr, uid, activity, workitem, context=None): report_data, format = render_report(cr, uid, [], activity.report_id.report_name, {}, context=context) attach_vals = { "name": "%s_%s_%s" % (activity.report_id.report_name, activity.name, workitem.partner_id.name), "datas_fname": "%s.%s" % (activity.report_id.report_name, activity.report_id.report_type), "parent_id": activity.report_directory_id.id, "datas": base64.encodestring(report_data), "file_type": format, } self.pool.get("ir.attachment").create(cr, uid, attach_vals) return True
def _process_wi_report(self, cr, uid, activity, workitem, context=None): report_data, format = render_report(cr, uid, [], activity.report_id.report_name, {}, context=context) attach_vals = { 'name': '%s_%s_%s'%(activity.report_id.report_name, activity.name,workitem.partner_id.name), 'datas_fname': '%s.%s'%(activity.report_id.report_name, activity.report_id.report_type), 'datas': base64.encodestring(report_data), } self.pool.get('ir.attachment').create(cr, uid, attach_vals) return True
def test_print_report(self): invoice = self.make_invoice() data, format = render_report( self.env.cr, self.env.uid, [invoice.id], 'one_slip_per_page_from_invoice', {}, context={'force_pdf': True}, ) self.assertTrue(data) self.assertEqual(format, 'pdf')
def test_print_multi_report_merge_on_disk(self): self.env.user.company_id.merge_mode = 'on_disk' invoice1 = self.make_invoice() invoice2 = self.make_invoice() data, format = render_report( self.env.cr, self.env.uid, [invoice1.id, invoice2.id], 'l10n_ch_payment_slip.one_slip_per_page_from_invoice', {}, context={'force_pdf': True}, ) self.assertTrue(data) self.assertEqual(format, 'pdf')
def create_invoice_zip(self): invoice_ids = self.env.context.get('active_ids') in_memory_zip = StringIO.StringIO() zf = zipfile.ZipFile(in_memory_zip, "a", zipfile.ZIP_DEFLATED, False) data = {"model": "account.invoice", "rows": ["1557", "1558", "1559"]} lista = "" for record in invoice_ids: account_obj = self.env['account.invoice'].browse(record) (result, format) = render_report(self._cr, self._uid, [account_obj.id], self.invoice_report.report_name, data) filename = account_obj.number.replace('/', '') lista += filename + "\n" if not filename: filename = 'invoice_' + str(record) zf.writestr(filename + '.' + format.encode("utf-8"), result) zf.close() in_memory_zip.seek(0) data = in_memory_zip.read() self.filedata = base64.encodestring(data) print lista self.filename = filename mod_obj = self.pool.get('ir.model.data') result = mod_obj.get_object_reference(self._cr, self._uid, 'account_invoice_zip', 'zip_invoice_form_view') view_id = result and result[1] or False obj_id = self.env['invoice.zip'].create({ 'filename': 'Invoice_Zip.zip', 'filedata': self.filedata, 'type': self.invoice_report.name, 'element': lista }) return { 'name': ('Invoice Zip'), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'invoice.zip', 'type': 'ir.actions.act_window', 'target': 'current', 'view_id': view_id, 'views': [(view_id, 'form'), (False, 'tree')], 'res_id': obj_id.id }
def create_report(self, res_ids, report_name=False, file_name=False, data=False): if not report_name or not res_ids: return ( False, Exception('Report name and Resources ids are required !!!')) try: ret_file_name = '/tmp/%s.pdf' % file_name (result, format) = render_report(self._cr, self._uid, res_ids, report_name, data) fp = open(ret_file_name, 'wb+') fp.write(result) fp.close() except Exception, e: print 'Exception in create report:', e return False, str(e)
def action_invoice_sent(self): res = super(account_invoice, self).action_invoice_sent() self.ensure_one() if self.journal_id.is_einvoice_pe and self.batch_pe_id: template = self.env.ref( 'l10n_pe_einvoice.email_template_edi_einvoice', False) attach = {} name = self.batch_pe_id.emessage_ids[ 0].xml_fname and self.batch_pe_id.emessage_ids[ 0].xml_fname.split('.')[0] or self.number attach['name'] = "%s.xml" % name attach['type'] = "binary" attach['datas'] = self.batch_pe_id.emessage_ids[0].xml_sign_datas attach['datas_fname'] = "%s.xml" % name attach['res_model'] = "mail.compose.message" attachment_id = self.env['ir.attachment'].create(attach) attachment_ids = [] attachment_ids.append(attachment_id.id) attach = {} (result_pdf, result_format) = report.render_report( self._cr, self._uid, self.ids, 'l10n_pe_einvoice.report_invoice', self._context) attach['name'] = "%s.pdf" % name attach['type'] = "binary" attach['datas'] = result_pdf.encode('base64') attach['datas_fname'] = "%s.pdf" % name attach['res_model'] = "mail.compose.message" attachment_id = self.env['ir.attachment'].create(attach) attachment_ids.append(attachment_id.id) vals = {} vals['default_use_template'] = bool(template) vals['default_template_id'] = template and template.id or False vals['default_attachment_ids'] = [(6, 0, attachment_ids)] res['context'].update(vals) return res
def create_pdf(self, jasper_id, res_ids, user_id): ctx = self.env.context.copy() res = False jasper_obj = self.env['jasper.document'] report_obj = self.env['ir.actions.report.xml'] xml_report_to_print_id = jasper_obj.browse(jasper_id).read( ['report_id'], load='_classic_write')[0]['report_id'] if xml_report_to_print_id: # Retrieve data to generate the report report_data = report_obj.browse(xml_report_to_print_id).read( ['model', 'report_name'])[0] datas = {'ids': res_ids, 'model': report_data['model']} if ctx and 'jasper' in ctx: datas['jasper'] = ctx['jasper'] # Generate the file to print res = report.render_report(self.env.cr, user_id, res_ids, report_data['report_name'], datas, context=ctx), report_data['report_name'] return res
def generate_email(self, res_ids, fields=None): """Generates an email from the template for given the given model based on records given by res_ids. :param template_id: id of the template to render. :param res_id: id of the record to use for rendering the template (model is taken from template definition) :returns: a dict containing all relevant fields for creating a new mail.mail entry, with one extra key ``attachments``, in the format [(report_name, data)] where data is base64 encoded. """ self.ensure_one() multi_mode = True if isinstance(res_ids, (int, long)): res_ids = [res_ids] multi_mode = False if fields is None: fields = ['subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to'] res_ids_to_templates = self.get_email_template_batch(res_ids) # templates: res_id -> template; template -> res_ids templates_to_res_ids = {} for res_id, template in res_ids_to_templates.iteritems(): templates_to_res_ids.setdefault(template, []).append(res_id) results = dict() for template, template_res_ids in templates_to_res_ids.iteritems(): Template = self.env['mail.template'] # generate fields value for all res_ids linked to the current template if template.lang: Template = Template.with_context(lang=template._context.get('lang')) for field in fields: generated_field_values = Template.render_template( getattr(template, field), template.model, template_res_ids, post_process=(field == 'body_html')) for res_id, field_value in generated_field_values.iteritems(): results.setdefault(res_id, dict())[field] = field_value # compute recipients if any(field in fields for field in ['email_to', 'partner_to', 'email_cc']): results = template.generate_recipients(results, template_res_ids) # update values for all res_ids for res_id in template_res_ids: values = results[res_id] # body: add user signature, sanitize if 'body_html' in fields and template.user_signature: signature = self.env.user.signature if signature: values['body_html'] = tools.append_content_to_html(values['body_html'], signature, plaintext=False) if values.get('body_html'): values['body'] = tools.html_sanitize(values['body_html']) # technical settings values.update( mail_server_id=template.mail_server_id.id or False, auto_delete=template.auto_delete, model=template.model, res_id=res_id or False, attachment_ids=[attach.id for attach in template.attachment_ids], ) # Add report in attachments: generate once for all template_res_ids if template.report_template: for res_id in template_res_ids: attachments = [] report_name = self.render_template(template.report_name, template.model, res_id) report = template.report_template report_service = report.report_name if report.report_type in ['qweb-html', 'qweb-pdf']: result, format = self.pool['report'].get_pdf(self._cr, self._uid, [res_id], report_service, context=Template._context), 'pdf' else: result, format = odoo_report.render_report(self._cr, self._uid, [res_id], report_service, {'model': template.model}, Template._context) # TODO in trunk, change return format to binary to match message_post expected format result = base64.b64encode(result) if not report_name: report_name = 'report.' + report_service ext = "." + format if not report_name.endswith(ext): report_name += ext attachments.append((report_name, result)) results[res_id]['attachments'] = attachments return multi_mode and results or results[res_ids[0]]
def _command(self, print_type, print_data, pdf_to_merge=None): """ Print a file on the selected CUPS server TODO : When available from pycups to print stdin data, rewrite the temp file part :param self: Liste des PDF à ajouter :type self: liste """ # Retrieve printer printer = self try: connection = printer.server_id._openConnection() except: pass raise except_orm( _('Error'), _('Connection to the CUPS server failed\nCups server : %s (%s:%s)' ) % (printer.server_id.server, printer.server_id.address, printer.server_id.port)) # Define printing options options = {} # Add the fitplot option if printer.fitplot: options['fitplot'] = 'fitplot' filename = None delete_file = False if print_type == 'report': # Retrieve data to generate the report report_obj = self.env['ir.actions.report.xml'] report_data = report_obj.browse(print_data['report_id']).read( ['model', 'report_name'])[0] datas = { 'ids': print_data['print_ids'], 'model': report_data['model'] } # Log the command to send logger.info('Object to print : %s (%s)' % (datas['model'], repr(datas['ids'][0]))) logger.info('Report to print : %s (%s)' % (report_data['report_name'], print_data['report_id'])) # The commit is necessary for Jasper find the data in PostgreSQL self.env.cr.commit() # Generate the file to print report_dict = self.env['report'].get_action( self.env[datas['model']].browse(print_data['print_ids']), report_data['report_name']) #On récupère les PDF en plus s'il y en a pour les passer dans le context de la méthode render_report context2 = self.env.context.copy() if pdf_to_merge: context2['pdf_to_merge'] = pdf_to_merge data_report = {'model': datas['model']} if 'data_jasper' in context2 and context2['data_jasper']: data_report['jasper'] = context2['data_jasper'] try: (data, format) = report.render_report(self.env.cr, self.env.uid, print_data['print_ids'], report_data['report_name'], data_report, context=context2) fd, filename = mkstemp(suffix='.' + format, prefix='printers-') os.write(fd, data) os.close(fd) delete_file = True except: raise except_orm( 'Error', 'Please check the connection of your printers and their reporting' ) elif print_type == 'file': filename = print_data['filename'] elif print_type == 'raw': # Define the raw option for cups # options['raw'] = 'raw' # Write the data into a file fd, filename = mkstemp(suffix='.', prefix='printers-raw') os.write(fd, print_data) os.close(fd) delete_file = True else: pass # raise osv.except_osv(_('Error'), _('Unknown command type, unable to print !')) # TODO : Rewrite using the cupsCreateJob/cupsStartDocument/cupsWriteRequestData/cupsFinishDocument functions, when available in pycups, instead of writing data into a temporary file jobid = False try: jobid = connection.printFile( printer.code, filename, self.env.context.get('jobname', 'Open-Prod'), options) except: raise except_orm( 'Error', 'Please check the connection of your printers and their reporting' ) finally: # Remove the file and free the memory if delete_file: os.remove(filename) # Operation successful, return True logger.info('Printers Job ID : %d' % jobid) printer.server_id._update_jobs(which='all', first_job_id=jobid) return jobid
def do_print_wo(self, print_plan=False, print_plan_mo=False): """ Fonction permettant d'imprimer le work order ainsi que les plans liés à la ligne de gamme du work order """ super(mrp_workorder, self).do_print_wo() printer_list = {} printer_report_ids = {} data_obj = self.env['ir.model.data'] report_object = self.env['printers.report'] user = self.env.user #On récupère les imprimantes entrées dans les préférences utilisateur if user.context_printer_id: user.context_printer_id.type_id and printer_list.update( {user.context_printer_id.type_id.id: user.context_printer_id}) if user.context_printer_medium_id: user.context_printer_medium_id.type_id and printer_list.update({ user.context_printer_medium_id.type_id.id: user.context_printer_medium_id }) if user.context_printer_small_id: user.context_printer_small_id.type_id and printer_list.update({ user.context_printer_small_id.type_id.id: user.context_printer_small_id }) if user.context_printer_4_id: user.context_printer_4_id.type_id and printer_list.update({ user.context_printer_4_id.type_id.id: user.context_printer_4_id }) if user.context_printer_5_id: user.context_printer_5_id.type_id and printer_list.update({ user.context_printer_5_id.type_id.id: user.context_printer_5_id }) for wo in self: report_id = False printer_id = False object_model = False key = () pdf_to_merge = [] #On recherche le rapport associé au work order object_model, object_id = data_obj.get_object_reference( 'printers_mrp', 'report_work_order') #On récupère le report du work order, en vérifiant qu'il est actif. if object_model and object_model == 'printers.report': printer_report = report_object.browse(object_id) if printer_report.active_report == True: printer_type = printer_report.printer_type_id.id report_id = printer_report.report_id.id #On sélectionne l'imprimante choisie par l'utilisateur for type, printer in printer_list.items(): if type == printer_type: printer_id = printer break if not printer_id: raise except_orm( _('Error'), _('No printer found for the work order %s.') % (wo.name)) else: key = (report_id, printer_id) if key in printer_report_ids: printer_report_ids[key]['work_order'].append(wo.id) else: printer_report_ids[key] = {'work_order': [wo.id]} #Si on ne récupère aucun report, on envoie un message d'erreur if not report_id: raise except_orm( _('Error'), _('No active report found for this work order %s.') % (wo.name)) # Impression des plans dans les Ots if print_plan and wo.rl_document_ids: for document in wo.rl_document_ids: if document.attachment: datas = StringIO() datas.write(base64.decodestring(document.attachment)) pdf_to_merge.append(datas) # Impression des plans dans les OFs if print_plan_mo and wo.mo_id.internal_plan_ids: for document in wo.mo_id.internal_plan_ids: if document.attachment: datas = StringIO() datas.write(base64.decodestring(document.attachment)) pdf_to_merge.append(datas) #Gestion des documents jasper product_id = wo.mo_id.product_id.id printed_doc_list = self.env['stock.quality.control'].search([ ('product_id', '=', product_id), ('type', '=', 'jasper_production'), ('report_id', '!=', False) ]) for printed_doc in printed_doc_list: (data, report_format) = report.render_report( self.env.cr, self.env.uid, [printed_doc.id], printed_doc.report_id.report_name, {'model': 'stock.quality.control'}) if report_format == 'PDF': datas = StringIO() datas.write(data) pdf_to_merge.append(datas) #Si on a récupéré aucune imprimante, on récupère la première de la liste des préférences des #utilisateurs if not printer_id: for type, printer in printer_list.items(): printer_id = printer break if not printer_id: raise except_orm(_('Error'), _('No printer found in your preference')) if printer_report_ids and pdf_to_merge: printer_report_ids[key]['pdf_to_merge'] = pdf_to_merge #Lancement des impressions for k, v in printer_report_ids.items(): k[1].send_printer(k[0], v['work_order'], v.get('pdf_to_merge', [])) return True
def generate_email(self, cr, uid, template_id, res_id, context=None): """Generates an email from the template for given (model, res_id) pair. :param template_id: id of the template to render. :param res_id: id of the record to use for rendering the template (model is taken from template definition) :returns: a dict containing all relevant fields for creating a new mail.mail entry, with one extra key ``attachments``, in the format expected by :py:meth:`mail_thread.message_post`. """ if context is None: context = {} report_xml_pool = self.pool.get('ir.actions.report.xml') template = self.get_email_template(cr, uid, template_id, res_id, context) values = {} for field in [ 'subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'email_bcc', 'reply_to' ]: values[field] = self.render_template(cr, uid, getattr(template, field), template.model, res_id, context=context) \ or False if template.user_signature: signature = self.pool.get('res.users').browse( cr, uid, uid, context).signature values['body_html'] = tools.append_content_to_html( values['body_html'], signature) if values['body_html']: values['body'] = tools.html_sanitize(values['body_html']) values.update(mail_server_id=template.mail_server_id.id or False, auto_delete=template.auto_delete, model=template.model, res_id=res_id or False) attachments = [] # Add report in attachments if template.report_template: report_name = self.render_template(cr, uid, template.report_name, template.model, res_id, context=context) report_service = report_xml_pool.browse( cr, uid, template.report_template.id, context).report_name # Ensure report is rendered using template's language ctx = context.copy() if template.lang: ctx['lang'] = self.render_template(cr, uid, template.lang, template.model, res_id, context) #service = netsvc.LocalService(report_service) (result, format) = report.render_report(cr, uid, [res_id], report_service, {'model': template.model}, ctx) #(result, format) = service.create(cr, uid, [res_id], {'model': template.model}, ctx) result = base64.b64encode(result) if not report_name: report_name = report_service ext = "." + format if not report_name.endswith(ext): report_name += ext attachments.append((report_name, result)) attachment_ids = [] # Add template attachments for attach in template.attachment_ids: attachment_ids.append(attach.id) values['attachments'] = attachments values['attachment_ids'] = attachment_ids return values
def generate_email(self, res_ids, fields=None): """Generates an email from the template for given the given model based on records given by res_ids. :param template_id: id of the template to render. :param res_id: id of the record to use for rendering the template (model is taken from template definition) :returns: a dict containing all relevant fields for creating a new mail.mail entry, with one extra key ``attachments``, in the format [(report_name, data)] where data is base64 encoded. """ self.ensure_one() multi_mode = True if isinstance(res_ids, (int, long)): res_ids = [res_ids] multi_mode = False if fields is None: fields = [ 'subject', 'body_html', 'email_from', 'email_to', 'partner_to', 'email_cc', 'reply_to', 'scheduled_date' ] res_ids_to_templates = self.get_email_template_batch(res_ids) # templates: res_id -> template; template -> res_ids templates_to_res_ids = {} for res_id, template in res_ids_to_templates.iteritems(): templates_to_res_ids.setdefault(template, []).append(res_id) results = dict() for template, template_res_ids in templates_to_res_ids.iteritems(): Template = self.env['mail.template'] # generate fields value for all res_ids linked to the current template if template.lang: Template = Template.with_context( lang=template._context.get('lang')) for field in fields: generated_field_values = Template.render_template( getattr(template, field), template.model, template_res_ids, post_process=(field == 'body_html')) for res_id, field_value in generated_field_values.iteritems(): results.setdefault(res_id, dict())[field] = field_value # compute recipients if any(field in fields for field in ['email_to', 'partner_to', 'email_cc']): results = template.generate_recipients(results, template_res_ids) # update values for all res_ids for res_id in template_res_ids: values = results[res_id] # body: add user signature, sanitize if 'body_html' in fields and template.user_signature: signature = self.env.user.signature if signature: values['body_html'] = tools.append_content_to_html( values['body_html'], signature, plaintext=False) if values.get('body_html'): values['body'] = tools.html_sanitize(values['body_html']) # technical settings values.update( mail_server_id=template.mail_server_id.id or False, auto_delete=template.auto_delete, model=template.model, res_id=res_id or False, attachment_ids=[ attach.id for attach in template.attachment_ids ], ) # Add report in attachments: generate once for all template_res_ids if template.report_template: for res_id in template_res_ids: attachments = [] report_name = self.render_template(template.report_name, template.model, res_id) report = template.report_template report_service = report.report_name if report.report_type in ['qweb-html', 'qweb-pdf']: result, format = self.pool['report'].get_pdf( self._cr, self._uid, [res_id], report_service, context=Template._context), 'pdf' else: result, format = odoo_report.render_report( self._cr, self._uid, [res_id], report_service, {'model': template.model}, Template._context) # TODO in trunk, change return format to binary to match message_post expected format result = base64.b64encode(result) if not report_name: report_name = 'report.' + report_service ext = "." + format if not report_name.endswith(ext): report_name += ext attachments.append((report_name, result)) results[res_id]['attachments'] = attachments return multi_mode and results or results[res_ids[0]]
def do_print_label(self, send_printer_list=None, send_printer_id=None): """ Fonction permettant de retrouver l'imprimante pour chaque étiquettes et de lancer l'impression :type self: stock.label :param send_printer_list: Dictionnaire contenant la liste des imprimantes de l'utilisateur :type send_printer_list: dict :param send_printer_id: id de l'imprimante envoyée :type send_printer_id: integer :return: True ou liste datas des étiquettes :rtype: bool """ printer_list = {} printer_report_label_ids = {} user = self.env.user pdf_to_merge = [] #On récupère les imprimantes entrées dans les préférences utilisateur if send_printer_list: printer_list = send_printer_list else: if user.context_printer_id: user.context_printer_id.type_id and printer_list.update({ user.context_printer_id.type_id.id: user.context_printer_id }) if user.context_printer_medium_id: user.context_printer_medium_id.type_id and printer_list.update( { user.context_printer_medium_id.type_id.id: user.context_printer_medium_id }) if user.context_printer_small_id: user.context_printer_small_id.type_id and printer_list.update({ user.context_printer_small_id.type_id.id: user.context_printer_small_id }) if user.context_printer_4_id: user.context_printer_4_id.type_id and printer_list.update({ user.context_printer_4_id.type_id.id: user.context_printer_4_id }) if user.context_printer_5_id: user.context_printer_5_id.type_id and printer_list.update({ user.context_printer_5_id.type_id.id: user.context_printer_5_id }) for label in self: printer_id = False key = () #Pour chaque étiquette, si le template a la case "report actif" de cochée, on récupère les informations if label.template_id.active_report: printer_type = label.template_id.printer_type_id.id report_rs = label.template_id.report_id report_id = report_rs and report_rs.id or False #On sélectionne l'imprimante choisie par l'utilisateur for type, printer in printer_list.items(): if type == printer_type: printer_id = printer break if not printer_id: raise except_orm( _('Error'), _('No printer found for the label %s.') % (label.name)) else: key = (report_id, printer_id) if (not send_printer_id) or (send_printer_id != printer_id): if key in printer_report_label_ids: printer_report_label_ids[key].append(label.id) else: printer_report_label_ids[key] = [label.id] elif send_printer_id and send_printer_id == printer_id: (data, report_format) = report.render_report( self.env.cr, self.env.uid, [label.id], report_rs.report_name, {'model': 'stock.label'}) if report_format == 'PDF': datas = StringIO() datas.write(data) pdf_to_merge.append(datas) #Lancement des impressions for k, v in printer_report_label_ids.items(): #On fait des listes des étiquettes (par 120) hashed_label_ids = hash_list(v, 120) for l_ids in hashed_label_ids: k[1].send_printer(k[0], l_ids) self.env.cr.execute( """UPDATE stock_adv_label SET print_nb = print_nb + 1, print_user_id = %s, print_date = %s WHERE id in %s""", ( self.env.cr.user.id, fields.Datetime.now(), tuple(l_ids), )) if pdf_to_merge: return pdf_to_merge else: return True
def do_print_picking(self): """ Fonction permettant d'imprimer le picking ainsi que les controles et plans liés aux produits du picking et les étiquettes liées aux moves (en fonction des booléens cochés) """ super(stock_picking, self).do_print_picking() printer_list = {} printer_report_ids = {} data_obj = self.env['ir.model.data'] report_object = self.env['printers.report'] plans_obj = self.env['stock.quality.control'] user = self.env.user #On récupère les imprimantes entrées dans les préférences utilisateur if user.context_printer_id: user.context_printer_id.type_id and printer_list.update( {user.context_printer_id.type_id.id: user.context_printer_id}) if user.context_printer_medium_id: user.context_printer_medium_id.type_id and printer_list.update({ user.context_printer_medium_id.type_id.id: user.context_printer_medium_id }) if user.context_printer_small_id: user.context_printer_small_id.type_id and printer_list.update({ user.context_printer_small_id.type_id.id: user.context_printer_small_id }) if user.context_printer_4_id: user.context_printer_4_id.type_id and printer_list.update({ user.context_printer_4_id.type_id.id: user.context_printer_4_id }) if user.context_printer_5_id: user.context_printer_5_id.type_id and printer_list.update({ user.context_printer_5_id.type_id.id: user.context_printer_5_id }) for picking in self: report_id = False printer_id = False object_model = False product_plans_jasper_type = '' key = () pdf_to_merge = [] #On regarde si au moins l'une des 3 cases est cochée, sinon on envoie un message d'erreur if not picking.print_picking_report and not picking.print_control and not picking.print_label: raise except_orm( _('Error'), _('You need to check at least one case in the printing part for the picking ' '%s (information tab).') % (picking.name)) #Pour chaque picking, on recherche le rapport associé en fonction de son type #et de l'option avec ou sans prix if picking.type == 'in': product_plans_jasper_type = 'jasper_receipt' object_model, object_id = data_obj.get_object_reference( 'printers_stock', 'report_receipt_order') elif picking.type == 'out': product_plans_jasper_type = 'jasper_delivery' if picking.report_type == 'with_price': object_model, object_id = data_obj.get_object_reference( 'printers_stock', 'report_delivery_order_with_price') elif picking.report_type == 'without_price' or not picking.report_type: object_model, object_id = data_obj.get_object_reference( 'printers_stock', 'report_delivery_order_without_price') #Lorsque la case d'impression du rapport du picking est cochée if picking.print_picking_report: if object_model and object_model == 'printers.report': printer_report = report_object.browse(object_id) if printer_report.active_report == True: printer_type = printer_report.printer_type_id.id report_id = printer_report.report_id.id #On sélectionne l'imprimante choisie par l'utilisateur for type, printer in printer_list.items(): if type == printer_type: printer_id = printer break if not printer_id: raise except_orm( _('Error'), _('No printer found for the picking %s.') % (picking.name)) else: key = (report_id, printer_id) if key in printer_report_ids: printer_report_ids[key]['picking'].append( picking.id) else: printer_report_ids[key] = {'picking': [picking.id]} # if not report_id: # raise except_orm(_('Error'), _('No active report found for this picking %s.') % (picking.name)) #Lorsque la case d'impression des plans et controles est cochée if picking.print_control: for document in picking.quality_control_ids: datas = StringIO() datas.write(base64.decodestring(document.attachment)) pdf_to_merge.append(datas) #On va chercher tous les controles et plans éventuels ramenés product_list = [x.product_id.id for x in picking.move_ids] plans_list = plans_obj.search([('product_id', 'in', product_list)]) for plan in plans_list: #S'il possède un report jasper, on crée le report, on vérifie qu'il soit bien sous format PDF et on l'ajoute #aux PDF à merger if plan.type == product_plans_jasper_type and plan.report_id: (data, report_format) = report.render_report( self.env.cr, self.env.uid, [plan.id], plan.report_id.report_name, {'model': 'stock.quality.control'}) if report_format == 'PDF': datas = StringIO() datas.write(data) pdf_to_merge.append(datas) #Si on a récupéré aucune imprimante, on récupère la première de la liste des préférences des #utilisateurs if not printer_id: for type, printer in printer_list.items(): printer_id = printer break if not printer_id: raise except_orm(_('Error'), _('No printer found in your preference')) #Si la case "Imprimer les étiquettes" est cochée dans le picking, on lance l'impression de toutes les étiquettes if picking.print_label: #On récupère toutes les étiquettes de tous les moves du picking label_rs = self.env['stock.label'] for move in picking.move_ids: for move_label in move.move_label_ids: label_rs += move_label.label_id #Si on a un report, ou déjà un pdf, on envoie l'id de l'imprimante à la méthode d'impression des étiquettes #Si pour une ou plusieurs étiquettes on trouve la même imprimante, on va merger le tout afin de ne créer qu'un seul #PDF. Sinon, on lance directement l'impression des étiquettes if report_id or pdf_to_merge: label_result = label_rs.do_print_label( printer_list, printer_id) if isinstance(label_result, list): pdf_to_merge += label_result else: label_rs.do_print_label(send_printer_list=printer_list, send_printer_id=False) if printer_report_ids and pdf_to_merge: printer_report_ids[key]['pdf_to_merge'] = pdf_to_merge #Si on a pas à imprimer le picking mais que l'on doit imprimer les plans et les controles, #on va aller chercher les PDF à imprimer. elif not printer_report_ids and pdf_to_merge: fo_pdf = StringIO() ret = PdfFileWriter() for current_pdf in pdf_to_merge: current_pdf.seek(0) tmp_pdf = PdfFileReader(current_pdf) for page in range(tmp_pdf.getNumPages()): ret.addPage(tmp_pdf.getPage(page)) ret.write(fo_pdf) printer_id.print_raw_data(fo_pdf.getvalue()) #Lancement des impressions for k, v in printer_report_ids.items(): k[1].send_printer(k[0], v['picking'], v.get('pdf_to_merge', [])) return True