How to set PDF name in qWeb report, Odoo?

后端 未结 8 1879
灰色年华
灰色年华 2021-01-12 13:41

I\'m making reports using qWeb in Odoo 8. Those generated PDF files are saved with a \"default\" name. I would like to set a specific name to every generated file (not after

8条回答
  •  独厮守ぢ
    2021-01-12 14:21

    In Odoo 8 you can patch the method report_download of addons/report/controllers/main.py like below (between FIX START and END). It will then use the code for the attachment attribute in the report action definition. As the system will then always also save the file as an attachment in the database you can change the behaviour further to only save in the database when attachment_use is set to True. In this way no extra fields need to be added and views changed.

    @route(['/report/download'], type='http', auth="user")
    def report_download(self, data, token):
        """This function is used by 'qwebactionmanager.js' in order to trigger the download of
        a pdf/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
        """
        requestcontent = simplejson.loads(data)
        url, type = requestcontent[0], requestcontent[1]
        try:
            if type == 'qweb-pdf':
                reportname = url.split('/report/pdf/')[1].split('?')[0]
    
                docids = None
                if '/' in reportname:
                    reportname, docids = reportname.split('/')
    
                if docids:
                    # Generic report:
                    response = self.report_routes(reportname, docids=docids, converter='pdf')
                    ##### FIX START: switch reportname with the evaluated attachment attribute of the action if available
                    docids = [int(i) for i in docids.split(',')]
                    report_obj = request.registry['report']
                    cr, uid, context = request.cr, request.uid, request.context
                    report = report_obj._get_report_from_name(cr, uid, reportname)
                    if report.attachment:
                        obj = report_obj.pool[report.model].browse(cr, uid, docids[0])
                        reportname=eval(report.attachment, {'object': obj, 'time': time}).split('.pdf')[0]
                    ##### FIX END    
                else:
                    # Particular report:
                    data = url_decode(url.split('?')[1]).items()  # decoding the args represented in JSON
                    response = self.report_routes(reportname, converter='pdf', **dict(data))
    
                response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)
                response.set_cookie('fileToken', token)
                return response
            elif type =='controller':
                reqheaders = Headers(request.httprequest.headers)
                response = Client(request.httprequest.app, BaseResponse).get(url, headers=reqheaders, follow_redirects=True)
                response.set_cookie('fileToken', token)
                return response
            else:
                return
        except Exception, e:
            se = _serialize_exception(e)
            error = {
                'code': 200,
                'message': "Odoo Server Error",
                'data': se
            }
            return request.make_response(html_escape(simplejson.dumps(error))) 
    

    You can set the attachment attribute of a report action for example in this way:

    
    
      
        
            
                'RFQ_'+object.name+'.pdf'
                
       
     
    

    This is the patch of _check_attachment of the Report object in addons/report/report.py to modify the attachment_use behaviour:

    @api.v7
    def _check_attachment_use(self, cr, uid, ids, report):
        """ Check attachment_use field. If set to true and an existing pdf is already saved, load
        this one now. Else, mark save it.
        """
        save_in_attachment = {}
        save_in_attachment['model'] = report.model
        save_in_attachment['loaded_documents'] = {}
    
        if report.attachment:
            for record_id in ids:
                obj = self.pool[report.model].browse(cr, uid, record_id)
                filename = eval(report.attachment, {'object': obj, 'time': time})
    
                # If the user has checked 'Reload from Attachment'
                if report.attachment_use:
                    alreadyindb = [('datas_fname', '=', filename),
                                   ('res_model', '=', report.model),
                                   ('res_id', '=', record_id)]
                    attach_ids = self.pool['ir.attachment'].search(cr, uid, alreadyindb)
                    if attach_ids:
                        # Add the loaded pdf in the loaded_documents list
                        pdf = self.pool['ir.attachment'].browse(cr, uid, attach_ids[0]).datas
                        pdf = base64.decodestring(pdf)
                        save_in_attachment['loaded_documents'][record_id] = pdf
                        _logger.info('The PDF document %s was loaded from the database' % filename)
    
                        continue  # Do not save this document as we already ignore it
    
                # FIX START (commenting out below lines and indenting the else clause one level down)
                # If the user has checked 'Save as Attachment Prefix'
                #~ if filename is False:
                    #~ # May be false if, for instance, the 'attachment' field contains a condition
                    #~ # preventing to save the file.
                    #~ continue
                    else:
                        save_in_attachment[record_id] = filename  # Mark current document to be saved
                # FIX END
        return save_in_attachment  
    

提交回复
热议问题