def survey_get_certification(self, survey_id, **kwargs): """ The certification document can be downloaded as long as the user has succeeded the certification """ survey = request.env['survey.survey'].sudo().search([ ('id', '=', survey_id), ('certificate', '=', True) ]) if not survey: # no certification found return werkzeug.utils.redirect("/") succeeded_attempt = request.env['survey.user_input'].sudo().search([ ('partner_id', '=', request.env.user.partner_id.id), ('survey_id', '=', survey_id), ('quizz_passed', '=', True) ], limit=1) if not succeeded_attempt: raise UserError(_("The user has not succeeded the certification")) report_sudo = request.env.ref('survey.certification_report').sudo() report = report_sudo.render_qweb_pdf([succeeded_attempt.id], data={'report_type': 'pdf'})[0] reporthttpheaders = [ ('Content-Type', 'application/pdf'), ('Content-Length', len(report)), ] reporthttpheaders.append(('Content-Disposition', content_disposition('Certification.pdf'))) return request.make_response(report, headers=reporthttpheaders)
def hook_next(self, data): """ This function is meant to be overwritten by inheriting plugins """ # Since there's nothing else to do in the original plugin, # we just launch the instance creation orm_app = request.env['clouder.application'].sudo() instance_id = orm_app.create_instance_from_request( data['result']['clws_id']) resp = { 'html': '', 'div_id': '', 'js': [], 'clws_id': data['result']['clws_id'] } if not instance_id: resp['html'] = """<p>""" + \ _("Error: instance creation failed.") + u"""</p>""" resp['div_id'] = 'CL_error_retry' else: resp['html'] = """<p>""" + \ _("Your request for a Clouder instance has been sent.") \ + u"""<br/>""" + \ _("Thank you for your interest in Clouder!") + u"""</p>""" resp['div_id'] = 'CL_final_thanks' return request.make_response(json.dumps(resp), headers=HEADERS)
def get_user_profile_avatar(self, user_id, field='image_large', width=0, height=0, crop=False, avoid_if_small=False, upper_limit=False, **post): if field not in ('image_small', 'image_medium', 'image_large'): return werkzeug.exceptions.Forbidden() can_sudo = self._check_avatar_access(user_id, **post) if can_sudo: status, headers, content = request.env['ir.http'].sudo().binary_content( model='res.users', id=user_id, field=field, default_mimetype='image/png') else: status, headers, content = request.env['ir.http'].binary_content( model='res.users', id=user_id, field=field, default_mimetype='image/png') if status == 301: return request.env['ir.http']._response_by_status(status, headers, content) if status == 304: return werkzeug.wrappers.Response(status=304) if not content: content = self._get_default_avatar(field, headers, width, height) content = tools.limited_image_resize( content, width=width, height=height, crop=crop, upper_limit=upper_limit, avoid_if_small=avoid_if_small) image_base64 = base64.b64decode(content) headers.append(('Content-Length', len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
def slide_get_image(self, slide_id, field='image_medium', width=0, height=0, crop=False): # Protect infographics by limiting access to 256px (large) images if field not in ('image_small', 'image_medium', 'image_large'): return werkzeug.exceptions.Forbidden() slide = request.env['slide.slide'].sudo().browse(slide_id).exists() if not slide: raise werkzeug.exceptions.NotFound() status, headers, image_base64 = request.env['ir.http'].sudo().binary_content( model='slide.slide', id=slide.id, field=field, default_mimetype='image/png') if status == 301: return request.env['ir.http']._response_by_status(status, headers, image_base64) if status == 304: return werkzeug.wrappers.Response(status=304) if not image_base64: image_base64 = self._get_default_avatar() if not (width or height): width, height = tools.image_guess_size_from_field_name(field) image_base64 = tools.image_process(image_base64, (width, height), crop=crop) content = base64.b64decode(image_base64) headers = http.set_safe_image_headers(headers, content) response = request.make_response(content, headers) response.status_code = status return response
def slide_get_image(self, slide_id, field='image_medium', width=0, height=0, crop=False, avoid_if_small=False, upper_limit=False): # Protect infographics by limiting access to 256px (large) images if field not in ('image_small', 'image_medium', 'image_large'): return werkzeug.exceptions.Forbidden() slide = request.env['slide.slide'].sudo().browse(slide_id).exists() if not slide: raise werkzeug.exceptions.NotFound() status, headers, content = request.env['ir.http'].sudo().binary_content( model='slide.slide', id=slide.id, field=field, default_mimetype='image/png') if status == 301: return request.env['ir.http']._response_by_status(status, headers, content) if status == 304: return werkzeug.wrappers.Response(status=304) if not content: content = self._get_default_avatar(field, headers, width, height) content = tools.limited_image_resize( content, width=width, height=height, crop=crop, upper_limit=upper_limit, avoid_if_small=avoid_if_small) image_base64 = base64.b64decode(content) headers.append(('Content-Length', len(image_base64))) response = request.make_response(image_base64, headers) response.status_code = status return response
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 if status == 301 and is_url(content): r = requests.get(content) image_base64 = r.content else: 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
def get_env(self, **post): """ Returns the list of environments linked to the given user Requires correct credentials (login/password) for the user """ # Check parameters lang = 'en_US' if 'lang' in post: lang = post['lang'] request.env = self.env_with_context({'lang': lang}) if 'login' not in post or 'password' not in post: return self.bad_request("Missing credentials") uid = self.check_login(post['login'], post['password']) if not uid: return json.dumps( {'error': _('Could not login with given credentials.')}) env_orm = request.env['clouder.environment'].sudo() user_orm = request.env['res.users'].sudo() user = user_orm.browse([uid])[0] env_ids = env_orm.search([('partner_id', '=', user.partner_id.id)]) result = {} for env in env_ids: result[str(env.id)] = { 'name': env.name } return request.make_response( json.dumps({'result': result}), headers=HEADERS)
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
def get_user_profile_avatar(self, user_id, field='image_large', width=0, height=0, crop=False, **post): if field not in ('image_small', 'image_medium', 'image_large'): return werkzeug.exceptions.Forbidden() can_sudo = self._check_avatar_access(user_id, **post) if can_sudo: status, headers, image_base64 = request.env['ir.http'].sudo().binary_content( model='res.users', id=user_id, field=field, default_mimetype='image/png') else: status, headers, image_base64 = request.env['ir.http'].binary_content( model='res.users', id=user_id, field=field, default_mimetype='image/png') if status == 301: return request.env['ir.http']._response_by_status(status, headers, image_base64) if status == 304: return werkzeug.wrappers.Response(status=304) if not image_base64: image_base64 = self._get_default_avatar() if not (width or height): width, height = tools.image_guess_size_from_field_name(field) image_base64 = tools.image_process(image_base64, (width, height), crop=crop) content = base64.b64decode(image_base64) headers = http.set_safe_image_headers(headers, content) response = request.make_response(content, headers) response.status_code = status return response
def page_login(self, **post): """ Uses check_login on the provided login and password See check_login docstring. """ if 'login' not in post: return self.bad_request("Missing parameter login") if 'password' not in post: post['password'] = False uid = self.check_login(post['login'], post['password']) result = {'response': bool(uid)} # Provide information to fill the form if login was successfull if post['password'] and uid: orm_user = request.env['res.users'].sudo() user = orm_user.browse([uid])[0] result['partner_info'] = { "name": user.partner_id.name, "phone": user.partner_id.phone, "email": user.partner_id.email, "street2": user.partner_id.street2, "city": user.partner_id.city, "country_id": user.partner_id.country_id.id, "street": user.partner_id.street, "zip": user.partner_id.zip, "state_id": user.partner_id.state_id.id } return request.make_response(json.dumps(result), headers=HEADERS)
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 = order_sudo.get_portal_last_transaction() 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, 'payment_tx': transaction, 'tx_post_msg': transaction.acquirer_id.post_msg if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], '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']])]) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('website_quote.so_quotation', values)
def sitemap_xml_index(self): 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': content.encode('base64'), 'mimetype': mimetype, 'type': 'binary', 'name': url, 'url': url, }) sitemap = Attachment.search([('url', '=', '/sitemap.xml'), ('type', '=', 'binary')], 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 = sitemap.datas.decode('base64') if not content: # Remove all sitemaps in ir.attachments as we're going to regenerated them sitemaps = Attachment.search([('url', '=like', '/sitemap%.xml'), ('type', '=', 'binary')]) 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.xml' % pages, content) else: break if not pages: return request.not_found() elif pages == 1: last_sitemap.write({ 'url': "/sitemap.xml", 'name': "/sitemap.xml" }) else: # Sitemaps must be split in several smaller files with a sitemap index content = View.render_template('website.sitemap_index_xml', { 'pages': range(1, pages + 1), 'url_root': request.httprequest.url_root, }) create_sitemap('/sitemap.xml', content) return request.make_response(content, [('Content-Type', mimetype)])
def download_pdf(self, **parameters): pdf = request.env['compassion.child'].sudo() \ .mobile_letter_pdf(**parameters) headers = [ ('Content-Type', 'application/pdf'), ('Content-Length', len(pdf)) ] return request.make_response(pdf, headers=headers)
def print_saleorder(self): sale_order_id = request.session.get('sale_last_order_id') if sale_order_id: pdf, _ = request.env.ref('sale.action_report_saleorder').sudo().render_qweb_pdf([sale_order_id]) pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', u'%s' % len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) else: return request.redirect('/shop')
def print_saleorder(self): sale_order_id = request.session.get('sale_last_order_id') if sale_order_id: pdf = request.env['report'].sudo().get_pdf([sale_order_id], 'sale.report_saleorder', data=None) pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) else: return request.redirect('/shop')
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))
def request_form(self, **post): """ Generates and returns the HTML base form """ # Check parameters if 'hostname' not in post or not post['hostname']: return self.bad_request(_("Missing argument hostname")) lang = 'en_US' if 'lang' in post: lang = post['lang'] request.env = self.env_with_context({'lang': lang}) # Getting data to generate the form app_orm = request.env['clouder.application'].sudo() domain_orm = request.env['clouder.domain'].sudo() country_orm = request.env['res.country'].sudo() state_orm = request.env['res.country.state'].sudo() applications = app_orm.search([('web_create_type', '!=', 'disabled')]) domains = domain_orm.search([]) countries = country_orm.search([]) states = state_orm.search([]) font_awesome = """ @font-face { font-family: 'FontAwesome'; src: url('%(path)s.eot?v=4.2.0'); src: url('%(path)s.eot?#iefix&v=4.2.0') format('embedded-opentype'), url('%(path)s.woff?v=4.2.0') format('woff'), url('%(path)s.ttf?v=4.2.0') format('truetype'), url('%(path)s.svg?v=4.2.0#fontawesomeregular') format('svg'); font-weight: normal; font-style: normal; } """ % { 'path': post['hostname'].rstrip('/') + "/clouder_form/fontawesome/fontawesome-webfont", } # Render the form qweb_context = { 'applications': applications.sorted(key=lambda r: self.uni_norm(r.name)), 'domains': domains.sorted(key=lambda r: self.uni_norm(r.name)), 'countries': countries.sorted(key=lambda r: self.uni_norm(r.name)), 'states': states.sorted(key=lambda r: self.uni_norm(r.name)), 'hostname': post['hostname'].rstrip('/'), 'font_awesome_definition': font_awesome } html = request.env.ref('clouder_website.plugin_form').render( qweb_context, engine='ir.qweb', context=request.context ) return request.make_response(html, headers=HEADERS)
def print_saleorder(self): sale_order_id = request.session.get("sale_last_order_id") if sale_order_id: order = request.env["sale.order"].browse(sale_order_id) pdf = request.env["report"].sudo().get_pdf(order, "sale.report_saleorder", data=None) pdfhttpheaders = [("Content-Type", "application/pdf"), ("Content-Length", len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders) else: return request.redirect("/shop")
def get_claim_report_user(self, employee_id, **post): if not request.env.user.has_group('fleet.fleet_group_manager'): return request.not_found() employee = request.env['hr.employee'].search([('id', '=', employee_id)], limit=1) partner_ids = (employee.user_id.partner_id | employee.address_home_id).ids if not employee or not partner_ids: return request.not_found() car_assignation_logs = request.env['fleet.vehicle.assignation.log'].search([('driver_id', 'in', partner_ids)]) doc_list = request.env['ir.attachment'].search([ ('res_model', '=', 'fleet.vehicle.assignation.log'), ('res_id', 'in', car_assignation_logs.ids)], order='create_date') writer = PdfFileWriter() font = "Helvetica" normal_font_size = 14 for document in doc_list: car_line_doc = request.env['fleet.vehicle.assignation.log'].browse(document.res_id) try: reader = PdfFileReader(io.BytesIO(base64.b64decode(document.datas)), strict=False, overwriteWarnings=False) except Exception: continue width = float(reader.getPage(0).mediaBox.getUpperRight_x()) height = float(reader.getPage(0).mediaBox.getUpperRight_y()) header = io.BytesIO() can = canvas.Canvas(header) can.setFont(font, normal_font_size) can.setFillColorRGB(1, 0, 0) car_name = car_line_doc.vehicle_id.display_name date_start = car_line_doc.date_start date_end = car_line_doc.date_end or '...' text_to_print = _("%s (driven from: %s to %s)") % (car_name, date_start, date_end) can.drawCentredString(width / 2, height - normal_font_size, text_to_print) can.save() header_pdf = PdfFileReader(header, overwriteWarnings=False) for page_number in range(0, reader.getNumPages()): page = reader.getPage(page_number) page.mergePage(header_pdf.getPage(0)) writer.addPage(page) _buffer = io.BytesIO() writer.write(_buffer) merged_pdf = _buffer.getvalue() _buffer.close() pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', len(merged_pdf))] return request.make_response(merged_pdf, headers=pdfhttpheaders)
def make_event_ics_file(self, event, **kwargs): if not event or not event.registration_ids: return request.not_found() files = event._get_ics_file() content = files[event.id] return request.make_response(content, [ ('Content-Type', 'application/octet-stream'), ('Content-Length', len(content)), ('Content-Disposition', content_disposition('%s.ics' % event.name)) ])
def bad_request(self, desc): """ Returns a "Bad Request" response with CORS headers """ # TODO: replace with error handling _logger.warning('Bad request received: {0}'.format(desc)) response = { "error": desc } return request.make_response(json.dumps(response), headers=HEADERS)
def make_event_ics_file(self, event, **kwargs): if not event or not event.registration_ids: return request.not_found() attendee_ids = list(json.loads(kwargs.get('attendees', '{}').replace("'", '"')).values()) files = event.get_ics_file(attendee_ids) content = files[event.id] return request.make_response(content, [ ('Content-Type', 'application/octet-stream'), ('Content-Length', len(content)), ('Content-Disposition', 'attachment; filename=' + event.name + '.ics') ])
def portal_order_page(self, order_id, pdf=None, access_token=None, message=False, **kw): try: order_sudo = self._document_check_access('sale.order', order_id, access_token=access_token) except (AccessError, MissingError): return request.redirect('/my') if pdf: pdf = request.env.ref('sale.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) # use sudo to allow accessing/viewing orders for public user # only if he knows the private token now = fields.Date.today() # Log only once a day if order_sudo and request.session.get('view_quote_%s' % order_sudo.id) != now and request.env.user.share and access_token: request.session['view_quote_%s' % order_sudo.id] = now body = _('Quotation viewed by customer') _message_post_helper(res_model='sale.order', res_id=order_sudo.id, message=body, token=order_sudo.access_token, message_type='notification', subtype="mail.mt_note", partner_ids=order_sudo.user_id.sudo().partner_id.ids) transaction = order_sudo.get_portal_last_transaction() # TODO SEB fix breadcrumbs -> should always be visible (or at least no home alone) values = { 'sale_order': order_sudo, 'message': int(message) if message else False, '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_state': transaction.state if transaction else False, 'need_payment': order_sudo.invoice_status == 'to invoice' and transaction.state in ['draft', 'cancel'], 'token': access_token, 'return_url': '/shop/payment/validate', 'bootstrap_formatting': True, 'partner_id': order_sudo.partner_id.id, } if order_sudo.has_to_be_paid() or values['need_payment']: domain = expression.AND([ ['&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id)], ['|', ('specific_countries', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id])] ]) acquirers = request.env['payment.acquirer'].sudo().search(domain) 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']])]) history = request.session.get('my_quotes_history', []) values.update(get_records_pager(history, order_sudo)) return request.render('sale.sale_order_portal_template', values)
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")
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 = json.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') 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)) report = request.env['report']._get_report_from_name(reportname) filename = "%s.%s" % (report.name, "pdf") if docids: ids = [int(x) for x in docids.split(",")] obj = request.env[report.model].browse(ids) if report.print_report_name and not len(obj) > 1: report_name = safe_eval(report.print_report_name, {'object': obj, 'time': time}) filename = "%s.%s" % (report_name, "pdf") response.headers.add('Content-Disposition', content_disposition(filename)) 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 as e: se = _serialize_exception(e) error = { 'code': 200, 'message': "Odoo Server Error", 'data': se } return request.make_response(html_escape(json.dumps(error)))
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) 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 = request.env['ir.http'].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)
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)
def qweb(self, mods=None, db=None): files = [f[0] for f in controllers_main.manifest_glob('qweb', addons=mods, db=db)] last_modified = controllers_main.get_last_modified(files) if request.httprequest.if_modified_since and request.httprequest.if_modified_since >= last_modified: return controllers_main.werkzeug.wrappers.Response(status=304) content, checksum = controllers_main.concat_xml(files) if request.context['lang'] == 'en_US': # request.env could be not available content = debrand_bytes(request.session.db and request.env or None, content) return controllers_main.make_conditional( request.make_response(content, [('Content-Type', 'text/xml')]), last_modified, checksum)
def export_xls_view(self, data, token): data = json.loads(data) files_name = data.get('files_name', []) columns_headers = data.get('headers', []) rows = data.get('rows', []) file_address = data.get('file_address', []) return request.make_response( self.from_data_excel(columns_headers, [rows, file_address]), headers=[ ('Content-Disposition', content_disposition(files_name)), ('Content-Type', self.content_type)], cookies={'fileToken': token} )
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
def report_download(self, data, token): requestcontent = json.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') else: # Particular report: data = url_decode(url.split( '?')[1]) # decoding the args represented in JSON response = self.report_routes(reportname, converter='pdf', **dict(data)) temp_dict = {} temp_dict.update(json.loads(dict(data).pop('options'))) if 'skit_report_type' in temp_dict.keys( ) and temp_dict['skit_report_type'] == 'XLS': report = request.env[ 'ir.actions.report']._get_report_from_name( reportname) filename = "%s.%s" % (report.name, "xls") # Customize the report name must be what we want # from print xls report ,pass the report_name and customize it. # code added for skit.event.report module execute same model for all event report if 'report_name' in temp_dict.keys( ) and temp_dict['skit_report_type'] == 'XLS': filename = "%s.%s" % (temp_dict['report_name'], "xls") response.headers.add('Content-Disposition', content_disposition(filename)) response.set_cookie('fileToken', token) return response report = request.env[ 'ir.actions.report']._get_report_from_name(reportname) filename = "%s.%s" % (report.name, "pdf") response.headers.add('Content-Disposition', content_disposition(filename)) 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 as e: se = _serialize_exception(e) error = {'code': 200, 'message': "Odoo Server Error", 'data': se} return request.make_response(html_escape(json.dumps(error)))
def hook_next(self, data): """ Returns the payment form after the basic form was submitted """ orm_clws = request.env['clouder.web.session'].sudo() orm_acq = request.env['payment.acquirer'].sudo() session = orm_clws.browse([data['result']['clws_id']])[0] company = request.env.ref('base.main_company') # Saving reference and amount session.write({ 'reference': "{0}_{1}".format(session.name, fields.Date.today()), 'amount': session.application_id.initial_invoice_amount }) # If instance creation is free, we just get to the creation process if not session.amount: return super(FormControllerExtend, self).hook_next(data) # Setting acquirer buttons acquirers = [] btn_args = [ session.reference, session.amount, company.currency_id.id, ] btn_kwargs = {'partner_id': session.partner_id.id} # The argument changed name between v8 and v9 of Odoo if self.version() >= 9: btn_kwargs['values'] = { 'return_url': '/clouder_form/payment_complete', 'cancel_url': '/clouder_form/payment_cancel' } else: btn_kwargs['tx_values'] = { 'return_url': '/clouder_form/payment_complete', 'cancel_url': '/clouder_form/payment_cancel' } render_ctx = dict(request.context, submit_class='btn btn-primary', submit_txt=_('Pay Now')) for acquirer in orm_acq.search([('clouder_form_enabled', '=', True), ('company_id', '=', company.id)]): acquirer.button = acquirer.with_context(**render_ctx).render( *btn_args, **btn_kwargs)[0] acquirers.append(acquirer) # Render the form qweb_context = { 'acquirers': acquirers, 'hostname': data['post_data']['hostname'].rstrip('/') } html = request.env.ref( 'clouder_website_payment.payment_buttons').render( qweb_context, engine='ir.qweb', context=request.context) # Send response resp = { 'clws_id': session.id, 'html': html, 'div_id': 'CL_payment', 'js': [ 'clouder_website_payment/static/src/' 'js/clouder_website_payment.js' ] } return request.make_response(json.dumps(resp), headers=HEADERS)
def export_xls(self, filename, title, company_id, date_from, date_to, **kw): company = request.env['res.company'].search([('id', '=', company_id)]) # account_ewt = request.env['account.account'].search([('name','=','Withholding Tax Expanded')], limit=1) account_type = request.env['account.account.type'].search([ ('name', '=', 'Fixed Assets') ]) account_ids = request.env['account.account'].search([ ('user_type_id', '=', account_type.id) ]) account_asset = request.env['account.asset.asset'].search([ ('state', '!=', 'draft') ]) date_processed = date.today().strftime('%m-%d-%Y') to_report_month = datetime.strptime(date_to, '%Y-%m-%d') user_id = request.env.user.name workbook = xlwt.Workbook() worksheet = workbook.add_sheet(title) # STYLES style_header_bold = xlwt.easyxf( "font: bold on;font: name Calibri;align: wrap no") style_header_right = xlwt.easyxf( "font: name Calibri;align: horiz right, wrap no") style_table_header_bold = xlwt.easyxf( "font: bold on;font: name Calibri;align: horiz centre, vert centre, wrap on;borders: top thin, bottom thin, right thin;" ) style_table_row = xlwt.easyxf( "font: name Calibri;align: horiz left, wrap no;borders: top thin, bottom thin, right thin;" ) style_table_row_amount = xlwt.easyxf( "font: name Calibri;align: horiz right, wrap no;borders: top thin, bottom thin, right thin;", num_format_str="#,##0.00") style_table_total = xlwt.easyxf( "pattern: pattern solid, fore_colour pale_blue;font: bold on;font: name Calibri;align: horiz left, wrap no;borders: top thin, bottom medium, right thin;" ) style_table_total_value = xlwt.easyxf( "pattern: pattern solid, fore_colour pale_blue;font: bold on;font: name Calibri;align: horiz right, wrap no;borders: top thin, bottom medium, right thin;", num_format_str="#,##0.00") worksheet.col(0).width = 350 * 12 worksheet.col(1).width = 350 * 12 worksheet.col(2).width = 350 * 12 worksheet.col(3).width = 500 * 12 worksheet.col(4).width = 500 * 12 worksheet.col(5).width = 350 * 12 worksheet.col(6).width = 350 * 12 worksheet.col(7).width = 350 * 12 worksheet.col(8).width = 350 * 12 worksheet.col(9).width = 350 * 12 worksheet.col(10).width = 350 * 12 worksheet.col(11).width = 350 * 12 worksheet.col(12).width = 350 * 12 worksheet.col(13).width = 350 * 12 worksheet.col(14).width = 350 * 12 worksheet.col(15).width = 350 * 12 worksheet.col(16).width = 350 * 12 worksheet.col(17).width = 350 * 12 worksheet.col(18).width = 350 * 12 worksheet.col(19).width = 350 * 12 worksheet.col(20).width = 350 * 12 worksheet.col(21).width = 350 * 12 worksheet.col(22).width = 350 * 12 worksheet.col(23).width = 350 * 12 worksheet.col(24).width = 350 * 12 worksheet.col(25).width = 350 * 12 worksheet.col(26).width = 350 * 12 worksheet.col(27).width = 350 * 12 worksheet.col(28).width = 350 * 12 worksheet.col(29).width = 350 * 12 worksheet.col(30).width = 350 * 12 worksheet.col(31).width = 350 * 12 worksheet.col(32).width = 350 * 12 worksheet.col(33).width = 350 * 12 worksheet.col(34).width = 350 * 12 worksheet.col(35).width = 350 * 12 worksheet.col(36).width = 350 * 12 worksheet.col(37).width = 350 * 12 worksheet.col(38).width = 350 * 12 # TEMPLATE HEADERS worksheet.write(0, 0, company.name, style_header_bold) # Company Name worksheet.write(1, 0, '%s %s %s %s %s %s' % (company.street or '', company.street2 or '', company.city or '', company.state_id.name or '', company.zip or '', company.country_id.name or ''), style_header_bold) # Company Address worksheet.write(2, 0, company.vat, style_header_bold) # Company TIN worksheet.write(4, 0, title, style_header_bold) # Report Title worksheet.write(5, 0, 'As of %s' % (to_report_month.strftime('%B %d, %Y')), style_header_bold) # Report Date # TABLE HEADER worksheet.write_merge(7, 8, 0, 0, 'REFERENCE DATE', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 1, 1, 'JOURNAL TYPE', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 2, 2, 'REFERENCE NO.', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 3, 3, 'SUPPLIER NAME', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 4, 4, 'REGISTERED ADDRESS', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 5, 5, 'TIN', style_table_header_bold) # HEADER worksheet.write_merge(7, 7, 6, 7, 'SOURCE DOCUMENT', style_table_header_bold) # HEADER worksheet.write(8, 6, 'TYPE', style_table_header_bold) # HEADER worksheet.write(8, 7, 'NUMBER', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 8, 8, 'GROSS AMOUNT', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 9, 9, 'NON-VAT / EXEMPT', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 10, 10, 'NET OF VAT', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 11, 11, 'INPUT TAX (12%)', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 12, 12, 'INPUT TAX ALLOWED', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 13, 13, 'PARTICULARS', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 14, 14, 'ASSET AMOUNT', style_table_header_bold) # HEADER worksheet.write_merge(7, 7, 15, 17, 'EXPANDED WITHOLDING TAX', style_table_header_bold) # HEADER worksheet.write(8, 15, 'ATC', style_table_header_bold) # HEADER worksheet.write(8, 16, 'EWT RATE', style_table_header_bold) # HEADER worksheet.write(8, 17, 'AMOUNT', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 18, 18, 'EWT ABSORBED BY COMPANY', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 19, 19, 'ESTIMATED LIFE', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 20, 20, 'MONTHLY DEPRECIATION', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 21, 21, 'JAN', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 22, 22, 'FEB', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 23, 23, 'MAR', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 24, 24, 'APR', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 25, 25, 'MAY', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 26, 26, 'JUN', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 27, 27, 'JUL', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 28, 28, 'AUG', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 29, 29, 'SEP', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 30, 30, 'OCT', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 31, 31, 'NOV', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 32, 32, 'DEC', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 33, 33, 'TOTAL', style_table_header_bold) # HEADER worksheet.write_merge(7, 7, 34, 36, 'ACCUMULATED DEPRECIATION', style_table_header_bold) # HEADER worksheet.write(8, 34, 'BEGINNING', style_table_header_bold) # HEADER worksheet.write(8, 35, 'CURRENT', style_table_header_bold) # HEADER worksheet.write(8, 36, 'TOTAL', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 37, 37, 'BOOK VALUE', style_table_header_bold) # HEADER worksheet.write_merge(7, 8, 38, 38, 'REMARKS', style_table_header_bold) # HEADER # TABLE ROW LINES # table_row_start = 9 row_count = 9 transaction_count = 0 # total_gross_amount = 0 # total_non_vat_amount = 0 # total_net_vat_amount = 0 # total_input_tax_amount = 0 # total_ap_amount = 0 # total_ewt_tax_amount = 0 for account in account_asset: source_type = '' source_no = '' if account.invoice_id: source_type = 'Vendor Bill' source_no = account.invoice_id.name ewt_tax_base = 0 ewt_atc = '' ewt_rate = 0 ewt_tax_amount = 0 input_tax_amount = 0 estimated_life = 0 if account.category_id.method_number and account.category_id.method_period: account.method_number * account.method_period monthly_value = 0 beginning_value = 0 current_value = 0 total_value = 0 jan_value = 0 feb_value = 0 mar_value = 0 apr_value = 0 may_value = 0 jun_value = 0 jul_value = 0 aug_value = 0 sep_value = 0 oct_value = 0 nov_value = 0 dec_value = 0 for line in account.depreciation_line_ids: month_today = date.today().strftime('%m') if line.sequence == 1: monthly_value = line.amount beginning_value = line.depreciated_value if month_today == '01': jan_value += line.amount if month_today == '02': feb_value += line.amount if month_today == '03': mar_value += line.amount if month_today == '04': apr_value += line.amount if month_today == '05': may_value += line.amount if month_today == '06': jun_value += line.amount if month_today == '07': jul_value += line.amount if month_today == '08': aug_value += line.amount if month_today == '09': sep_value += line.amount if month_today == '10': oct_value += line.amount if month_today == '11': nov += line.amount if month_today == '12': dec_value += line.amount worksheet.write(row_count, 0, account.date, style_table_row) worksheet.write(row_count, 1, account.category_id.journal_id.name, style_table_row) worksheet.write(row_count, 2, '', style_table_row) worksheet.write(row_count, 3, account.partner_id.name or '', style_table_row) worksheet.write( row_count, 4, '%s %s %s %s %s %s' % (account.partner_id.street or '', account.partner_id.street2 or '', account.partner_id.city or '', account.partner_id.state_id.name or '', account.partner_id.zip or '', account.partner_id.country_id.name or ''), style_table_row) worksheet.write(row_count, 5, account.partner_id.vat or '', style_table_row) worksheet.write(row_count, 6, source_type, style_table_row) worksheet.write(row_count, 7, source_no, style_table_row) worksheet.write(row_count, 8, account.value, style_table_row_amount) worksheet.write(row_count, 9, '', style_table_row_amount) worksheet.write(row_count, 10, '', style_table_row_amount) worksheet.write(row_count, 11, input_tax_amount, style_table_row_amount) worksheet.write(row_count, 12, '', style_table_row_amount) worksheet.write(row_count, 13, '', style_table_row) worksheet.write(row_count, 14, account.value, style_table_row_amount) worksheet.write(row_count, 15, ewt_atc or '', style_table_row) worksheet.write(row_count, 16, ewt_rate, style_table_row_amount) worksheet.write(row_count, 17, ewt_tax_amount, style_table_row_amount) worksheet.write(row_count, 18, '', style_table_row_amount) worksheet.write(row_count, 19, estimated_life, style_table_row_amount) worksheet.write(row_count, 20, monthly_value, style_table_row_amount) worksheet.write(row_count, 21, jan_value, style_table_row_amount) worksheet.write(row_count, 22, feb_value, style_table_row_amount) worksheet.write(row_count, 23, mar_value, style_table_row_amount) worksheet.write(row_count, 24, apr_value, style_table_row_amount) worksheet.write(row_count, 25, mar_value, style_table_row_amount) worksheet.write(row_count, 26, jun_value, style_table_row_amount) worksheet.write(row_count, 27, jul_value, style_table_row_amount) worksheet.write(row_count, 28, aug_value, style_table_row_amount) worksheet.write(row_count, 29, sep_value, style_table_row_amount) worksheet.write(row_count, 30, oct_value, style_table_row_amount) worksheet.write(row_count, 31, nov_value, style_table_row_amount) worksheet.write(row_count, 32, dec_value, style_table_row_amount) worksheet.write(row_count, 33, account.value_residual, style_table_row_amount) worksheet.write(row_count, 34, beginning_value, style_table_row_amount) worksheet.write(row_count, 35, current_value, style_table_row_amount) worksheet.write(row_count, 36, total_value, style_table_row_amount) worksheet.write(row_count, 37, total_value, style_table_row_amount) worksheet.write(row_count, 38, '', style_table_row_amount) row_count += 1 transaction_count += 1 # total_gross_amount += account.amount_total # total_non_vat_amount += account.vat_exempt_sales # total_net_vat_amount += account.vat_sales # total_input_tax_amount += input_tax_amount # total_ap_amount += account.amount_total # total_ewt_tax_amount += ewt_tax_amount table_total_start = row_count # for account_id in account_ids: # accounts_asset = request.env['account.move.line'].search([('account_id', '=', account_id.id)]) # for account in accounts_asset: # ewt_tax_base = 0 # ewt_atc = '' # ewt_rate = 0 # ewt_tax_amount = 0 # input_tax_amount = 0 # has_ewt = False # for tax in account.tax_line_ids: # if tax.account_id.id == account_ewt.id: # has_ewt = True # ewt_tax_base = tax.base # ewt_atc = tax.tax_id.ewt_structure_id.name # ewt_rate = tax.tax_id.amount # ewt_tax_amount = tax.amount_total # else: # if tax.amount == 12.00: # input_tax_amount = tax.amount_total # worksheet.write(row_count, 0, account.date, style_table_row) # worksheet.write(row_count, 1, account.journal_id.name, style_table_row) # worksheet.write(row_count, 2, account.name, style_table_row) # worksheet.write(row_count, 3, account.partner_id.name, style_table_row) # worksheet.write(row_count, 4, '%s %s %s %s %s %s'%(account.partner_id.street or '',account.partner_id.street2 or '',account.partner_id.city or '',account.partner_id.state_id.name or '',account.partner_id.zip or '',account.partner_id.country_id.name or ''), style_table_row) # worksheet.write(row_count, 5, account.partner_id.vat or '', style_table_row) # worksheet.write(row_count, 6, '', style_table_row) # worksheet.write(row_count, 7, account.origin or '', style_table_row) # worksheet.write(row_count, 8, account.amount_total, style_table_row_amount) # worksheet.write(row_count, 9, account.vat_exempt_sales, style_table_row_amount) # worksheet.write(row_count, 10, account.vat_sales, style_table_row_amount) # worksheet.write(row_count, 11, input_tax_amount, style_table_row_amount) # worksheet.write(row_count, 12, '', style_table_row_amount) # worksheet.write(row_count, 13, account.x_description or '', style_table_row) # worksheet.write(row_count, 14, account.amount_total, style_table_row_amount) # worksheet.write(row_count, 15, ewt_atc or '', style_table_row) # worksheet.write(row_count, 16, ewt_rate, style_table_row_amount) # worksheet.write(row_count, 17, ewt_tax_amount, style_table_row_amount) # worksheet.write(row_count, 18, '', style_table_row_amount) # row_count +=1 # transaction_count +=1 # total_gross_amount += account.amount_total # total_non_vat_amount += account.vat_exempt_sales # total_net_vat_amount += account.vat_sales # total_input_tax_amount += input_tax_amount # total_ap_amount += account.amount_total # total_ewt_tax_amount += ewt_tax_amount # table_total_start = row_count # TABLE TOTALS worksheet.write_merge(table_total_start, table_total_start, 0, 7, 'TOTAL', style_table_total) worksheet.write(table_total_start, 8, '-', style_table_total_value) worksheet.write(table_total_start, 9, '-', style_table_total_value) worksheet.write(table_total_start, 10, '-', style_table_total_value) worksheet.write(table_total_start, 11, '-', style_table_total_value) worksheet.write(table_total_start, 12, '', style_table_total_value) worksheet.write(table_total_start, 13, '', style_table_total_value) worksheet.write(table_total_start, 14, '-', style_table_total_value) worksheet.write(table_total_start, 15, '', style_table_total_value) worksheet.write(table_total_start, 16, '', style_table_total_value) worksheet.write(table_total_start, 17, '-', style_table_total_value) worksheet.write(table_total_start, 18, '', style_table_total_value) worksheet.write(table_total_start, 19, '', style_table_total_value) worksheet.write(table_total_start, 20, '', style_table_total_value) worksheet.write(table_total_start, 21, '', style_table_total_value) worksheet.write(table_total_start, 22, '', style_table_total_value) worksheet.write(table_total_start, 23, '', style_table_total_value) worksheet.write(table_total_start, 24, '', style_table_total_value) worksheet.write(table_total_start, 25, '', style_table_total_value) worksheet.write(table_total_start, 26, '', style_table_total_value) worksheet.write(table_total_start, 27, '', style_table_total_value) worksheet.write(table_total_start, 28, '', style_table_total_value) worksheet.write(table_total_start, 29, '', style_table_total_value) worksheet.write(table_total_start, 30, '', style_table_total_value) worksheet.write(table_total_start, 31, '', style_table_total_value) worksheet.write(table_total_start, 32, '', style_table_total_value) worksheet.write(table_total_start, 33, '', style_table_total_value) worksheet.write(table_total_start, 34, '', style_table_total_value) worksheet.write(table_total_start, 35, '', style_table_total_value) worksheet.write(table_total_start, 36, '', style_table_total_value) worksheet.write(table_total_start, 37, '', style_table_total_value) worksheet.write(table_total_start, 38, '', style_table_total_value) # worksheet.write(0, 18, 'No. of Transaction: %s'%(transaction_count), style_header_right) # worksheet.write(1, 18, 'Date Processed: %s'%(date_processed), style_header_right) # worksheet.write(2, 18, 'Processed By: %s'%(user_id), style_header_right) response = request.make_response( None, headers=[('Content-Type', 'application/vnd.ms-excel'), ('Content-Disposition', 'attachment; filename=%s;' % (filename))]) workbook.save(response.stream) return response
def attachment_add(self, name, file, res_model, res_id, access_token=None, **kwargs): """Process a file uploaded from the portal chatter and create the corresponding `ir.attachment`. The attachment will be created "pending" until the associated message is actually created, and it will be garbage collected otherwise. :param name: name of the file to save. :type name: string :param file: the file to save :type file: werkzeug.FileStorage :param res_model: name of the model of the original document. To check access rights only, it will not be saved here. :type res_model: string :param res_id: id of the original document. To check access rights only, it will not be saved here. :type res_id: int :param access_token: access_token of the original document. To check access rights only, it will not be saved here. :type access_token: string :return: attachment data {id, name, mimetype, file_size, access_token} :rtype: dict """ try: self._document_check_access(res_model, int(res_id), access_token=access_token) except (AccessError, MissingError) as e: raise UserError( _("The document does not exist or you do not have the rights to access it." )) IrAttachment = request.env['ir.attachment'] access_token = False # Avoid using sudo or creating access_token when not necessary: internal # users can create attachments, as opposed to public and portal users. if not request.env.user.has_group('base.group_user'): IrAttachment = IrAttachment.sudo().with_context( binary_field_real_user=IrAttachment.env.user) access_token = IrAttachment._generate_access_token() # At this point the related message does not exist yet, so we assign # those specific res_model and res_is. They will be correctly set # when the message is created: see `portal_chatter_post`, # or garbage collected otherwise: see `_garbage_collect_attachments`. attachment = IrAttachment.create({ 'name': name, 'datas': base64.b64encode(file.read()), 'res_model': 'mail.compose.message', 'res_id': 0, 'access_token': access_token, }) return request.make_response(data=json.dumps( attachment.read( ['id', 'name', 'mimetype', 'file_size', 'access_token'])[0]), headers=[('Content-Type', 'application/json')])
def make_json_response(self, data, headers=None, cookies=None): data = json.dumps(data) if headers is None: headers = {} headers["Content-Type"] = "application/json" return request.make_response(data, headers=headers, cookies=cookies)
def get(self, sub_domain, status, token=None): try: user = request.env['res.users'].sudo().search([('sub_domain', '=', sub_domain)]) if not user: return request.make_response( json.dumps({ 'code': 404, 'msg': error_code[404] })) if not token: return request.make_response( json.dumps({ 'code': 300, 'msg': error_code[300].format('token') })) access_token = request.env( user=user.id)['wechat_mall.access_token'].search([ ('token', '=', token), ('create_uid', '=', user.id) ]) if not access_token: return request.make_response( json.dumps({ 'code': 901, 'msg': error_code[901] })) wechat_user = request.env(user=user.id)['wechat_mall.user'].search( [('open_id', '=', access_token.open_id), ('create_uid', '=', user.id)]) if not wechat_user: return request.make_response( json.dumps({ 'code': 10000, 'msg': error_code[10000] })) user_coupons_list = request.env( user=user.id)['wechat_mall.user.coupons'].search([ ('create_uid', '=', user.id), ]) data = [] for item in user_coupons_list: data.append({ "id": item.id, "user_id": wechat_user.id, "coupons_id": item.coupons_id, "name": item.name, "dateEndType": item.dateEndType, "dateEndDays": item.dateEndDays, "dateEnd": item.dateEnd, "moneyHreshold": item.moneyHreshold, "money": item.moneyMax, "number": item.number, }) response = request.make_response(headers={"Content-Type": "json"}, data=json.dumps({ 'code': 0, 'msg': 'success', 'data': data, })) return response except AttributeError: return request.make_response( json.dumps({ 'code': 404, 'msg': error_code[404] })) except Exception as e: _logger.exception(e) return request.make_response( json.dumps({ 'code': -1, 'msg': error_code[-1], 'data': e.message }))
def export_xlsx(self, data, **kw): jdata = json.loads(data) output = io.BytesIO() workbook = xlsxwriter.Workbook(output, {'in_memory': True}) worksheet = workbook.add_worksheet(jdata['title']) header_bold = workbook.add_format({'bold': True, 'pattern': 1, 'bg_color': '#AAAAAA'}) header_plain = workbook.add_format({'pattern': 1, 'bg_color': '#AAAAAA'}) bold = workbook.add_format({'bold': True}) measure_count = jdata['measure_count'] origin_count = jdata['origin_count'] # Step 1: writing col group headers col_group_headers = jdata['col_group_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(col_group_headers): worksheet.write(i, 0, '', header_plain) for header in header_row: while (carry and carry[0]['x'] == x): cell = carry.popleft() for j in range(measure_count * (2 * origin_count - 1)): worksheet.write(y, x+j, '', header_plain) if cell['height'] > 1: carry.append({'x': x, 'height': cell['height'] - 1}) x = x + measure_count * (2 * origin_count - 1) for j in range(header['width']): worksheet.write(y, x + j, header['title'] if j == 0 else '', header_plain) 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 j in range(measure_count * (2 * origin_count - 1)): worksheet.write(y, x+j, '', header_plain) if cell['height'] > 1: carry.append({'x': x, 'height': cell['height'] - 1}) x = x + measure_count * (2 * origin_count - 1) x, y = 1, y + 1 # Step 2: writing measure headers measure_headers = jdata['measure_headers'] if measure_headers: worksheet.write(y, 0, '', header_plain) for measure in measure_headers: style = header_bold if measure['is_bold'] else header_plain worksheet.write(y, x, measure['title'], style) for i in range(1, 2 * origin_count - 1): worksheet.write(y, x+i, '', header_plain) x = x + (2 * origin_count - 1) x, y = 1, y + 1 # set minimum width of cells to 16 which is around 88px worksheet.set_column(0, len(measure_headers), 16) # Step 3: writing origin headers origin_headers = jdata['origin_headers'] if origin_headers: worksheet.write(y, 0, '', header_plain) for origin in origin_headers: style = header_bold if origin['is_bold'] else header_plain worksheet.write(y, x, origin['title'], style) x = x + 1 y = y + 1 # Step 4: 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 workbook.close() xlsx_data = output.getvalue() filename = osutil.clean_filename(_("Pivot %(title)s (%(model_name)s)", title=jdata['title'], model_name=jdata['model'])) response = request.make_response(xlsx_data, headers=[('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'), ('Content-Disposition', content_disposition(filename + '.xlsx'))], ) return response
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=Order.access_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']: domain = expression.AND( [[ '&', ('website_published', '=', True), ('company_id', '=', order_sudo.company_id.id) ], [ '|', ('specific_countries', '=', False), ('country_ids', 'in', [order_sudo.partner_id.country_id.id]) ]]) acquirers = request.env['payment.acquirer'].sudo().search(domain) 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)
def res_ok(self, data=None): ret = {'code': 0, 'msg': 'success'} if data: ret['data'] = data return request.make_response(headers={'Content-Type': 'json'}, data=json.dumps(ret))
def res_err(self, code, data=None): ret = {'code': code, 'msg': error_code[code] or data} if data: ret['data'] = data return request.make_response(json.dumps(ret))
def export_xls(self, data, token): jdata = json.loads(data) 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;") measure_count = jdata['measure_count'] origin_count = jdata['origin_count'] # Step 1: writing col group headers col_group_headers = jdata['col_group_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(col_group_headers): worksheet.write(i, 0, '', header_plain) for header in header_row: while (carry and carry[0]['x'] == x): cell = carry.popleft() for j in range(measure_count * (2 * origin_count - 1)): worksheet.write(y, x + j, '', header_plain) if cell['height'] > 1: carry.append({'x': x, 'height': cell['height'] - 1}) x = x + measure_count * (2 * origin_count - 1) for j in range(header['width']): worksheet.write(y, x + j, header['title'] if j == 0 else '', header_plain) 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 j in range(measure_count * (2 * origin_count - 1)): worksheet.write(y, x + j, '', header_plain) if cell['height'] > 1: carry.append({'x': x, 'height': cell['height'] - 1}) x = x + measure_count * (2 * origin_count - 1) x, y = 1, y + 1 # Step 2: writing measure headers measure_headers = jdata['measure_headers'] if measure_headers: worksheet.write(y, 0, '', header_plain) for measure in measure_headers: style = header_bold if measure['is_bold'] else header_plain worksheet.write(y, x, measure['title'], style) for i in range(1, 2 * origin_count - 1): worksheet.write(y, x + i, '', header_plain) x = x + (2 * origin_count - 1) x, y = 1, y + 1 # Step 3: writing origin headers origin_headers = jdata['origin_headers'] if origin_headers: worksheet.write(y, 0, '', header_plain) for origin in origin_headers: style = header_bold if origin['is_bold'] else header_plain worksheet.write(y, x, origin['title'], style) x = x + 1 y = y + 1 # Step 4: 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
collected_products = product_model.sudo().search([ ('master_product', '=', int(id)) ]) for coll_prod in collected_products: image_model.create({ 'name': ufile.filename, 'product_tmpl_id': coll_prod.id, 'image_id': attachment.id, 'sequence': 0, }) if to_add: coll_prod.with_context({ 'collection_mark': 'collected' }).write({ 'image': datas, 'main_image_attachment_id': attachment.id }) args = { 'filename': ufile.filename, 'mimetype': ufile.content_type, 'id': attachment.id } except Exception, e: args = dict(error=_("Something horrible happened"), message=e.message) _logger.exception("Fail to upload attachment(%s) exception(%s)" % (ufile.filename, e.message)) return request.make_response(json.dumps(args), [('Content-Type', 'application/json')])
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 = json.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') 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)) report = request.env['report']._get_report_from_name( reportname) filename = "%s.%s" % (report.name, "pdf") if docids: ids = [int(x) for x in docids.split(",")] obj = request.env[report.model].browse(ids) if report.print_report_name and not len(obj) > 1: filename = safe_eval(report.print_report_name, { 'object': obj, 'time': time }) response.headers.add('Content-Disposition', content_disposition(filename)) 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': u'系统错误', 'data': se} return request.make_response(html_escape(json.dumps(error)))
def export_xls(self, filename, title, company_id, date_from, date_to, account_id, **kw): company = request.env['res.company'].search([('id', '=', company_id)]) account = request.env['account.account'].search([('id', '=', account_id)]) account_move_lines = request.env['account.move.line'].sudo().search( [('account_id.id', '=', account_id), ('date', '>=', date_from), ('date', '<=', date_to)], order='partner_id asc') date_processed = date.today().strftime('%m-%d-%Y') report_month = datetime.strptime(date_from, '%Y-%m-%d') user_id = request.env.user.name workbook = xlwt.Workbook() worksheet = workbook.add_sheet(title) # STYLES style_header_bold = xlwt.easyxf( "font: bold on;font: name Calibri;align: wrap no") style_header_right = xlwt.easyxf( "font: name Calibri;align: horiz right, wrap no") style_table_header_bold = xlwt.easyxf( "font: bold on;font: name Calibri;align: horiz centre, vert centre, wrap on;borders: top thin, bottom thin, right thin;" ) style_table_row = xlwt.easyxf( "font: name Calibri;align: horiz left, wrap no;borders: top thin, bottom thin, right thin;" ) style_table_row_amount = xlwt.easyxf( "font: name Calibri;align: horiz right, wrap no;borders: top thin, bottom thin, right thin;", num_format_str="#,##0.00") style_table_total = xlwt.easyxf( "pattern: pattern solid, fore_colour pale_blue;font: bold on;font: name Calibri;align: horiz left, wrap no;borders: top thin, bottom medium, right thin;" ) style_table_total_value = xlwt.easyxf( "pattern: pattern solid, fore_colour pale_blue;font: bold on;font: name Calibri;align: horiz right, wrap no;borders: top thin, bottom medium, right thin;", num_format_str="#,##0.00") style_end_report = xlwt.easyxf( "font: bold on;font: name Calibri;align: horiz left, wrap no;") worksheet.col(0).width = 250 * 12 worksheet.col(1).width = 500 * 12 worksheet.col(2).width = 750 * 12 worksheet.col(3).width = 750 * 12 worksheet.col(4).width = 300 * 12 worksheet.col(5).width = 800 * 12 worksheet.col(6).width = 350 * 12 worksheet.col(7).width = 300 * 12 worksheet.col(8).width = 350 * 12 # TEMPLATE HEADERS worksheet.write(0, 0, 'BIR FORM 1601E - SCHEDULE I', style_header_bold) # BIR FORM INFO worksheet.write(1, 0, title, style_header_bold) # TITLE worksheet.write(2, 0, 'FOR THE MONTH OF %s' % (report_month.strftime('%B, %Y')), style_header_bold) # Report Date # worksheet.write(3, 0, account_id, style_header_bold) # Report Date # worksheet.write(4, 0, account_move_lines, style_header_bold) # Report Date worksheet.write(5, 0, 'TIN: %s' % (company.vat), style_header_bold) # Company Name worksheet.write(6, 0, "WITHHOLDING AGENT'S NAME: %s" % (company.name), style_header_bold) # Company TIN # TABLE HEADER worksheet.write(9, 0, 'SEQ NO', style_table_header_bold) # HEADER worksheet.write(9, 1, 'TAXPAYER IDENTIIFICATION NUMBER', style_table_header_bold) # HEADER worksheet.write(9, 2, 'CORPORATION (Registered Name)', style_table_header_bold) # HEADER worksheet.write(9, 3, 'INDIVIDUAL (Last Name, First Name, Middle Name)', style_table_header_bold) # HEADER worksheet.write(9, 4, 'ATC CODE', style_table_header_bold) # HEADER worksheet.write(9, 5, 'NATURE OF PAYMENT', style_table_header_bold) # HEADER worksheet.write(9, 6, 'AMOUNT OF INCOME PAYMENT', style_table_header_bold) # HEADER worksheet.write(9, 7, 'TAX RATE', style_table_header_bold) # HEADER worksheet.write(9, 8, 'AMOUNT OF TAX WITHHELD', style_table_header_bold) # HEADER # TABLE ROW LINES row_count = 10 seq_count = 1 registered_name = '' customer_name = '' amount_income = 0 amount_tax = 0 total_amount_tax = 0 payment_nature = '' for account in account_move_lines: if account.partner_id.company_type == 'company': registered_name = account.partner_id.name customer_name = '' else: registered_name = account.partner_id.parent_id.name customer_name = account.partner_id.name if not account.partner_id.parent_id: registered_name = account.partner_id.name customer_name = '' for tax in account.invoice_id.tax_line_ids: if tax.account_id == account.account_id: amount_income = tax.base amount_tax = tax.amount_total if amount_tax <= 0: if account.debit > 0: amount_tax = account.debit else: amount_tax = account.credit # GET NATURE OF PAYMENT if account.invoice_id: payment_nature = account.invoice_id.x_description worksheet.write(row_count, 0, seq_count, style_table_row) worksheet.write(row_count, 1, account.partner_id.vat or '', style_table_row) worksheet.write(row_count, 2, registered_name, style_table_row) worksheet.write(row_count, 3, customer_name, style_table_row) worksheet.write(row_count, 4, account.tax_line_id.ewt_structure_id.name or '', style_table_row) worksheet.write(row_count, 5, payment_nature, style_table_row) worksheet.write(row_count, 6, amount_income, style_table_row_amount) worksheet.write(row_count, 7, account.tax_line_id.amount, style_table_row_amount) worksheet.write(row_count, 8, amount_tax, style_table_row_amount) row_count += 1 seq_count += 1 total_amount_tax += amount_tax table_total_start = row_count end_report = table_total_start + 2 # TABLE TOTALS worksheet.write_merge(table_total_start, table_total_start, 0, 7, 'GRAND TOTAL', style_table_total) worksheet.write(table_total_start, 8, total_amount_tax, style_table_total_value) worksheet.write(end_report, 0, 'END OF REPORT', style_end_report) response = request.make_response( None, headers=[('Content-Type', 'application/vnd.ms-excel'), ('Content-Disposition', 'attachment; filename=%s;' % (filename))]) workbook.save(response.stream) return response
def get_post_method(self, **kw): return request.make_response('get_post')
def test_company_context(self): return request.make_response( json.dumps(request.context.get('allowed_company_ids')))
def get(self, sub_domain, coupons_id, token=None): try: user = request.env['res.users'].sudo().search([('sub_domain', '=', sub_domain)]) if not user: return request.make_response( json.dumps({ 'code': 404, 'msg': error_code[404] })) if not token: return request.make_response( json.dumps({ 'code': 300, 'msg': error_code[300].format('token') })) access_token = request.env( user=user.id)['wechat_mall.access_token'].search([ ('token', '=', token), ('create_uid', '=', user.id) ]) if not access_token: return request.make_response( json.dumps({ 'code': 901, 'msg': error_code[901] })) wechat_user = request.env(user=user.id)['wechat_mall.user'].search( [('open_id', '=', access_token.open_id), ('create_uid', '=', user.id)]) if not wechat_user: return request.make_response( json.dumps({ 'code': 10000, 'msg': error_code[10000] })) # 是否有剩余 coupons = request.env(user=user.id)['wechat_mall.coupons'].search([ ('create_uid', '=', user.id), ('id', '=', coupons_id) ]) if not coupons: response = request.make_response( headers={"Content-Type": "json"}, data=json.dumps({ 'code': 20001, 'msg': 'failed', })) return response # 是否已过期 if coupons.dateEndType == 'deadline' and coupons.dateEnd > fields.datetime.now( ): response = request.make_response( headers={"Content-Type": "json"}, data=json.dumps({ 'code': 20004, 'msg': 'failed', })) return response # 是否已领过 user_coupons = request.env( user=user.id)['wechat_mall.user.coupons'].search([ ('create_uid', '=', user.id), ('coupons_id', '=', coupons_id) ]) if user_coupons: if user_coupons.number > coupons.numberPersonMax: response = request.make_response( headers={"Content-Type": "json"}, data=json.dumps({ 'code': 20003, 'msg': 'failed', })) return response else: # 领成功了 user_coupons.write({'number': user_coupons.number + 1}) else: # 领成功了 request.env(user=user.id)['wechat_mall.user.coupons'].create({ "user_id": wechat_user.id, "coupons_id": coupons.id, "name": coupons.name, "dateEndType": coupons.dateEndType, "dateEndDays": coupons.dateEndDays, "dateEnd": coupons.dateEnd, "moneyHreshold": coupons.moneyHreshold, "moneyMax": coupons.moneyMax, "number": 1, }) response = request.make_response(headers={"Content-Type": "json"}, data=json.dumps({ 'code': 0, 'msg': 'success', })) return response except Exception as e: _logger.exception(e) return request.make_response( json.dumps({ 'code': -1, 'msg': error_code[-1], 'data': e.message }))
def test_ignore_args_converter_nokw(self, a, b='youhou'): return request.make_response(json.dumps(dict(a=a, b=b)))
def action_mes_inventory_export(self, meslineid, firstinventoryid, lastinventoryid): tempdomain = [('id', '>=', firstinventoryid), ('id', '<=', lastinventoryid), ('isproductionline', '=', True)] if meslineid: tempdomain.append(('mesline_id', '=', meslineid)) inventorylist = request.env['aas.stock.inventory'].search(tempdomain) workbook = xlwt.Workbook(style_compression=2) worksheet = workbook.add_sheet(u'库存盘点') base_style = xlwt.easyxf('align: wrap yes') worksheet.write(0, 0, u'产线名称', base_style) worksheet.write(0, 1, u'盘点名称', base_style) worksheet.write(0, 2, u'盘点时间', base_style) worksheet.write(0, 3, u'盘点库位', base_style) worksheet.write(0, 4, u'盘点产品', base_style) worksheet.write(0, 5, u'客户料号', base_style) worksheet.write(0, 6, u'盘点批次', base_style) worksheet.write(0, 7, u'账存数量', base_style) worksheet.write(0, 8, u'实盘数量', base_style) worksheet.write(0, 9, u'差异数量', base_style) rowindex = 1 if inventorylist and len(inventorylist) > 0: for tinventory in inventorylist: if not tinventory.inventory_lines or len( tinventory.inventory_lines) <= 0: continue for invenline in tinventory.inventory_lines: product = invenline.product_id customercode = '' if not product.customer_product_code else product.customer_product_code worksheet.write(rowindex, 0, tinventory.mesline_id.name, base_style) worksheet.write(rowindex, 1, tinventory.name, base_style) worksheet.write( rowindex, 2, fields.Datetime.to_china_string( tinventory.create_time), base_style) worksheet.write(rowindex, 3, invenline.location_id.name, base_style) worksheet.write(rowindex, 4, product.default_code, base_style) worksheet.write(rowindex, 5, customercode, base_style) worksheet.write(rowindex, 6, invenline.product_lot.name, base_style) worksheet.write(rowindex, 7, invenline.stock_qty, base_style) worksheet.write(rowindex, 8, invenline.actual_qty, base_style) worksheet.write(rowindex, 9, invenline.differ_qty, base_style) rowindex += 1 stream = StringIO() workbook.save(stream) outvalues = stream.getvalue() timestr = fields.Datetime.to_china_string(fields.Datetime.now()) filename = 'Inventory %s' % timestr.replace('-', '').replace( ':', '').replace(' ', '') xlshttpheaders = [('Content-Type', 'application/vnd.ms-excel'), ('Content-Length', len(outvalues)), ('Content-Disposition', 'attachment; filename=%s.xls;' % filename)] return request.make_response(outvalues, headers=xlshttpheaders)
def test_ignore_args_converter(self, a, b='youhou', **kw): return request.make_response(json.dumps(dict(a=a, b=b, kw=kw)))
def _make_pdf_response(self, file, filename): headers = [('Content-Type', 'application/pdf'), ('Content-Disposition', 'attachment; filename="{}";'.format(filename)), ('Content-Length', len(file))] return request.make_response(file, headers)
def test_ignore_args_kw(self, a, **kw): return request.make_response(json.dumps(dict(a=a, kw=kw)))
def check_data(self, **post): """ Checks that the form data submitted is not a doublon """ if 'inst_type' not in post: result = {'error': _('Missing inst_type parameter')} return request.make_response(json.dumps(result), headers=HEADERS) if post['inst_type'] not in ['service', 'base']: result = { 'error': _('Incorrect inst_type parameter: {0}').format( post['inst_type']) } return request.make_response(json.dumps(result), headers=HEADERS) # Checking data errors for service requests if post['inst_type'] == 'service': # Check that the required data has been passed if ('environment_id' not in post and 'environment_prefix' not in post) or \ 'suffix' not in post: result = { 'error': _('Prefix and either environment_id or ' 'environment_prefix are required.') } return \ request.make_response(json.dumps(result), headers=HEADERS) # Check that the required data is not empty if (not post['environment_id'] and not post['environment_prefix']) or not post['suffix']: result = { 'error': _('Prefix and either environment_id or ' 'environment_prefix should not be empty.') } return \ request.make_response(json.dumps(result), headers=HEADERS) # If we have an ID if post['environment_id']: # Check that the ID is valid try: int(post['environment_id']) except ValueError: result = { 'error': _('Invalid environment_id: {0}.').format( post['environment_id']) } return request.make_response(json.dumps(result), headers=HEADERS) orm_cont = request.env['clouder.service'].sudo() # Searching for existing services with # the environment and suffix result = orm_cont.search([('environment_id', '=', int(post['environment_id'])), ('suffix', '=', post['suffix'])]) # If a service is found, return an error for those fields if result: result = { 'next_step_validated': False, 'suffix': False, 'environment_id': False, 'message': _('Container name already un use ' 'for this environment.') + _('<br/>Please change the environment or suffix.') } return request.make_response(json.dumps(result), headers=HEADERS) # Otherwise, search for sessions that already reserved the name orm_clws = request.env['clouder.web.session'].sudo() result = orm_clws.search([('environment_id', '=', int(post['environment_id'])), ('suffix', '=', post['suffix'])]) # If there is such a session, invalidate data if result: result = { 'next_step_validated': False, 'suffix': False, 'environment_id': False, 'message': _('Container suffix already reserved ' 'for this environment.') + _('<br/>Please change the environment or suffix.') } return request.make_response(json.dumps(result), headers=HEADERS) # No problem detected result = { 'next_step_validated': True, 'suffix': True, 'environment_id': True, 'message': False } return request.make_response(json.dumps(result), headers=HEADERS) else: # Check that the environment prefix is not already attributed orm_env = request.env['clouder.environment'].sudo() result = orm_env.search([('prefix', '=', post['environment_prefix'])]) if result: result = { 'environment_prefix': False, 'message': _('Environment prefix already in use.') + _('<br/>Please use a different environment ' 'or environment prefix.') } return request.make_response(json.dumps(result), headers=HEADERS) # Check that the environment prefix is not already reserved orm_clws = request.env['clouder.web.session'].sudo() orm_app = request.env['clouder.application'].sudo() app_ids = [ app.id for app in orm_app.search([('web_create_type', '=', 'service')]) ] result = orm_clws.search([('application_id', 'in', app_ids), ('environment_id', '=', False), ('environment_prefix', '=', post['environment_prefix'])]) if result: result = { 'environment_prefix': False, 'message': _('Environment prefix already reserved.') + _('<br/>Please use a different environment ' 'or environment prefix.') } return request.make_response(json.dumps(result), headers=HEADERS) # No problem detected result = { 'next_step_validated': True, 'environment_prefix': True, 'message': False } return request.make_response(json.dumps(result), headers=HEADERS) # Check data for base request elif post['inst_type'] == 'base': if 'domain_id' not in post or 'prefix' not in post: result = {'error': _('Missing argument for check.')} return request.make_response(json.dumps(result), headers=HEADERS) # Check that the prefix is not already in use for this domain orm_base = request.env['clouder.base'].sudo() result = orm_base.search([('domain_id', '=', int(post['domain_id'])), ('name', '=', post['prefix'])]) if result: result = { 'next_step_validated': False, 'domain_id': False, 'prefix': False, 'message': _('Base prefix is already in use for this domain.') + _('<br/>Please change the prefix or domain.') } return request.make_response(json.dumps(result), headers=HEADERS) # Check that the prefix/domain combination is not already reserved orm_clws = request.env['clouder.web.session'].sudo() orm_app = request.env['clouder.application'].sudo() app_ids = [ app.id for app in orm_app.search([('web_create_type', '=', 'base')]) ] result = orm_clws.search([('application_id', 'in', app_ids), ('domain_id', '=', int(post['domain_id'])), ('prefix', '=', post['prefix'])]) if result: result = { 'next_step_validated': False, 'domain_id': False, 'prefix': False, 'message': _('Base prefix is already in ' 'reserved for this domain.') + _('<br/>Please change the prefix or domain.') } return request.make_response(json.dumps(result), headers=HEADERS) # No problem detected result = { 'next_step_validated': True, 'domain_id': True, 'prefix': True, 'message': False } return request.make_response(json.dumps(result), headers=HEADERS)
def test_ignore_args_a(self, a): return request.make_response(json.dumps(dict(a=a, kw=None)))
def shape(self, module, filename, **kwargs): """ Returns a color-customized svg (background shape or illustration). """ svg = None if module == 'illustration': attachment = request.env['ir.attachment'].sudo().browse( unslug(filename)[1]) if (not attachment.exists() or attachment.type != 'binary' or not attachment.public or not attachment.url.startswith(request.httprequest.path)): raise werkzeug.exceptions.NotFound() svg = b64decode(attachment.datas).decode('utf-8') else: shape_path = get_resource_path(module, 'static', 'shapes', filename) if not shape_path: raise werkzeug.exceptions.NotFound() with tools.file_open(shape_path, 'r') as file: svg = file.read() user_colors = [] for key, value in kwargs.items(): colorMatch = re.match('^c([1-5])$', key) if colorMatch: # Check that color is hex or rgb(a) to prevent arbitrary injection if not re.match( r'(?i)^#[0-9A-F]{6,8}$|^rgba?\(\d{1,3},\d{1,3},\d{1,3}(?:,[0-9.]{1,4})?\)$', value.replace(' ', '')): raise werkzeug.exceptions.BadRequest() user_colors.append( [tools.html_escape(value), colorMatch.group(1)]) elif key == 'flip': if value == 'x': svg = svg.replace('<svg ', '<svg style="transform: scaleX(-1);" ') elif value == 'y': svg = svg.replace('<svg ', '<svg style="transform: scaleY(-1)" ') elif value == 'xy': svg = svg.replace('<svg ', '<svg style="transform: scale(-1)" ') default_palette = { '1': '#3AADAA', '2': '#7C6576', '3': '#F6F6F6', '4': '#FFFFFF', '5': '#383E45', } color_mapping = { default_palette[palette_number]: color for color, palette_number in user_colors } # create a case-insensitive regex to match all the colors to replace, eg: '(?i)(#3AADAA)|(#7C6576)' regex = '(?i)%s' % '|'.join('(%s)' % color for color in color_mapping.keys()) def subber(match): key = match.group().upper() return color_mapping[key] if key in color_mapping else key svg = re.sub(regex, subber, svg) return request.make_response(svg, [ ('Content-type', 'image/svg+xml'), ('Cache-control', 'max-age=%s' % http.STATIC_CACHE_LONG), ])
def test_ignore_args_none(self): return request.make_response(json.dumps(dict(a=None, kw=None)))
def return_web_pdf_view(self, pdf=None): pdfhttpheaders = [('Content-Type', 'application/pdf'), ('Content-Length', u'%s' % len(pdf))] return request.make_response(pdf, headers=pdfhttpheaders)
def get_post_method_no_multilang(self, **kw): return request.make_response('get_post_nomultilang')
def sitemap_xml_index(self): 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': content.encode('base64'), '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 = sitemap.datas.decode('base64') 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.with_context( use_public_user=True).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 = map( lambda p: "%d-%d" % (current_website.id, p), 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)])
def status_http(self, debug=None, **kwargs): resp = """ <!DOCTYPE HTML> <html> <head> <title>Odoo'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', })