Example #1
0
 def avatar(self, res_model, res_id, partner_id):
     headers = [('Content-Type', 'image/png')]
     status = 200
     content = 'R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=='  # default image is one white pixel
     if res_model in request.env:
         try:
             # if the current user has access to the document, get the partner avatar as sudo()
             request.env[res_model].browse(res_id).check_access_rule('read')
             if partner_id in request.env[res_model].browse(res_id).sudo(
             ).exists().message_ids.mapped('author_id').ids:
                 status, headers, _content = binary_content(
                     model='res.partner',
                     id=partner_id,
                     field='image_medium',
                     default_mimetype='image/png',
                     env=request.env(user=SUPERUSER_ID))
                 # binary content return an empty string and not a placeholder if obj[field] is False
                 if _content != '':
                     content = _content
                 if status == 304:
                     return werkzeug.wrappers.Response(status=304)
         except AccessError:
             pass
     image_base64 = base64.b64decode(content)
     headers.append(('Content-Length', len(image_base64)))
     response = request.make_response(image_base64, headers)
     response.status = str(status)
     return response
Example #2
0
 def print_sale_details(self, date_start=False, date_stop=False, **kw):
     r = request.env['report.point_of_sale.report_saledetails']
     pdf, _ = request.env.ref(
         'point_of_sale.sale_details_report').with_context(
             date_start=date_start, date_stop=date_stop).render_qweb_pdf(r)
     pdfhttpheaders = [('Content-Type', 'application/pdf'),
                       ('Content-Length', len(pdf))]
     return request.make_response(pdf, headers=pdfhttpheaders)
Example #3
0
 def portal_sale_order_report(self, order_id, access_token=None, **kw):
     pdf = request.env.ref(
         'sale.action_report_saleorder').sudo().render_qweb_pdf([order_id
                                                                 ])[0]
     pdfhttpheaders = [
         ('Content-Type', 'application/pdf'),
         ('Content-Length', len(pdf)),
     ]
     return request.make_response(pdf, headers=pdfhttpheaders)
Example #4
0
 def report(self, output_format, report_name, token, report_id=False, **kw):
     uid = request.session.uid
     domain = [('create_uid', '=', uid)]
     stock_traceability = request.env['stock.traceability.report'].sudo(
         uid).search(domain, limit=1)
     line_data = json.loads(kw['data'])
     try:
         if output_format == 'pdf':
             response = request.make_response(
                 stock_traceability.with_context(
                     active_id=report_id).get_pdf(line_data),
                 headers=[('Content-Type', 'application/pdf'),
                          ('Content-Disposition', 'attachment; filename=' +
                           'stock_traceability' + '.pdf;')])
             response.set_cookie('fileToken', token)
             return response
     except Exception as e:
         se = _serialize_exception(e)
         error = {'code': 200, 'message': 'actpy Server Error', 'data': se}
         return request.make_response(html_escape(json.dumps(error)))
Example #5
0
    def get_wishlist(self, count=False, **kw):
        values = request.env['product.wishlist'].with_context(
            display_default_code=False).current()
        if count:
            return request.make_response(
                json.dumps(values.mapped('product_id').ids))

        if not len(values):
            return request.redirect("/shop")

        return request.render("website_sale_wishlist.product_wishlist",
                              dict(wishes=values))
Example #6
0
    def portal_order_report(self, order_id, access_token=None, **kw):
        try:
            order_sudo = self._order_check_access(order_id, access_token)
        except AccessError:
            return request.redirect('/my')

        # print report as sudo, since it require access to taxes, payment term, ... and portal
        # does not have those access rights.
        pdf = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([order_sudo.id])[0]
        pdfhttpheaders = [
            ('Content-Type', 'application/pdf'),
            ('Content-Length', len(pdf)),
        ]
        return request.make_response(pdf, headers=pdfhttpheaders)
Example #7
0
 def slide_download(self, slide, sitemap=False):
     if slide.download_security == 'public' or (
             slide.download_security == 'user' and request.session.uid):
         filecontent = base64.b64decode(slide.datas)
         disposition = 'attachment; filename=%s.pdf' % werkzeug.urls.url_quote(
             slide.name)
         return request.make_response(
             filecontent, [('Content-Type', 'application/pdf'),
                           ('Content-Length', len(filecontent)),
                           ('Content-Disposition', disposition)])
     elif not request.session.uid and slide.download_security == 'user':
         return werkzeug.utils.redirect('/web?redirect=/slides/slide/%s' %
                                        (slide.id))
     return request.render("website.403")
