def url_for(path_or_uri, lang=None): current_path = request.httprequest.path # should already be text location = pycompat.to_text(path_or_uri).strip() force_lang = lang is not None url = werkzeug.urls.url_parse(location) if not url.netloc and not url.scheme and (url.path or force_lang): location = werkzeug.urls.url_join(current_path, location) lang = pycompat.to_text(lang or request.context.get('lang') or 'en_US') langs = [lg[0] for lg in request.env['ir.http']._get_language_codes()] if (len(langs) > 1 or force_lang) and is_multilang_url( location, langs): ps = location.split(u'/') if ps[1] in langs: # Replace the language only if we explicitly provide a language to url_for if force_lang: ps[1] = lang # Remove the default language unless it's explicitly provided elif ps[1] == request.env['ir.http']._get_default_lang().code: ps.pop(1) # Insert the context language or the provided language elif lang != request.env['ir.http']._get_default_lang( ).code or force_lang: ps.insert(1, lang) location = u'/'.join(ps) return location
def _compile_directive_snippet(self, el, options): el.set('t-call', el.attrib.pop('t-snippet')) name = self.env['ir.ui.view'].search([('key', '=', el.attrib.get('t-call'))]).display_name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = u'<div name="%s" data-oe-type="snippet" data-oe-thumbnail="%s">' % ( escape(pycompat.to_text(name)), escape(pycompat.to_text(thumbnail)) ) return [self._append(ast.Str(div))] + self._compile_node(el, options) + [self._append(ast.Str(u'</div>'))]
def _compile_directive_install(self, el, options): if self.user_has_groups('base.group_system'): module = self.env['ir.module.module'].search([('name', '=', el.attrib.get('t-install'))]) if not module or module.state == 'installed': return [] name = el.attrib.get('string') or 'Snippet' thumbnail = el.attrib.pop('t-thumbnail', 'oe-thumbnail') div = u'<div name="%s" data-oe-type="snippet" data-module-id="%s" data-oe-thumbnail="%s"><section/></div>' % ( escape(pycompat.to_text(name)), module.id, escape(pycompat.to_text(thumbnail)) ) return [self._append(ast.Str(div))] else: return []
def charge(env, key, account_token, credit, description=None, credit_template=None): """ Account charge context manager: takes a hold for ``credit`` amount before executing the body, then captures it if there is no error, or cancels it if the body generates an exception. :param str key: service identifier :param str account_token: user identifier :param int credit: cost of the body's operation :param description: a description of the purpose of the charge, the user will be able to see it in their dashboard :type description: str :param credit_template: a QWeb template to render and show to the user if their account does not have enough credits for the requested operation :type credit_template: str """ endpoint = get_endpoint(env) params = { 'account_token': account_token, 'credit': credit, 'key': key, 'description': description, } try: transaction_token = jsonrpc(endpoint + '/iap/1/authorize', params=params) except InsufficientCreditError as e: if credit_template: arguments = json.loads(e.args[0]) arguments['body'] = pycompat.to_text( env['ir.qweb'].render(credit_template)) e.args = (json.dumps(arguments), ) raise e try: transaction = IapTransaction() transaction.credit = credit yield transaction except Exception as e: params = { 'token': transaction_token, 'key': key, } r = jsonrpc(endpoint + '/iap/1/cancel', params=params) raise e else: params = { 'token': transaction_token, 'key': key, 'credit_to_capture': transaction.credit, } r = jsonrpc(endpoint + '/iap/1/capture', params=params) # noqa
def fiscal_pos_map_to_csv(self): writer = pycompat.csv_writer(open('account.fiscal.' 'position.tax.template-%s.csv' % self.suffix, 'wb')) fiscal_pos_map_iterator = self.iter_fiscal_pos_map() keys = next(fiscal_pos_map_iterator) writer.writerow(keys) for row in fiscal_pos_map_iterator: writer.writerow([pycompat.to_text(s) for s in row.values()])
def taxes_to_csv(self): writer = pycompat.csv_writer(open('account.tax.template-%s.csv' % self.suffix, 'wb')) taxes_iterator = self.iter_taxes() keys = next(taxes_iterator) writer.writerow(keys[3:] + ['sequence']) seq = 100 for row in sorted(taxes_iterator, key=lambda r: r['description']): if not _is_true(row['active']): continue seq += 1 if row['parent_id:id']: cur_seq = seq + 1000 else: cur_seq = seq writer.writerow([ pycompat.to_text(v) for v in list(row.values())[3:] ] + [cur_seq])
def tax_codes_to_csv(self): writer = pycompat.csv_writer(open('account.tax.code.template-%s.csv' % self.suffix, 'wb')) tax_codes_iterator = self.iter_tax_codes() keys = next(tax_codes_iterator) writer.writerow(keys) # write structure tax codes tax_codes = {} # code: id for row in tax_codes_iterator: tax_code = row['code'] if tax_code in tax_codes: raise RuntimeError('duplicate tax code %s' % tax_code) tax_codes[tax_code] = row['id'] writer.writerow([pycompat.to_text(v) for v in row.values()]) # read taxes and add leaf tax codes new_tax_codes = {} # id: parent_code def add_new_tax_code(tax_code_id, new_name, new_parent_code): if not tax_code_id: return name, parent_code = new_tax_codes.get(tax_code_id, (None, None)) if parent_code and parent_code != new_parent_code: raise RuntimeError('tax code "%s" already exist with ' 'parent %s while trying to add it with ' 'parent %s' % (tax_code_id, parent_code, new_parent_code)) else: new_tax_codes[tax_code_id] = (new_name, new_parent_code) taxes_iterator = self.iter_taxes() next(taxes_iterator) for row in taxes_iterator: if not _is_true(row['active']): continue if row['child_depend'] and row['amount'] != 1: raise RuntimeError('amount must be one if child_depend ' 'for %s' % row['id']) # base parent base_code = row['BASE_CODE'] if not base_code or base_code == '/': base_code = 'NA' if base_code not in tax_codes: raise RuntimeError('undefined tax code %s' % base_code) if base_code != 'NA': if row['child_depend']: raise RuntimeError('base code specified ' 'with child_depend for %s' % row['id']) if not row['child_depend']: # ... in lux, we have the same code for invoice and refund if base_code != 'NA': assert row['base_code_id:id'], 'missing base_code_id for %s' % row['id'] assert row['ref_base_code_id:id'] == row['base_code_id:id'] add_new_tax_code(row['base_code_id:id'], 'Base - ' + row['name'], base_code) # tax parent tax_code = row['TAX_CODE'] if not tax_code or tax_code == '/': tax_code = 'NA' if tax_code not in tax_codes: raise RuntimeError('undefined tax code %s' % tax_code) if tax_code == 'NA': if row['amount'] and not row['child_depend']: raise RuntimeError('TAX_CODE not specified ' 'for non-zero tax %s' % row['id']) if row['tax_code_id:id']: raise RuntimeError('tax_code_id specified ' 'for tax %s' % row['id']) else: if row['child_depend']: raise RuntimeError('TAX_CODE specified ' 'with child_depend for %s' % row['id']) if not row['amount']: raise RuntimeError('TAX_CODE specified ' 'for zero tax %s' % row['id']) if not row['tax_code_id:id']: raise RuntimeError('tax_code_id not specified ' 'for tax %s' % row['id']) if not row['child_depend'] and row['amount']: # ... in lux, we have the same code for invoice and refund assert row['tax_code_id:id'], 'missing tax_code_id for %s' % row['id'] assert row['ref_tax_code_id:id'] == row['tax_code_id:id'] add_new_tax_code(row['tax_code_id:id'], 'Taxe - ' + row['name'], tax_code) for tax_code_id in sorted(new_tax_codes): name, parent_code = new_tax_codes[tax_code_id] writer.writerow([ tax_code_id, u'lu_tct_m' + parent_code, tax_code_id.replace('lu_tax_code_template_', u''), u'1', u'', pycompat.to_text(name), u'' ])
def record_to_html(self, record, field_name, options): assert options['tagName'] != 'img',\ "Oddly enough, the root tag of an image field can not be img. " \ "That is because the image goes into the tag, or it gets the " \ "hose again." if options.get('qweb_img_raw_data', False): return super(Image, self).record_to_html(record, field_name, options) aclasses = ['img', 'img-responsive'] if options.get( 'qweb_img_responsive', True) else ['img'] aclasses += options.get('class', '').split() classes = ' '.join(pycompat.imap(escape, aclasses)) max_size = None if options.get('resize'): max_size = options.get('resize') else: max_width, max_height = options.get('max_width', 0), options.get( 'max_height', 0) if max_width or max_height: max_size = '%sx%s' % (max_width, max_height) sha = hashlib.sha1(getattr( record, '__last_update').encode('utf-8')).hexdigest()[0:7] max_size = '' if max_size is None else '/%s' % max_size src = '/web/image/%s/%s/%s%s?unique=%s' % (record._name, record.id, field_name, max_size, sha) alt = None if options.get('alt-field') and getattr(record, options['alt-field'], None): alt = escape(record[options['alt-field']]) elif options.get('alt'): alt = options['alt'] src_zoom = None if options.get('zoom') and getattr(record, options['zoom'], None): src_zoom = '/web/image/%s/%s/%s%s?unique=%s' % ( record._name, record.id, options['zoom'], max_size, sha) elif options.get('zoom'): src_zoom = options['zoom'] atts = OrderedDict() atts["src"] = src atts["class"] = classes atts["style"] = options.get('style') atts["alt"] = alt atts["data-zoom"] = src_zoom and u'1' or None atts["data-zoom-image"] = src_zoom atts = self.env['ir.qweb']._post_processing_att( 'img', atts, options.get('template_options')) img = ['<img'] for name, value in atts.items(): if value: img.append(' ') img.append(escape(pycompat.to_text(name))) img.append('="') img.append(escape(pycompat.to_text(value))) img.append('"') img.append('/>') return u''.join(img)