How to set PDF name in qWeb report, Odoo?
Asked Answered
J

8

7

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 file was saved, but in "generation" time).

Is that possible? If it is, how to do it?

Thanks in advance.

Joannjoanna answered 27/5, 2015 at 14:28 Comment(0)
I
3

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:

<?xml version="1.0" encoding="UTF-8"?>
<openerp>
  <data>
    <!-- rename the file names of the standard rfq report -->
        <record id="purchase.report_purchase_quotation" model="ir.actions.report.xml">
            <field name="attachment">'RFQ_'+object.name+'.pdf'</field>
        </record>    
   </data>
</openerp> 

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  
Inaccuracy answered 22/8, 2015 at 5:47 Comment(0)
S
3

you can use 'custom file name' module

  1. Download module
  2. https://www.odoo.com/apps/modules/8.0/report_custom_filename/
  3. Change name in setting - > action -> report

select your report and change the name ..

Shorthand answered 11/3, 2016 at 12:42 Comment(0)
V
2

In General Qweb Report the Menu you can print your Qweb Report in Odoo 8.0

<?xml version="1.0" encoding="utf-8"?>
<openerp>
    <data>
        <report 
            id="report_sale_order"
            string="Quotation / Order"
            model="sale.order" 
            report_type="qweb-pdf"
            file="sale.report_saleorder" 
            name="sale.report_saleorder" 
        />
    </data>
</openerp>

In <report> Tag has the different attributes for print the report in Qweb If you want to change the name of your printed PDF then the name Attribute is more important for us.

Based on the name attribute our report PDF File name comes over hear in generalize one you should set the name attribute base on your_module_name.report_name

If you want to change your customize name of your PDF File then change the name attribute as per your sweet report name.

I hope this should helpful for you ..:)

Veg answered 27/5, 2015 at 16:37 Comment(2)
Thanks. Really it helps, but I need to print 'every' PDF with a customized name. For example: I want to print every task with the name it has in database. So, any help?Joannjoanna
May be its possible but i do not know about it if I found in future then definitely ask it to you.Veg
R
2

addons\report\controllers\main.py

Line : 127

response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % reportname)

change it with

invoicename="ma_facture" #create a variable you can add date for example stfftime("%d-%m-%Y")
response.headers.add('Content-Disposition', 'attachment; filename=%s.pdf;' % invoicename)
Radome answered 2/9, 2015 at 13:19 Comment(6)
Hello Usman Maqbool, I approved your last edit suggestion. I would like to suggest that, when editing, you don't put the names of programming languages in code markdown, and remove the "Thanks" from posts. Kind regards!Upbeat
@S.L. Barth now please remove ban and i got my mistake...please.Radome
Only moderators can give or remove edit bans. They are normally temporary though. You'll have to wait until it is over. You might be interested in the discussions about it on Meta Stack Overflow, although to be fair I don't think they'll help much.Upbeat
yes I have seen this link but this is not helpful for my case. Do you have any idea that how much time it takes to over the bans?Radome
That information should be given with the edit ban. I'd have to look up to know for certain, but I think the first time is 2 days. A second ban is 7 days, and then a month. But again - I'd have to look that up.Upbeat
I am not getting any info regarding number of days blocked and I am blocked first time and its more than 2 days.Radome
D
2

I think this was a bug which was fixed in version 9. Simply replace the contents of addons\report\controllers\main.py with this https://github.com/odoo/odoo/blob/9.0/addons/report/controllers/main.py and then restart the odoo server

Duodecimal answered 14/10, 2015 at 12:32 Comment(0)
S
2
<report 
      id="report_sale_order"
      string="Quotation / Order"
      model="sale.order" 
      report_type="qweb-pdf"
      file="sale.report_saleorder" 
      name="sale.report_saleorder" 
/>

is correct for string name is a print PDF name done

Suellensuelo answered 4/12, 2015 at 6:28 Comment(0)
J
2

You can give dynamic report name using configuration, but it will apply when you print one report.

Below is the example to Print custom name in report.Create one field in ir.actions.report.xml, in which user can configure report name.