Example #8
0
    def get_report(self, **kwargs):
        uid = request.session.uid
        gst_report_obj = request.env['gst.report'].sudo(uid)
        data = {
            'from_date': kwargs['from_date'],
            'to_date': kwargs['to_date'],
            'company_id': int(kwargs['company_id']),
            'year': kwargs['year'],
            'month': kwargs['month'],
            'summary_type': kwargs['summary_type'],
        }

        utc_tz = pytz.timezone('UTC')
        tz = pytz.timezone(
            request.env.user.tz) if request.env.user.tz else pytz.utc

        def utc_to_local_zone(naive_datetime):
            utc_dt = utc_tz.localize(naive_datetime,
                                     is_dst=False)
            return utc_dt.astimezone(tz)

        create_date = datetime.strptime(
            datetime.today().strftime(DEFAULT_SERVER_DATETIME_FORMAT),
            DEFAULT_SERVER_DATETIME_FORMAT)
        company_id = request.env['res.company'].browse(int(data['company_id']))
        gst_file_name = ''
        if data['summary_type'] == 'gstr1':
            gst_file_name = _('GSTR-1')
        elif data['summary_type'] == 'gstr2':
            gst_file_name = _('GSTR-2')
        filename = gst_file_name + _('_%s_%s-%s_%s.xlsx') % (
            company_id.vat, datetime.today().strftime("%B"),
            data['year'],
            utc_to_local_zone(create_date).strftime(
                "%d/%m/%Y %H:%M:%S"))

        response = request.make_response(
            None,
            headers=[
                ('Content-Type', 'application/vnd.ms-excel'),
                ('Content-Disposition',
                 'attachment; filename=' + filename + ';')
            ]
        )
        gst_report_obj.print_report(data, 1, response)
        return response
Example #9
0
    def livechat_lib(self, ext, **kwargs):
        # _get_asset return the bundle html code (script and link list) but we want to use the attachment content
        xmlid = 'im_livechat.external_lib'
        files, remains = request.env["ir.qweb"]._get_asset_content(
            xmlid, options=request.context)
        asset = AssetsBundle(xmlid, files, remains)

        mock_attachment = getattr(asset, ext)()
        if isinstance(
                mock_attachment, list
        ):  # suppose that CSS asset will not required to be split in pages
            mock_attachment = mock_attachment[0]
        # can't use /web/content directly because we don't have attachment ids (attachments must be created)
        status, headers, content = binary_content(id=mock_attachment.id,
                                                  unique=asset.checksum)
        content_base64 = base64.b64decode(content) if content else ''
        headers.append(('Content-Length', len(content_base64)))
        return request.make_response(content_base64, headers)
Example #10
0
    def portal_my_picking_report(self, picking_id, access_token=None, **kw):
        """ Print delivery slip for customer, using either access rights or access token
        to be sure customer has access """
        try:
            picking_sudo = self._stock_picking_check_access(
                picking_id, access_token=access_token)
        except exceptions.AccessError:
            return request.redirect('/my')

        # print report as sudo, since it require access to product, taxes, payment term etc.. and portal does not have those access rights.
        pdf = request.env.ref(
            'stock.action_report_delivery').sudo().render_qweb_pdf(
                [picking_sudo.id])[0]
        pdfhttpheaders = [
            ('Content-Type', 'application/pdf'),
            ('Content-Length', len(pdf)),
        ]
        return request.make_response(pdf, headers=pdfhttpheaders)
Example #11
0
    def user_avatar(self, user_id=0, **post):
        status, headers, content = binary_content(
            model='res.users',
            id=user_id,
            field='image_medium',
            default_mimetype='image/png',
            env=request.env(user=SUPERUSER_ID))

        if not content:
            img_path = modules.get_module_resource('web', 'static/src/img',
                                                   'placeholder.png')
            with open(img_path, 'rb') as f:
                image = f.read()
            content = base64.b64encode(image)
        if status == 304:
            return werkzeug.wrappers.Response(status=304)
        image_base64 = base64.b64decode(content)
        headers.append(('Content-Length', len(image_base64)))
        response = request.make_response(image_base64, headers)
        response.status = str(status)
        return response
Example #12
0
    def view(self, db, token, action, id, view='calendar'):
        registry = registry_get(db)
        with registry.cursor() as cr:
            # Since we are in auth=none, create an env with SUPERUSER_ID
            env = Environment(cr, SUPERUSER_ID, {})
            attendee = env['calendar.attendee'].search([
                ('access_token', '=', token), ('event_id', '=', int(id))
            ])
            if not attendee:
                return request.not_found()
            timezone = attendee.partner_id.tz
            lang = attendee.partner_id.lang or 'en_US'
            event = env['calendar.event'].with_context(tz=timezone,
                                                       lang=lang).browse(
                                                           int(id))

            # If user is internal and logged, redirect to form view of event
            # otherwise, display the simplifyed web page with event informations
            if request.session.uid and request.env['res.users'].browse(
                    request.session.uid).user_has_groups('base.group_user'):
                return werkzeug.utils.redirect(
                    '/web?db=%s#id=%s&view_type=form&model=calendar.event' %
                    (db, id))

            # NOTE : we don't use request.render() since:
            # - we need a template rendering which is not lazy, to render before cursor closing
            # - we need to display the template in the language of the user (not possible with
            #   request.render())
            response_content = env['ir.ui.view'].with_context(
                lang=lang).render_template(
                    'calendar.invitation_page_anonymous', {
                        'event': event,
                        'attendee': attendee,
                    })
            return request.make_response(response_content,
                                         headers=[('Content-Type', 'text/html')
                                                  ])
Example #13
0
    def status_http(self, debug=None, **kwargs):
        resp = """
<!DOCTYPE HTML>
<html>
    <head>
        <title>actpy's PosBox</title>
        <style>
        body {
            width: 480px;
            margin: 60px auto;
            font-family: sans-serif;
            text-align: justify;
            color: #6B6B6B;
        }
        .device {
            border-bottom: solid 1px rgb(216,216,216);
            padding: 9px;
        }
        .device:nth-child(2n) {
            background:rgb(240,240,240);
        }
        </style>
    </head>
    <body>
        <h1>Hardware Status</h1>
        <p>The list of enabled drivers and their status</p>
"""
        statuses = self.get_status()
        for driver in statuses:

            status = statuses[driver]

            if status['status'] == 'connecting':
                color = 'black'
            elif status['status'] == 'connected':
                color = 'green'
            else:
                color = 'red'

            resp += "<h3 style='color:"+color+";'>"+driver+' : '+status['status']+"</h3>\n"
            resp += "<ul>\n"
            for msg in status['messages']:
                resp += '<li>'+msg+'</li>\n'
            resp += "</ul>\n"
        resp += """
            <h2>Connected Devices</h2>
            <p>The list of connected USB devices as seen by the posbox</p>
        """
        if debug is None:
            resp += """(<a href="/hw_proxy/status?debug">debug version</a>)"""
        devices = subprocess.check_output("lsusb").split('\n')
        count   = 0
        resp += "<div class='devices'>\n"
        for device in devices:
            device_name = device[device.find('ID')+2:]
            device_id   = device_name.split()[0]
            if not (device_id in BANNED_DEVICES):
                resp += "<div class='device' data-device='"+device+"'>"+device_name+"</div>\n"
                count += 1

        if count == 0:
            resp += "<div class='device'>No USB Device Found</div>"

        resp += "</div>\n</body>\n</html>\n\n"

        if debug is not None:
            resp += """

                <h3>Debug version</h3>
                <p><tt>lsusb -v</tt> output:</p>
                <pre>
                %s
                </pre>

            """ % subprocess.check_output('lsusb -v', shell=True)

        return request.make_response(resp,{
            'Cache-Control': 'no-cache',
            'Content-Type': 'text/html; charset=utf-8',
            'Access-Control-Allow-Origin':  '*',
            'Access-Control-Allow-Methods': 'GET',
            })