from openerp import models, fields
class IrActionsReportXml(models.Model):
    _inherit = 'ir.actions.report.xml'

    download_filename = fields.Char(
        'Download filename')

Now you need to create two files.

  1. Report Controller

    from openerp import http
    from openerp.addons.mail.models import mail_template
    from openerp.addons.report.controllers.main import ReportController
    from openerp.addons.web.controllers.main import content_disposition
    
    
    class ReportController(ReportController):
        @http.route([
            '/report/<path:converter>/<reportname>',
            '/report/<path:converter>/<reportname>/<docids>',
        ])
        def report_routes(self, reportname, docids=None, converter=None, **data):
            response = super(ReportController, self).report_routes(
                reportname, docids=docids, converter=converter, **data)
            if docids:
                docids = [int(i) for i in docids.split(',')]
            report_xml = http.request.session.model('ir.actions.report.xml')
            report_ids = report_xml.search(
                [('report_name', '=', reportname)])
            for report in report_xml.browse(report_ids):
                if not report.download_filename:
                    continue
                objects = http.request.session.model(report.model)\
                    .browse(docids or [])
                generated_filename = mail_template.mako_template_env\
                    .from_string(report.download_filename)\
                    .render({
                        'objects': objects,
                        'o': objects[:1],
                        'object': objects[:1],
                        'ext': report.report_type.replace('qweb-', ''),
                    })
                response.headers['Content-Disposition'] = content_disposition(
                    generated_filename)
            return response
    
        @http.route(['/report/download'])
        def report_download(self, data, token):
            response = super(ReportController, self).report_download(data, token)
            # if we got another content disposition before, ditch the one added
            # by super()
            last_index = None
            for i in range(len(response.headers) - 1, -1, -1):
                if response.headers[i][0] == 'Content-Disposition':
                    if last_index:
                        response.headers.pop(last_index)
                    last_index = i
            return response
    

2.Report.py

    import json
    from openerp import http
    from openerp.addons.web.controllers import main
    from openerp.addons.mail.models import mail_template


    class Reports(main.Reports):
        @http.route('/web/report', type='http', auth="user")
        @main.serialize_exception
        def index(self, action, token):
            result = super(Reports, self).index(action, token)
            action = json.loads(action)
            context = dict(http.request.context)
            context.update(action["context"])
            report_xml = http.request.env['ir.actions.report.xml']
            reports = report_xml.search([
                ('report_name', '=', action['report_name']),
                ('download_filename', '!=', False)])
            for report in reports:
                objects = http.request.session.model(context['active_model'])\
                    .browse(context['active_ids'])
                generated_filename = mail_template.mako_template_env\
                    .from_string(report.download_filename)\
                    .render({
                        'objects': objects,
                        'o': objects[0],
                        'object': objects[0],
                    })
                result.headers['Content-Disposition'] = main.content_disposition(
                    generated_filename)
            return result

Odoo community Providing us a default module for report custom name. you can directly install this module and set report name like : ${o.name}

Here o means your record.

Below is a link of odoo community module for V8 and V9.

https://www.odoo.com/apps/modules/9.0/report_custom_filename/

https://www.odoo.com/apps/modules/8.0/report_custom_filename/ This may help you.

Johnsson answered 4/4, 2017 at 4:21 Comment(0)
P
1

Easy Way to change report PDF file name in Odoo v10:

Just add this code where you write the report tag, and give same ID in both, report and new added record. Like the following:

<report id="report_quote_temp" string="Quote Template" model="sale.order" report_type="qweb-pdf"
    file="custom_template.report_quote_custom" name="custom_template.report_quote_custom"
    menu="True" paperformat="custom_template.custom_paperformat" />

<record id="report_quote_temp" model="ir.actions.report.xml">
    <field name="print_report_name">'SALES_'+object.name+'.pdf'</field>
</record>

It will print the report file as SALES_SO004.pdf, where SO004 is your sale or quotation number.

Phrasing answered 31/1, 2018 at 6:36 Comment(1)
This is the best solution of all, no need module installed. Works on Version 17.0 tested on 19 Jun 2024. ThanksLai

© 2022 - 2024 — McMap. All rights reserved.