Example #14
0
    def sitemap_xml_index(self, **kwargs):
        current_website = request.website
        Attachment = request.env['ir.attachment'].sudo()
        View = request.env['ir.ui.view'].sudo()
        mimetype = 'application/xml;charset=utf-8'
        content = None

        def create_sitemap(url, content):
            return Attachment.create({
                'datas': base64.b64encode(content),
                'mimetype': mimetype,
                'type': 'binary',
                'name': url,
                'url': url,
            })
        dom = [('url', '=' , '/sitemap-%d.xml' % current_website.id), ('type', '=', 'binary')]
        sitemap = Attachment.search(dom, limit=1)
        if sitemap:
            # Check if stored version is still valid
            create_date = fields.Datetime.from_string(sitemap.create_date)
            delta = datetime.datetime.now() - create_date
            if delta < SITEMAP_CACHE_TIME:
                content = base64.b64decode(sitemap.datas)

        if not content:
            # Remove all sitemaps in ir.attachments as we're going to regenerated them
            dom = [('type', '=', 'binary'), '|', ('url', '=like', '/sitemap-%d-%%.xml' % current_website.id),
                   ('url', '=', '/sitemap-%d.xml' % current_website.id)]
            sitemaps = Attachment.search(dom)
            sitemaps.unlink()

            pages = 0
            locs = request.website.sudo(user=request.website.user_id.id).enumerate_pages()
            while True:
                values = {
                    'locs': islice(locs, 0, LOC_PER_SITEMAP),
                    'url_root': request.httprequest.url_root[:-1],
                }
                urls = View.render_template('website.sitemap_locs', values)
                if urls.strip():
                    content = View.render_template('website.sitemap_xml', {'content': urls})
                    pages += 1
                    last_sitemap = create_sitemap('/sitemap-%d-%d.xml' % (current_website.id, pages), content)
                else:
                    break

            if not pages:
                return request.not_found()
            elif pages == 1:
                # rename the -id-page.xml => -id.xml
                last_sitemap.write({
                    'url': "/sitemap-%d.xml" % current_website.id,
                    'name': "/sitemap-%d.xml" % current_website.id,
                })
            else:
                # TODO: in master/saas-15, move current_website_id in template directly
                pages_with_website = ["%d-%d" % (current_website.id, p) for p in range(1, pages + 1)]

                # Sitemaps must be split in several smaller files with a sitemap index
                content = View.render_template('website.sitemap_index_xml', {
                    'pages': pages_with_website,
                    'url_root': request.httprequest.url_root,
                })
                create_sitemap('/sitemap-%d.xml' % current_website.id, content)

        return request.make_response(content, [('Content-Type', mimetype)])
Example #15
0
    def export_xls(self, data, token):
        jdata = json.loads(data)
        nbr_measures = jdata['nbr_measures']
        workbook = xlwt.Workbook()
        worksheet = workbook.add_sheet(jdata['title'])
        header_bold = xlwt.easyxf("font: bold on; pattern: pattern solid, fore_colour gray25;")
        header_plain = xlwt.easyxf("pattern: pattern solid, fore_colour gray25;")
        bold = xlwt.easyxf("font: bold on;")

        # Step 1: writing headers
        headers = jdata['headers']

        # x,y: current coordinates
        # carry: queue containing cell information when a cell has a >= 2 height
        #      and the drawing code needs to add empty cells below
        x, y, carry = 1, 0, deque()
        for i, header_row in enumerate(headers):
            worksheet.write(i, 0, '', header_plain)
            for header in header_row:
                while (carry and carry[0]['x'] == x):
                    cell = carry.popleft()
                    for i in range(nbr_measures):
                        worksheet.write(y, x+i, '', header_plain)
                    if cell['height'] > 1:
                        carry.append({'x': x, 'height': cell['height'] - 1})
                    x = x + nbr_measures
                style = header_plain if 'expanded' in header else header_bold
                for i in range(header['width']):
                    worksheet.write(y, x + i, header['title'] if i == 0 else '', style)
                if header['height'] > 1:
                    carry.append({'x': x, 'height': header['height'] - 1})
                x = x + header['width']
            while (carry and carry[0]['x'] == x):
                cell = carry.popleft()
                for i in range(nbr_measures):
                    worksheet.write(y, x+i, '', header_plain)
                if cell['height'] > 1:
                    carry.append({'x': x, 'height': cell['height'] - 1})
                x = x + nbr_measures
            x, y = 1, y + 1

        # Step 2: measure row
        if nbr_measures > 1:
            worksheet.write(y, 0, '', header_plain)
            for measure in jdata['measure_row']:
                style = header_bold if measure['is_bold'] else header_plain
                worksheet.write(y, x, measure['measure'], style)
                x = x + 1
            y = y + 1

        # Step 3: writing data
        x = 0
        for row in jdata['rows']:
            worksheet.write(y, x, row['indent'] * '     ' + ustr(row['title']), header_plain)
            for cell in row['values']:
                x = x + 1
                if cell.get('is_bold', False):
                    worksheet.write(y, x, cell['value'], bold)
                else:
                    worksheet.write(y, x, cell['value'])
            x, y = 0, y + 1

        response = request.make_response(None,
            headers=[('Content-Type', 'application/vnd.ms-excel'),
                    ('Content-Disposition', 'attachment; filename=table.xls;')],
            cookies={'fileToken': token})
        workbook.save(response.stream)

        return response
Example #16
0
    def view(self, order_id, pdf=None, token=None, message=False, **post):
        # use sudo to allow accessing/viewing orders for public user
        # only if he knows the private token
        now = fields.Date.today()
        if token:
            Order = request.env['sale.order'].sudo().search([
                ('id', '=', order_id), ('access_token', '=', token)
            ])
        else:
            Order = request.env['sale.order'].search([('id', '=', order_id)])
        # Log only once a day
        if Order and request.session.get(
                'view_quote_%s' % Order.id) != now and request.env.user.share:
            request.session['view_quote_%s' % Order.id] = now
            body = _('Quotation viewed by customer')
            _message_post_helper(
                res_model='sale.order',
                res_id=Order.id,
                message=body,
                token=token,
                message_type='notification',
                subtype="mail.mt_note",
                partner_ids=Order.user_id.sudo().partner_id.ids)
        if not Order:
            return request.render('website.404')

        # Token or not, sudo the order, since portal user has not access on
        # taxes, required to compute the total_amout of SO.
        order_sudo = Order.sudo()

        days = 0
        if order_sudo.validity_date:
            days = (fields.Date.from_string(order_sudo.validity_date) -
                    fields.Date.from_string(fields.Date.today())).days + 1
        if pdf:
            pdf = request.env.ref(
                'website_quote.report_web_quote').sudo().with_context(
                    set_viewport_size=True).render_qweb_pdf([order_sudo.id])[0]
            pdfhttpheaders = [('Content-Type', 'application/pdf'),
                              ('Content-Length', len(pdf))]
            return request.make_response(pdf, headers=pdfhttpheaders)
        transaction_id = request.session.get('quote_%s_transaction_id' %
                                             order_sudo.id)
        if not transaction_id:
            Transaction = request.env['payment.transaction'].sudo().search([
                ('reference', '=', order_sudo.name)
            ])
        else:
            Transaction = request.env['payment.transaction'].sudo().browse(
                transaction_id)
        values = {
            'quotation':
            order_sudo,
            'message':
            message and int(message) or False,
            'option':
            any(not x.line_id for x in order_sudo.options),
            'order_valid': (not order_sudo.validity_date)
            or (now <= order_sudo.validity_date),
            'days_valid':
            days,
            'action':
            request.env.ref('sale.action_quotations').id,
            'no_breadcrumbs':
            request.env.user.partner_id.commercial_partner_id
            not in order_sudo.message_partner_ids,
            'tx_id':
            Transaction.id if Transaction else False,
            'tx_state':
            Transaction.state if Transaction else False,
            'tx_post_msg':
            Transaction.acquirer_id.post_msg if Transaction else False,
            'payment_tx':
            Transaction,
            'need_payment':
            order_sudo.invoice_status == 'to invoice'
            and Transaction.state in ['draft', 'cancel', 'error'],
            'token':
            token,
            'return_url':
            '/shop/payment/validate',
            'bootstrap_formatting':
            True,
            'partner_id':
            order_sudo.partner_id.id,
        }

        if order_sudo.require_payment or values['need_payment']:
            acquirers = request.env['payment.acquirer'].sudo().search([
                ('website_published', '=', True),
                ('company_id', '=', order_sudo.company_id.id)
            ])

            values['form_acquirers'] = [
                acq for acq in acquirers
                if acq.payment_flow == 'form' and acq.view_template_id
            ]
            values['s2s_acquirers'] = [
                acq for acq in acquirers if acq.payment_flow == 's2s'
                and acq.registration_view_template_id
            ]
            values['pms'] = request.env['payment.token'].search([
                ('partner_id', '=', order_sudo.partner_id.id),
                ('acquirer_id', 'in',
                 [acq.id for acq in values['s2s_acquirers']])
            ])

            for acq in values['form_acquirers']:
                acq.form = acq.render(
                    '/',
                    order_sudo.amount_total,
                    order_sudo.pricelist_id.currency_id.id,
                    values={
                        'return_url':
                        '/quote/%s/%s' %
                        (order_id, token) if token else '/quote/%s' % order_id,
                        'type':
                        'form',
                        'alias_usage':
                        _('If we store your payment information on our server, subscription payments will be made automatically.'
                          ),
                        'partner_id':
                        order_sudo.partner_id.id,
                    })
        history = request.session.get('my_quotes_history', [])
        values.update(get_records_pager(history, order_sudo))
        return request.render('website_quote.so_quotation', values)