def _parse_import_data(self, data, import_fields, options): # Get fields of type date/datetime all_fields = self.env[self.res_model].fields_get() for name, field in all_fields.iteritems(): if field['type'] in ('date', 'datetime') and name in import_fields: # Parse date index = import_fields.index(name) dt = datetime.datetime server_format = DEFAULT_SERVER_DATE_FORMAT if field['type'] == 'date' else DEFAULT_SERVER_DATETIME_FORMAT if options.get('%s_format' % field['type'], server_format) != server_format: user_format = ustr(options.get('%s_format' % field['type'])).encode('utf-8') for num, line in enumerate(data): if line[index]: try: line[index] = dt.strftime(dt.strptime(ustr(line[index]).encode('utf-8'), user_format), server_format) except ValueError as e: raise ValueError(_("Column %s contains incorrect values. Error in line %d: %s") % (name, num + 1, ustr(e.message))) except Exception as e: raise ValueError(_("Error Parsing Date [%s:L%d]: %s") % (name, num + 1, ustr(e.message))) elif field['type'] in ('float', 'monetary') and name in import_fields: # Parse float, sometimes float values from file have currency symbol or () to denote a negative value # We should be able to manage both case index = import_fields.index(name) self._parse_float_from_data(data, index, name, options) return data
def compile(self, source): command = self.get_command() try: compiler = Popen(command, stdin=PIPE, stdout=PIPE, stderr=PIPE) except Exception: raise CompileError("Could not execute command %r" % command[0]) (out, err) = compiler.communicate(input=source.encode('utf-8')) if compiler.returncode: cmd_output = misc.ustr(out) + misc.ustr(err) if not cmd_output: cmd_output = u"Process exited with return code %d\n" % compiler.returncode raise CompileError(cmd_output) return out.decode('utf8')
def _process_text(self, txt): """Translate ``txt`` according to the language in the local context, replace dynamic ``[[expr]]`` with their real value, then escape the result for XML. :param str txt: original text to translate (must NOT be XML-escaped) :return: translated text, with dynamic expressions evaluated and with special XML characters escaped (``&,<,>``). """ if not self.localcontext: return str2xml(txt) if not txt: return '' result = '' sps = _regex.split(txt) while sps: # This is a simple text to translate to_translate = tools.ustr(sps.pop(0)) result += tools.ustr(self.localcontext.get('translate', lambda x:x)(to_translate)) if sps: txt = None try: expr = sps.pop(0) txt = safe_eval(expr, self.localcontext) if txt and isinstance(txt, basestring): txt = tools.ustr(txt) except Exception: _logger.info("Failed to evaluate expression [[ %s ]] with context %r while rendering report, ignored.", expr, self.localcontext) if isinstance(txt, basestring): result += txt elif txt and (txt is not None) and (txt is not False): result += ustr(txt) return str2xml(result)
def run_rtlcss(self, source): rtlcss = 'rtlcss' cmd = [rtlcss, '-'] try: rtlcss = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except Exception: # Check the presence of rtlcss, if rtlcss not available then we should return normal less file try: process = Popen( ['rtlcss', '--version'], stdout=PIPE, stderr=PIPE ) except (OSError, IOError): _logger.warning('You need rtlcss to convert css file to right to left compatiblity.') return source msg = "Could not execute command %r" % cmd[0] _logger.error(msg) self.css_errors.append(msg) return '' result = rtlcss.communicate(input=source.encode('utf-8')) if rtlcss.returncode: cmd_output = ''.join(misc.ustr(result)) if not cmd_output: cmd_output = "Process exited with return code %d\n" % rtlcss.returncode error = self.get_rtlcss_error(cmd_output, source=source) _logger.warning(error) self.css_errors.append(error) return '' rtlcss_result = result[0].strip().decode('utf8') return rtlcss_result
def compile_css(self, cmd, source): """Sanitizes @import rules, remove duplicates @import rules, then compile""" imports = [] def sanitize(matchobj): ref = matchobj.group(2) line = '@import "%s"%s' % (ref, matchobj.group(3)) if '.' not in ref and line not in imports and not ref.startswith(('.', '/', '~')): imports.append(line) return line msg = "Local import '%s' is forbidden for security reasons." % ref _logger.warning(msg) self.css_errors.append(msg) return '' source = re.sub(self.rx_preprocess_imports, sanitize, source) try: compiler = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except Exception: msg = "Could not execute command %r" % cmd[0] _logger.error(msg) self.css_errors.append(msg) return '' result = compiler.communicate(input=source.encode('utf-8')) if compiler.returncode: cmd_output = ''.join(misc.ustr(result)) if not cmd_output: cmd_output = "Process exited with return code %d\n" % compiler.returncode error = self.get_preprocessor_error(cmd_output, source=source) _logger.warning(error) self.css_errors.append(error) return '' compiled = result[0].strip().decode('utf8') return compiled
def _unsubscribe_check(self, text): url = "/groups/unsubscribe/{}/{}/{}".format( self.mailing_list.id, self.partner.id, self.token ) r = self.url_open(url) body = ustr(r.content) # normalize space to make matching simpler self.assertIn(text, u' '.join(body.split()))
def get_preprocessor_error(self, stderr, source=None): """Improve and remove sensitive information from sass/less compilator error messages""" error = misc.ustr(stderr).split('Load paths')[0].replace(' Use --trace for backtrace.', '') if 'Cannot load compass' in error: error += "Maybe you should install the compass gem using this extra argument:\n\n" \ " $ sudo gem install compass --pre\n" error += "This error occured while compiling the bundle '%s' containing:" % self.name for asset in self.stylesheets: if isinstance(asset, PreprocessedCSS): error += '\n - %s' % (asset.url if asset.url else '<inline sass>') return error
def _parse_import_data(self, data, import_fields, options): # Get fields of type date/datetime all_fields = self.env[self.res_model].fields_get() for name, field in all_fields.iteritems(): if field['type'] in ('date', 'datetime') and name in import_fields: # Parse date index = import_fields.index(name) dt = datetime.datetime server_format = DEFAULT_SERVER_DATE_FORMAT if field['type'] == 'date' else DEFAULT_SERVER_DATETIME_FORMAT if options.get('%s_format' % field['type'], server_format) != server_format: user_format = ustr(options.get('%s_format' % field['type'])).encode('utf-8') for num, line in enumerate(data): if line[index]: try: line[index] = dt.strftime(dt.strptime(ustr(line[index]).encode('utf-8'), user_format), server_format) except ValueError, e: raise ValueError(_("Column %s contains incorrect values. Error in line %d: %s") % (name, num + 1, ustr(e.message))) except Exception, e: raise ValueError(_("Error Parsing Date [%s:L%d]: %s") % (name, num + 1, ustr(e.message)))
def compile_css(self, cmd, source, atype): """Sanitizes @import rules, remove duplicates @import rules, then compile""" imports = [] def handle_compile_error(e, source): error = self.get_preprocessor_error(e, source=source) _logger.warning(error) self.css_errors.append(error) return '' def sanitize(matchobj): ref = matchobj.group(2) line = '@import "%s"%s' % (ref, matchobj.group(3)) if '.' not in ref and line not in imports and not ref.startswith(('.', '/', '~')): imports.append(line) return line if atype == ScssStylesheetAsset: msg = "Local import '%s' is forbidden for security reasons. Please remove all @import \"your_file.scss\" imports in your custom sass files. In Odoo you have to import all sass files in the assets, and not through the @import statement." % ref else: msg = "Local import '%s' is forbidden for security reasons. Please remove all @import \"your_file.less\" imports in your custom less files. In Odoo you have to import all less files in the assets, and not through the @import statement." % ref _logger.warning(msg) self.css_errors.append(msg) return '' source = re.sub(self.rx_preprocess_imports, sanitize, source) if atype == ScssStylesheetAsset: try: path_to_bs = get_resource_path('web', 'static', 'lib', 'bootstrap', 'scss') path_to_bs_components = get_resource_path('web', 'static', 'lib', 'bootstrap', 'scss', 'bootstrap') result = sass.compile( string=source.encode('utf-8'), include_paths=[path_to_bs, path_to_bs_components], output_style='expanded', precision=8, ) compiled = result.strip() except sass.CompileError as e: return handle_compile_error(e, source=source) else: try: compiler = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except Exception: msg = "Could not execute command %r" % cmd[0] _logger.error(msg) self.css_errors.append(msg) return '' result = compiler.communicate(input=source.encode('utf-8')) if compiler.returncode: cmd_output = ''.join(misc.ustr(result)) if not cmd_output: cmd_output = "Process exited with return code %d\n" % compiler.returncode return handle_compile_error(cmd_output, source=source) compiled = result[0].strip().decode('utf8') return compiled
def simple_vat_check(self, country_code, vat_number): ''' Check the VAT number depending of the country. http://sima-pc.com/nif.php ''' if not ustr(country_code).encode('utf-8').isalpha(): return False check_func_name = 'check_vat_' + country_code check_func = getattr(self, check_func_name, None) or getattr(vatnumber, check_func_name, None) if not check_func: # No VAT validation available, default to check that the country code exists if country_code.upper() == 'EU': # Foreign companies that trade with non-enterprises in the EU # may have a VATIN starting with "EU" instead of a country code. return True return bool(self.env['res.country'].search([('code', '=ilike', country_code)])) return check_func(vat_number)
def _create_user_from_template(self, values): template_user_id = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False')) template_user = self.browse(template_user_id) if not template_user.exists(): raise ValueError(_('Signup: invalid template user')) if not values.get('login'): raise ValueError(_('Signup: no login given for new user')) if not values.get('partner_id') or not values.get('name'): raise ValueError(_('Signup: no name or partner given for new user')) # create a copy of the template user (attached to a specific partner_id if given) values['active'] = True try: with self.env.cr.savepoint(): return template_user.with_context(no_reset_password=True).copy(values) except Exception as e: # copy may failed if asked login is not available. raise SignupError(ustr(e))
def _create_user_from_template(self, values): template_user_id = literal_eval( self.env['ir.config_parameter'].sudo().get_param( 'base.template_portal_user_id', 'False')) template_user = self.browse(template_user_id) if not template_user.exists(): raise ValueError(_('Signup: invalid template user')) if not values.get('login'): raise ValueError(_('Signup: no login given for new user')) if not values.get('partner_id') and not values.get('name'): raise ValueError( _('Signup: no name or partner given for new user')) # create a copy of the template user (attached to a specific partner_id if given) values['active'] = True try: with self.env.cr.savepoint(): return template_user.with_context( no_reset_password=True).copy(values) except Exception as e: # copy may failed if asked login is not available. raise SignupError(ustr(e))
def _signup_create_user(self, values): """ create a new user from the template user """ get_param = self.env['ir.config_parameter'].sudo().get_param template_user_id = literal_eval(get_param('auth_signup.template_user_id', 'False')) template_user = self.browse(template_user_id) assert template_user.exists(), 'Signup: invalid template user' # check that uninvited users may sign up if 'partner_id' not in values: if get_param('auth_signup.invitation_scope', 'b2b') != 'b2c': raise SignupError(_('Signup is not allowed for uninvited users')) assert values.get('login'), "Signup: no login given for new user" assert values.get('partner_id') or values.get('name'), "Signup: no name or partner given for new user" # create a copy of the template user (attached to a specific partner_id if given) values['active'] = True try: with self.env.cr.savepoint(): return template_user.with_context(no_reset_password=True).copy(values) except Exception as e: # copy may failed if asked login is not available. raise SignupError(ustr(e))
def _signup_create_user(self, values): """ create a new user from the template user """ IrConfigParam = self.env["ir.config_parameter"] template_user_id = literal_eval(IrConfigParam.get_param("auth_signup.template_user_id", "False")) template_user = self.browse(template_user_id) assert template_user.exists(), "Signup: invalid template user" # check that uninvited users may sign up if "partner_id" not in values: if not literal_eval(IrConfigParam.get_param("auth_signup.allow_uninvited", "False")): raise SignupError("Signup is not allowed for uninvited users") assert values.get("login"), "Signup: no login given for new user" assert values.get("partner_id") or values.get("name"), "Signup: no name or partner given for new user" # create a copy of the template user (attached to a specific partner_id if given) values["active"] = True try: with self.env.cr.savepoint(): return template_user.with_context(no_reset_password=True).copy(values) except Exception, e: # copy may failed if asked login is not available. raise SignupError(ustr(e))
def _signup_create_user(self, values): """ create a new user from the template user """ IrConfigParam = self.env['ir.config_parameter'] template_user_id = literal_eval(IrConfigParam.get_param('auth_signup.template_user_id', 'False')) template_user = self.browse(template_user_id) assert template_user.exists(), 'Signup: invalid template user' # check that uninvited users may sign up if 'partner_id' not in values: if not literal_eval(IrConfigParam.get_param('auth_signup.allow_uninvited', 'False')): raise SignupError('Signup is not allowed for uninvited users') assert values.get('login'), "Signup: no login given for new user" assert values.get('partner_id') or values.get('name'), "Signup: no name or partner given for new user" # create a copy of the template user (attached to a specific partner_id if given) values['active'] = True try: with self.env.cr.savepoint(): return template_user.with_context(no_reset_password=True).copy(values) except Exception, e: # copy may failed if asked login is not available. raise SignupError(ustr(e))
def check_vat_mx(self, vat): ''' Mexican VAT verification Verificar RFC México ''' # we convert to 8-bit encoding, to help the regex parse only bytes vat = ustr(vat).encode('iso8859-1') m = self.__check_vat_mx_re.match(vat) if not m: #No valid format return False try: ano = int(m.group('ano')) if ano > 30: ano = 1900 + ano else: ano = 2000 + ano datetime.date(ano, int(m.group('mes')), int(m.group('dia'))) except ValueError: return False # Valid format and valid date return True
def compile_css(self, cmd, source): """Sanitizes @import rules, remove duplicates @import rules, then compile""" imports = [] def sanitize(matchobj): ref = matchobj.group(2) line = '@import "%s"%s' % (ref, matchobj.group(3)) if '.' not in ref and line not in imports and not ref.startswith( ('.', '/', '~')): imports.append(line) return line msg = "Local import '%s' is forbidden for security reasons." % ref _logger.warning(msg) self.css_errors.append(msg) return '' source = re.sub(self.rx_preprocess_imports, sanitize, source) try: compiler = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE) except Exception: msg = "Could not execute command %r" % cmd[0] _logger.error(msg) self.css_errors.append(msg) return '' result = compiler.communicate(input=source.encode('utf-8')) if compiler.returncode: cmd_output = ''.join(misc.ustr(result)) if not cmd_output: cmd_output = "Process exited with return code %d\n" % compiler.returncode error = self.get_preprocessor_error(cmd_output, source=source) _logger.warning(error) self.css_errors.append(error) return '' compiled = result[0].strip().decode('utf8') return compiled
def _process_text(self, txt): """Translate ``txt`` according to the language in the local context, replace dynamic ``[[expr]]`` with their real value, then escape the result for XML. :param str txt: original text to translate (must NOT be XML-escaped) :return: translated text, with dynamic expressions evaluated and with special XML characters escaped (``&,<,>``). """ if not self.localcontext: return str2xml(txt) if not txt: return '' result = '' sps = _regex.split(txt) while sps: # This is a simple text to translate to_translate = tools.ustr(sps.pop(0)) result += tools.ustr( self.localcontext.get('translate', lambda x: x)(to_translate)) if sps: txt = None try: expr = sps.pop(0) txt = safe_eval(expr, self.localcontext) if txt and isinstance(txt, basestring): txt = tools.ustr(txt) except Exception: _logger.info( "Failed to evaluate expression [[ %s ]] with context %r while rendering report, ignored.", expr, self.localcontext) if isinstance(txt, basestring): result += txt elif txt and (txt is not None) and (txt is not False): result += ustr(txt) return str2xml(result)
def tbai_get_partner_vat_number(self): country_code, vat_number = (self.vat and tbai_utils.split_vat(self.vat) or (None, None)) if not ustr(country_code).encode("utf-8").isalpha(): vat_number = self.vat return vat_number
def create(self, **params): """ This method is used for generating token """ try: grant_type = params.get('grant_type', None) scope = params.get('scope', None) #Need to handle everywhere if not grant_type: info = _("Empty value for grant_type!") _logger.error(info) raise ValidationError(info) if grant_type != 'refresh_token': info = _("Wrong value for grant_type. Value must be refresh_token!") _logger.error(info) raise ValidationError(info) if not scope: info = _("Empty value for scope!") _logger.error(info) raise ValidationError(info) db_name = params.get('db_name', None) refresh_token = params['refresh_token'] if params.get('refresh_token') else None if not refresh_token: info = _("Empty value for refresh_token!") _logger.error(info) raise http.SessionExpiredException(info) if not db_name: db_name = request.httprequest.headers.get('db_name', tools.config.get('db_name', False)) if not db_name: info = _("Empty value for 'db_name'!") _logger.error(info) raise http.SessionExpiredException(_(info)) authorization_header = request.httprequest.headers.get('Authorization') if not authorization_header: authorization_header = request.httprequest.headers.get('HTTP_AUTHORIZATION') if not authorization_header: error_msg = _('The Authorization header is missing') _logger.error(error_msg) raise ValidationError(error_msg) OuthApplication = self.env['rest.oauth.app'] client_id, client_secret = OuthApplication.get_basic_decode_auth_header(authorization_header) if not client_id or not client_secret: error_msg = _('The client_id/client_secret is wrong') _logger.error(error_msg) raise ValidationError(error_msg) oauth_app = OuthApplication.search([('client_id', '=', client_id), ('client_secret', '=', client_secret)]) if not oauth_app: error_msg = _('The client_id/client_secret are not belongs to the registered app!') _logger.error(error_msg) raise ValidationError(error_msg) OuthAppToken = self.env['rest.oauth.app.token'] oauth_app_token = OuthAppToken.check_refresh_token(refresh_token) if not oauth_app_token: info = _("The refresh_token is expired or not found or invalid!") _logger.error(info) raise http.SessionExpiredException(info) user = oauth_app_token.user_id vals = { 'oauth_app_id': oauth_app.id, 'user_id': user.id, } oauth_app_token.action_invalid() oauth_app_token = OuthAppToken.create(vals) oauth_app_token.action_generate_access_token() oauth_app_token.action_generate_refresh_token() token_vals = oauth_app_token.get_token_vals(oauth_app_token.id) return { 'name': _("OK"), 'code': 200, 'description': _("Access token created successfully"), 'data': token_vals, } except Exception as e: if getattr(e, 'args', ()): err = [ustr(a) for a in e.args] err = err[0] err = odoo.tools.exception_to_unicode(err) _logger.exception(err) raise e
def rest_request_auth_code_implicit(self, **kwargs): _logger.info(_("Requested Auth Code Service...")) try: response_type = kwargs.get('response_type', None) client_id = kwargs.get('client_id', None) return_redirect = kwargs.get('return_redirect', True) redirect_uri = kwargs.get('redirect_uri', None) odoo_oauth2client_uri = kwargs.get('odoo_oauth2client_uri', None) scope = kwargs.get('scope', None) state = kwargs.get('state', None) user = request.env.user if None in [response_type, client_id, redirect_uri, scope, state]: error_msg = _( 'The following parameters are must: response_type, client_id, redirect_uri, scope.' ) _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) if response_type not in ['code', 'token']: error_msg = _( 'The value of "response_type" must be either "code" or "token"' ) _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) if return_redirect not in [True, False]: error_msg = _( 'The value of "return_redirect" must be either "True" or "False"' ) _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) redirect_uri = unquote(redirect_uri) OuthApplication = request.env['rest.oauth.app'] oauth_app = OuthApplication.search([('client_id', '=', client_id)]) if not oauth_app: error_msg = _('The "client_id" is wrong') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) auth_redirect_uri = urljoin(redirect_uri, urlparse(redirect_uri).path) auth_redirect_uri = redirect_uri auth_redirect_uris = [ x.strip() for x in oauth_app.auth_redirect_uri.split(',') ] if auth_redirect_uri not in auth_redirect_uris: error_msg = _('The value of "redirect_uri" is wrong') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) OuthAppToken = request.env['rest.oauth.app.token'] OuthAppAuthCode = request.env['rest.oauth.app.auth.code'] vals = { 'oauth_app_id': oauth_app.id, 'user_id': user.id, 'location_uri': redirect_uri, } oauth_app_token = OuthAppToken.create(vals) res = { 'odoo_oauth2client_uri': odoo_oauth2client_uri, 'scope': scope, 'state': state, 'redirect_uri': redirect_uri, } if response_type == 'code' and oauth_app.type_auth_grant == 'auth_code': auth_code_vals = OuthAppAuthCode.generate_auth_vals( oauth_app_token.id) auth_code = auth_code_vals.get('auth_code') res.update({ 'code': auth_code, }) elif response_type == 'token' and oauth_app.type_auth_grant == 'implicit': oauth_app_token.action_generate_access_token() token_vals = oauth_app_token.get_token_vals(oauth_app_token.id) res.update(token_vals) else: error_msg = _('The requested application cant found!') _logger.error(error_msg) return self.generate_response(http_status_codes['not_found'], error_msg) if return_redirect: encoded_params = urls.url_encode(res) redirect_uri = '?'.join([redirect_uri, encoded_params]) _logger.info( _("Requested auth_code redirected to redirect_uri")) return utils.redirect(redirect_uri) else: _logger.info(_("Requested auth_code returned")) return self.generate_response(http_status_codes['created'], res) except Exception as e: if getattr(e, 'args', ()): e = [ustr(a) for a in e.args] e = e[0] error_msg = tools.exception_to_unicode(e) _logger.exception(error_msg) #_logger.error(error_msg) return self.generate_response( http_status_codes['internal_server_error'], error_msg)
def create(self, **params): """ This method is used for generating token """ try: grant_type = params.get('grant_type', None) scope = params.get('scope', None) #Need to handle everywhere if not grant_type: info = _("Empty value for grant_type!") _logger.error(info) raise ValidationError(info) if grant_type != 'password': info = _("Wrong value for grant_type. Value must be password!") _logger.error(info) raise ValidationError(info) if not scope: info = _("Empty value for scope!") _logger.error(info) raise ValidationError(info) db_name = params.get('db_name', None) username = params['username'] if params.get('username') else None password = params['password'] if params.get('password') else None if not db_name: db_name = request.httprequest.headers.get( 'db_name', tools.config.get('db_name', False)) if not username or not password: info = _("Empty value for 'username' or 'password'!") _logger.error(info) raise http.SessionExpiredException(info) if not db_name: info = _("Empty value for 'db_name'!") _logger.error(info) raise http.SessionExpiredException(_(info)) authorization_header = request.httprequest.headers.get( 'Authorization') if not authorization_header: authorization_header = request.httprequest.headers.get( 'HTTP_AUTHORIZATION') if not authorization_header: error_msg = _('The Authorization header is missing') _logger.error(error_msg) raise ValidationError(error_msg) OuthApplication = self.env['rest.oauth.app'] client_id, client_secret = OuthApplication.get_basic_decode_auth_header( authorization_header) if not client_id or not client_secret: error_msg = _('The client_id/client_secret is wrong') _logger.error(error_msg) raise ValidationError(error_msg) oauth_app = OuthApplication.search([('client_id', '=', client_id), ('client_secret', '=', client_secret)]) if not oauth_app: error_msg = _( 'The client_id/client_secret are not belongs to the registered app!' ) _logger.error(error_msg) raise ValidationError(error_msg) try: request.session.authenticate(db_name, username, password) except Exception as e: err = odoo.tools.exception_to_unicode(e) _logger.exception(err) raise http.SessionExpiredException( _("Wrong login/password (%s") % (err)) uid = request.session.uid if uid: OuthAppToken = request.env['rest.oauth.app.token'] user = self.env['res.users'].sudo().browse(uid) vals = { 'oauth_app_id': oauth_app.id, 'user_id': user.id, } oauth_app_token = OuthAppToken.create(vals) oauth_app_token.action_generate_access_token() oauth_app_token.action_generate_refresh_token() token_vals = oauth_app_token.get_token_vals(oauth_app_token.id) return { 'name': _("OK"), 'code': 200, 'description': _("Login was successfully"), 'data': token_vals, } else: raise http.SessionExpiredException(_("Wrong login/password")) except Exception as e: if getattr(e, 'args', ()): err = [ustr(a) for a in e.args] err = err[0] err = odoo.tools.exception_to_unicode(err) _logger.exception(err) #To Do: Username and password is printing in log. Restrict that raise e
def _parse_import_data(self, data, import_fields, options): """ 解析导入的数据,发生异常的情况下,输出到异常信息字段列表中 返回值有2个 1 解析过程是否存在错误 2 解析后的数据集合 3 解析后的发生的错误信息列表 :param data: :param import_fields: :param options: :return: """ # Get fields of type date/datetime ex_message_list = [] process_result = True all_fields = self.env[self.res_model].fields_get() for name, field in all_fields.iteritems(): if field['type'] in ('date', 'datetime') and name in import_fields: # Parse date index = import_fields.index(name) dt = datetime.datetime server_format = DEFAULT_SERVER_DATE_FORMAT if field[ 'type'] == 'date' else DEFAULT_SERVER_DATETIME_FORMAT if options.get('%s_format' % field['type'], server_format) != server_format: user_format = ustr(options.get( '%s_format' % field['type'])).encode('utf-8') for num, line in enumerate(data): if line[index]: try: line[index] = dt.strftime( dt.strptime( ustr(line[index]).encode('utf-8'), user_format), server_format) except ValueError, e: traceback.print_exc() err_msg = _( "Column %s contains incorrect values. Error in line %d: %s" ) % (name, num + 1, ustr(e.message)) process_result = False ex_message_vals = { "message": err_msg, 'rows': { "from": num, "to": num, } } ex_message_list.append(ex_message_vals) #raise ValueError(_("Column %s contains incorrect values. Error in line %d: %s") % (name, num + 1, ustr(e.message))) except Exception, e: traceback.print_exc() err_msg = _("Error Parsing Date [%s:L%d]: %s" ) % (name, num + 1, ustr( e.message)) process_result = False ex_message_vals = { "message": err_msg, 'rows': { "from": num, "to": num, } } ex_message_list.append(ex_message_vals)
def _scenario_save(self, message, transition_type, scenario_id=None, step_id=None): """ Save the scenario on this terminal, handling transient errors by retrying the same step Return the action to the terminal """ self.ensure_one() result = ('M', ['TEST'], False) tries = 0 while True: try: result = self._do_scenario_save( message, transition_type, scenario_id=scenario_id, step_id=step_id, ) break except OperationalError as e: # Automatically retry the typical transaction serialization # errors self.env.cr.rollback() if e.pgcode not in PG_CONCURRENCY_ERRORS_TO_RETRY: logger.warning( "[%s] OperationalError", self.code, exc_info=True) result = ('R', [ 'Please contact', 'your', 'administrator', ], 0) break if tries >= MAX_TRIES_ON_CONCURRENCY_FAILURE: logger.warning( "[%s] Concurrent transaction - " "OperationalError %s, maximum number of tries reached", self.code, e.pgcode) result = ('E', [ ustr('Concurrent transaction - OperationalError ' '%s, maximum number of tries reached') % (e.pgcode), ], True) break wait_time = random.uniform(0.0, 2 ** tries) tries += 1 logger.info( "[%s] Concurrent transaction detected (%s), " "retrying %d/%d in %.04f sec...", self.code, e.pgcode, tries, MAX_TRIES_ON_CONCURRENCY_FAILURE, wait_time) time.sleep(wait_time) except (exceptions.except_orm, exceptions.UserError) as e: # ORM exception, display the error message and require the "go # back" action self.env.cr.rollback() logger.warning('[%s] OSV Exception:', self.code, exc_info=True) result = ('E', [e.name or '', '', e.value or ''], True) break except Exception as e: self.env.cr.rollback() logger.error('[%s] Exception: ', self.code, exc_info=True) result = ('R', ['Please contact', 'your', 'administrator'], 0) self.empty_scanner_values() break self.log('Return value : %r' % (result,)) # Manage automatic steps if result[0] == 'A': return self.scanner_call(self.code, 'action', message=result[2]) return result
def get_rtlcss_error(self, stderr, source=None): """Improve and remove sensitive information from sass/less compilator error messages""" error = misc.ustr(stderr).split('Load paths')[0].replace(' Use --trace for backtrace.', '') error += "This error occured while compiling the bundle '%s' containing:" % self.name return error
def rest_request_auth_token(self, **kwargs): _logger.info(_("Requested Auth Token Service...")) try: grant_type = kwargs.get('grant_type', None) code = kwargs.get('code', None) redirect_uri = kwargs.get('redirect_uri', None) if grant_type != 'authorization_code': error_msg = _('The "grant_type" must be authorization_code') _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) if None in [code, redirect_uri]: error_msg = _( 'The following parameters are must: code, redirect_uri') _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) authorization_header = request.httprequest.headers.get( 'Authorization') if not authorization_header: authorization_header = request.httprequest.headers.get( 'HTTP_AUTHORIZATION') if not authorization_header: error_msg = _('The "Authorization" header is missing') _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) redirect_uri = unquote(redirect_uri) OuthAppAuthCode = request.env['rest.oauth.app.auth.code'] oauth_app = OuthAppAuthCode.get_oauthapp_auth_code(code) if not oauth_app: error_msg = _( 'The auth code is expired or not found or invalid!') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) auth_redirect_uri = urljoin(redirect_uri, urlparse(redirect_uri).path) auth_redirect_uri = redirect_uri auth_redirect_uris = [ x.strip() for x in oauth_app.auth_redirect_uri.split(',') ] if auth_redirect_uri not in auth_redirect_uris: error_msg = _('The value of "redirect_uri" is wrong') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) client_id = oauth_app.client_id client_secret = oauth_app.client_secret gen_auth_headers = oauth_app.generate_basic_auth_header( client_id, client_secret) authorization = gen_auth_headers.get('Authorization') if authorization != authorization_header: error_msg = _( 'Either client_id or client_secret wrong or wrongly encoded!' ) _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) oauth_app_token = OuthAppAuthCode.get_token_auth_code(code) oauth_app_token.action_generate_access_token() oauth_app_token.action_generate_refresh_token() token_vals = oauth_app_token.get_token_vals(oauth_app_token.id) OuthAppAuthCode.check_auth_code(code).action_invalid() return self.generate_response(http_status_codes['created'], token_vals) except Exception as e: if getattr(e, 'args', ()): e = [ustr(a) for a in e.args] e = e[0] error_msg = tools.exception_to_unicode(e) _logger.exception(error_msg) return self.generate_response( http_status_codes['internal_server_error'], error_msg)
def download_xml(self): order_ids = self._context.get('active_ids', []) if order_ids: Orders = Element('ORDERS420') #Top Element Orders.set('SoftwareManufacturer', ustr('Monitor ERP System AB')) Orders.set('SoftwareName', ustr('Monitor')) Orders.set('SoftwareVersion', ustr('8.0.12p39')) for order in self.env['sale.order'].browse(order_ids): Order = SubElement(Orders, 'Order') Order.set('OrderNumber', ustr(str(order.po_num) or '')) head = SubElement(Order, 'Head') #Header Part supplier = SubElement(head, 'Supplier') #Supplier (Company Address) supplier.set('SupplierCodeEdi', '123') #FixMe supplier_name = SubElement(supplier, 'Name') supplier_name.text = ustr(order.user_id.company_id.name) StreetBox1 = SubElement(supplier, 'StreetBox1') if order.user_id.company_id.street: StreetBox1.text = ustr(order.user_id.company_id.street) StreetBox2 = SubElement(supplier, 'StreetBox2') if order.user_id.company_id.street2: StreetBox2.text = ustr(order.user_id.company_id.street2) ZipCity1 = SubElement(supplier, 'ZipCity1') if order.user_id.company_id.city: ZipCity1.text = ustr( order.user_id.company_id.city) + ' ' + ustr( order.user_id.company_id.state_id.name or '') ZipCity2 = SubElement(supplier, 'ZipCity2') if order.user_id.company_id.zip: ZipCity2.text = ustr(order.user_id.company_id.zip) Country = SubElement(supplier, 'Country') if order.user_id.company_id.country_id: Country.text = ustr( order.user_id.company_id.country_id.name) Buyer = SubElement(head, 'Buyer') #Customer Address Buyer_name = SubElement(Buyer, 'Name') Buyer_name.text = ustr(order.partner_id.name) StreetBox1 = SubElement(Buyer, 'StreetBox1') if order.partner_id.street: StreetBox1.text = ustr(order.partner_id.street) StreetBox2 = SubElement(Buyer, 'StreetBox2') if order.partner_id.street2: StreetBox2.text = ustr(order.partner_id.street2) ZipCity1 = SubElement(Buyer, 'ZipCity1') if order.partner_id.city: ZipCity1.text = ustr( order.partner_id.city or '') + ' ' + ustr( order.partner_id.state_id.name or '') + ' ' + ustr( order.partner_id.zip or '') ZipCity2 = SubElement(Buyer, 'ZipCity2') if order.partner_id.zip: ZipCity2.text = ustr( order.partner_id.city2_mailing) + ' ' + ustr( order.partner_id.state_id2.name) + ' ' + ustr( order.partner_id.zip2_mailing or '') Country = SubElement(Buyer, 'Country') if order.partner_id.country_id: Country.text = ustr(order.partner_id.country_id.name) References = SubElement(head, 'References') #References BuyerReference = SubElement(References, 'BuyerReference') BuyerReference.text = ustr(order.buyer_reference or '') BuyerComment = SubElement(References, 'BuyerComment') BuyerComment.text = ustr(order.buyer_comment or '') GoodsLabeling = SubElement(References, 'GoodsLabeling') GoodsLabeling_row1 = SubElement(GoodsLabeling, 'Row1') GoodsLabeling_row1.text = ustr(str(order.po_num) or '') GoodsLabeling_row2 = SubElement(GoodsLabeling, 'Row2') DeliveryAddress = SubElement( head, 'DeliveryAddress' ) #Delivery Address #FixMe: Need to confirm which value? DeliveryAddress_name = SubElement(DeliveryAddress, 'Name') DeliveryAddress_name.text = ustr( order.partner_shipping_id.name) StreetBox1 = SubElement(DeliveryAddress, 'StreetBox1') if order.partner_shipping_id.street_delivery: StreetBox1.text = ustr( order.partner_shipping_id.street_delivery) StreetBox2 = SubElement(DeliveryAddress, 'StreetBox2') if order.partner_shipping_id.street2_delivery: StreetBox2.text = ustr( order.partner_shipping_id.street2_delivery) ZipCity1 = SubElement(DeliveryAddress, 'ZipCity1') if order.partner_shipping_id.city_delivery: ZipCity1.text = ustr( order.partner_shipping_id.city_delivery or '') + ' ' + ustr( order.partner_shipping_id.state_id_delivery.name or '') + ' ' + ustr( order.partner_shipping_id.zip_delivery or '') ZipCity2 = SubElement(DeliveryAddress, 'ZipCity2') if order.partner_shipping_id.city2_delivery: ZipCity2.text = ustr( order.partner_shipping_id.city2_delivery or '') + ' ' + ustr( order.partner_shipping_id.state_id2_delivery.name or '') + ' ' + ustr( order.partner_shipping_id.zip2_delivery or '') Country = SubElement(DeliveryAddress, 'Country') if order.partner_shipping_id.country_id: Country.text = ustr( order.partner_shipping_id.country_id.name) CompanyAdressFlag = SubElement(DeliveryAddress, 'CompanyAdressFlag') CompanyAdressFlag.text = ustr(order.company_id.id) Terms = SubElement(head, 'Terms') #Terms DeliveryTerms = SubElement(Terms, 'DeliveryTerms') IncoTermCombiTerm = SubElement(DeliveryTerms, 'IncoTermCombiTerm') if order.incoterm: IncoTermCombiTerm.text = ustr(order.incoterm.name or '') DeliveryMethod = SubElement(DeliveryTerms, 'DeliveryMethod') DeliveryMethod.text = ustr(order.carrier_id.name or '') TransportPayer = SubElement(DeliveryTerms, 'TransportPayer') TransportPayer.text = ustr(order.transport_payer or '') CustomerTransportTimeDays = SubElement( DeliveryTerms, 'CustomerTransportTimeDays') CustomerTransportTimeDays.text = ustr( order.customer_transport_time_days or '') CustomerInvoiceCode = SubElement(Terms, 'CustomerInvoiceCode') CustomerInvoiceCode.text = ustr(order.customer_invoice_code or '') OrderDate = SubElement(Terms, 'OrderDate') if order.order_date: OrderDate.text = ustr(order.order_date).split(' ')[0] PaymentTerms = SubElement(Terms, 'PaymentTerms') TermsOfPaymentDays = SubElement(PaymentTerms, 'TermsOfPaymentDays') if order.payment_term_id: TermsOfPaymentDays.text = ustr(order.payment_term_id.name) Export = SubElement(head, 'Export') #Export Currency = SubElement(Export, 'Currency') if order.pricelist_id.currency_id: Currency.text = ustr(order.pricelist_id.currency_id.name) Rows = SubElement(Order, 'Rows') #Line Items line_no = 1 row_type = 1 for line in order.order_line: Row = SubElement(Rows, 'Row') Row.set('RowNumber', ustr(line_no)) Row.set('RowType', ustr(row_type)) #FixMe line_no += 1 Part = SubElement(Row, 'Part') if line.product_id and line.product_id.part_number: Part.set('PartNumber', '') else: Part.set('PartNumber', '') if line.product_id and line.part_number_product: Part.set('SupplierPartNumber', ustr(line.part_number_product.name)) else: Part.set('SupplierPartNumber', '') Text = SubElement(Row, 'Text') Text.text = ustr(line.product_id.name or line.name) ReferenceNumber = SubElement(Row, 'ReferenceNumber') if line.product_id.default_code: ReferenceNumber.text = ustr( line.product_id.default_code) Quantity = SubElement(Row, 'Quantity') Quantity.text = ustr(str(int(line.product_uom_qty))) Unit = SubElement(Row, 'Unit') Unit.text = ustr(line.product_uom.name) DeliveryPeriod = SubElement(Row, 'DeliveryPeriod') currentDT = datetime.datetime.now() date = currentDT.strftime("%m/%d/%Y") DeliveryPeriod.text = ustr(date) Each = SubElement(Row, 'Each') Each.text = ustr(str(int(line.price_unit or ''))) Discount = SubElement(Row, 'Discount') Discount.text = ustr(str(int(line.discount))) Setup = SubElement(Row, 'Setup') Setup.text = ustr(line.setup or 0) Alloy = SubElement(Row, 'Alloy') Alloy.text = ustr(line.alloy or 0) filename = '/opt/odoo/Sale Order XML.xml' f = open(filename, 'w') orders = ElementTree.tostring(Orders, encoding="utf-8") data = minidom.parseString(orders).toprettyxml(encoding="utf-8") f.write(data) f.close() file_base64 = '' with open( filename, "r", ) as file: file_base64 = base64.b64encode(file.read()) export_id = self.env['so.xml.file'].create({ 'xml_file': file_base64, 'file_name': filename, }) return { 'view_mode': 'form', 'res_id': export_id.id, 'res_model': 'so.xml.file', 'view_type': 'form', 'type': 'ir.actions.act_window', 'context': self._context, 'target': 'new', }
def _stripe_convert_input_method(self, atts, options=None): output_vals = {} if atts.mimetype == 'text/csv': options = options or {} csv_data = base64.b64decode(atts.datas) if not PY2: csv_data = ustr(csv_data) dialect = csv.Sniffer().sniff(csv_data) dialect.lineterminator = '\n' # TODO: guess encoding with chardet? Or https://github.com/aadsm/jschardet encoding = options.get('encoding', 'utf-8') if encoding != 'utf-8': # csv module expect utf-8, see http://docs.python.org/2/library/csv.html csv_data = csv_data.decode(encoding).encode('utf-8') fieldnames = [ "id", "Type", "name", "amount", "Fee", "Destination Platform Fee", "Net", "DO NOT IMPORT", "date", "Available On (UTC)", "note", "amount_currency", "currency_id", "Transfer", "Transfer Date (UTC)", "Transfer Group", "DO NOT IMPORT", "ref", "DO NOT IMPORT", "DO NOT IMPORT", "DO NOT IMPORT" ] stripe_dict = csv.DictReader(StringIO(csv_data), fieldnames=fieldnames, dialect=dialect) stripe = {'EUR': []} fees = copy.deepcopy(stripe) dates = copy.deepcopy(stripe) all_dates = [] for row in itertools.islice(stripe_dict, 1, None): try: key = row['currency_id'].upper() fee = Decimal(row['Fee'].replace(',', '.')) dt = datetime.datetime.strptime(row['date'], '%Y-%m-%d %H:%M') dt_fmt = ['%Y', '%m', '%d', '%H', '%M'] dt_vals = tuple( map( lambda fmt: int(datetime.datetime.strftime( dt, fmt)), dt_fmt)) date = datetime.datetime( *dt_vals, tzinfo=timezone('UTC')).astimezone( timezone(self.env.user.tz or 'UTC')).strftime('%Y-%m-%d') amount = float(row['amount'].replace(',', '.')) amount_currency = 0 if row['amount_currency']: amount_currency = float(row['amount_currency'].replace( ',', '.')) except Exception as e: raise UserError( 'It seems that you have chosen a wrong file or a wrong conversion type!\n\n%s' % (e)) row['currency_id'] = key row['date'] = date row['amount'] = amount row['amount_currency'] = amount_currency row['Net'] = float(row['Net'].replace(',', '.')) row['Fee'] = fee if key not in fees: key = 'EUR' fees[key].append(fee) dates[key].append(date) all_dates.append(date) stripe[key].append(row) # Min/Max date from all dates min_date = min(all_dates) max_date = max(all_dates) for key in stripe.keys(): if not dates[key]: continue if sum(fees[key]) != 0: fee_vals = dict( id='txn_fees_stripe_%s_%s%s' % (key.lower(), min_date.replace( '-', ''), max_date.replace('-', '')), date=max_date, name='Stripe Gebühren %s - %s (%s)' % (min_date.replace('-', ' '), max_date[-2:], key), amount=-sum(fees[key]), currency_id=key, ref='Automatische Berechnung (Transaktionen)', note='') stripe[key].append(fee_vals) for currency, lines in stripe.items(): if len(lines) == 0: continue output = StringIO() writer = csv.DictWriter(output, fieldnames=fieldnames, dialect=dialect) writer.writeheader() for line in lines: writer.writerow(line) filename = '%s - %s (%s) - Stripe Import (Odoo).csv' % ( min_date.replace('-', ' '), max_date[-2:], currency) output_vals[filename] = output _logger.info('File %s with %s lines to be created', currency, len(lines)) return output_vals
def _six_transactions_convert_input_method(self, atts, options=None): output_vals = {} if atts.mimetype == 'text/csv': options = options or {} csv_data = base64.b64decode(atts.datas) if not PY2: csv_data = ustr(csv_data) dialect = csv.Sniffer().sniff(csv_data) dialect.lineterminator = '\n' # TODO: guess encoding with chardet? Or https://github.com/aadsm/jschardet encoding = options.get('encoding', 'utf-8') if encoding != 'utf-8': # csv module expect utf-8, see http://docs.python.org/2/library/csv.html csv_data = csv_data.decode(encoding).encode('utf-8') fieldnames = [ 'date', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'note', 'DO NOT IMPORT', 'txn_id', 'ref', 'DO NOT IMPORT', 'DO NOT IMPORT', 'amount', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'DO NOT IMPORT', 'name' ] six_dict = csv.DictReader(StringIO(csv_data), fieldnames=fieldnames, dialect=dialect) six = {'EUR': []} dates = copy.deepcopy(six) fieldnames_new = fieldnames[:] fieldnames_new.insert(0, 'id') fieldnames_new.append('partner_id') for row in itertools.islice(six_dict, 1, None): try: key = 'EUR' date = datetime.datetime.strptime( row['date'], '%d.%m.%Y').strftime('%Y-%m-%d') amount = float(row['amount'].replace(',', '.')) except Exception as e: raise UserError( 'It seems that you have chosen a wrong file or a wrong conversion type!\n\n%s' % (e)) row['id'] = 'txn_six_transactions_%s' % row['txn_id'] row['date'] = date row['amount'] = amount del row['DO NOT IMPORT'] dates[key].append(date) six[key].append(row) fieldnames_new = [ x for x in fieldnames_new if x != 'DO NOT IMPORT' ] for currency, lines in six.items(): if len(lines) == 0: continue min_date = min(dates[currency]) max_date = max(dates[currency]) output = StringIO() dialect.delimiter = ',' writer = csv.DictWriter(output, fieldnames=fieldnames_new, dialect=dialect) writer.writeheader() for line in lines: writer.writerow(line) filename = '%s - %s (%s) - SIX Transaction Import (Odoo).csv' % ( min_date.replace('-', ' '), max_date[-2:], currency) output_vals[filename] = output _logger.info('File %s with %s lines to be created', currency, len(lines)) return output_vals
def get_rtlcss_error(self, stderr, source=None): """Improve and remove sensitive information from sass/less compilator error messages""" error = misc.ustr(stderr).split('Load paths')[0].replace( ' Use --trace for backtrace.', '') error += "This error occured while compiling the bundle '%s' containing:" % self.name return error
def parameter(dico, resource, special=None, parameters=None): """ Convert value to a parameter for SOAP query @type dico: dict @param dico: Contain parameter starts with OERP_ @type resource: dict @param resource: Contain parameter starts with WIZARD_ @rtype: xmlstring @return: XML String representation """ _logger.debug('Included parameters: %s', parameters) res = '' for key in resource: _logger.debug(' PARAMETER -> RESOURCE: %s' % key) if key in 'xml_data': continue e = Element('parameter') e.set('name', 'OERP_%s' % key.upper()) e.text = ustr(resource[key]) res += tostring(e) + '\n' for key in dico: _logger.debug(' PARAMETER -> DICO: %s' % key) if key in 'params': continue val = dico[key] e = Element('parameter') e.set('name', 'WIZARD_%s' % key.upper()) if isinstance(val, list): if isinstance(val[0], tuple): e.text = ','.join(map(str, val[0][2])) else: e.text = ','.join(map(str, val)) else: e.text = val and ustr(val) or '' res += tostring(e) + '\n' # Duplicate WIZARD parameters with prefix OERP e = Element('parameter') e.set('name', 'OERP_%s' % key.upper()) if isinstance(val, list): if isinstance(val[0], tuple): e.text = ','.join(map(str, val[0][2])) else: e.text = ','.join(map(str, val)) else: e.text = val and ustr(val) or '' res += tostring(e) + '\n' if special is None: special = {} for key in special: _logger.debug(' PARAMETER -> SPECIAL: %s' % key) e = Element('parameter') e.set('name', key) e.text = ustr(special[key]) res += tostring(e) + '\n' res = entities(res) if resource.get('xml_data'): res += '<parameter class="java.lang.String"' \ 'name="XML_DATA">' res += '<![CDATA["%s"]]></parameter>' % \ resource['xml_data'] return res
def log(self, log_message): if self.log_enabled: logger.info('[%s] %s' % (self.code, ustr(log_message)))
def text_get(node): return ''.join([ustr(n.text) for n in node])
def rest_request_auth_odoo(self, **kwargs): #To Do: Need to cjeck can easily be attacked. if then, find another solution _logger.info(_("Requested Odoo Auth Service...")) try: code = kwargs.get('code', None) scope = kwargs.get('scope', None) state = kwargs.get('state', None) redirect_uri = kwargs.get('redirect_uri', None) odoo_oauth2client_uri = kwargs.get('odoo_oauth2client_uri', None) if None in [code, state, odoo_oauth2client_uri]: error_msg = _( 'The following parameters are must: code, state, odoo_oauth2client_uri' ) _logger.error(error_msg) return self.generate_response( http_status_codes['not_acceptable'], error_msg) redirect_uri = unquote(redirect_uri) odoo_oauth2client_uri = unquote(odoo_oauth2client_uri) OuthAppAuthCode = request.env['rest.oauth.app.auth.code'] oauth_app = OuthAppAuthCode.get_oauthapp_auth_code(code) if not oauth_app: error_msg = _( 'The auth code is expired or not found or invalid!') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) auth_redirect_uri = urljoin(redirect_uri, urlparse(redirect_uri).path) auth_redirect_uri = redirect_uri auth_redirect_uris = [ x.strip() for x in oauth_app.auth_redirect_uri.split(',') ] if auth_redirect_uri not in auth_redirect_uris: error_msg = _('The value of "redirect_uri" is wrong') _logger.error(error_msg) return self.generate_response( http_status_codes['unauthorized'], error_msg) odoo_oauth2client_uri = urljoin( odoo_oauth2client_uri, urlparse(odoo_oauth2client_uri).path) odoo_oauth2client_uri = odoo_oauth2client_uri if odoo_oauth2client_uri != oauth_app.odoo_oauth2client_uri: error_msg = _('The value of "odoo_oauth2client_uri" is wrong') _logger.error(error_msg) return self.generate_response(http_status_codes['bad_request'], error_msg) client_id = oauth_app.client_id client_secret = oauth_app.client_secret gen_auth_headers = oauth_app.generate_basic_auth_header( client_id, client_secret) params = { 'code': code, 'grant_type': 'authorization_code', 'redirect_uri': redirect_uri, 'scope': scope, 'state': state, } encoded_params = urls.url_encode(params) base_url = request.env['ir.config_parameter'].sudo().get_param( 'web.base.url') auth_token_uri = urls.url_join(base_url, rest_auth_token_endpoint) auth_token_uri = '?'.join([auth_token_uri, encoded_params]) _logger.info( _("Requested auth_code redirected from odoo endpoint to access_token endpoint" )) res = requests.request('GET', auth_token_uri, data=params, headers=gen_auth_headers) status = res.status_code try: response = res.json() except Exception as e: response = res.text return self.generate_response(status, response) oauth_app_token = OuthAppAuthCode.get_token_auth_code(code) encoded_params = urls.url_encode(response) odoo_oauth2client_uri = '?'.join( [odoo_oauth2client_uri, encoded_params]) _logger.info( _("Requested auth_code redirected from access_token endpoint to odoo_oauth2client endpoint" )) return utils.redirect(odoo_oauth2client_uri) except Exception as e: if getattr(e, 'args', ()): e = [ustr(a) for a in e.args] e = e[0] error_msg = tools.exception_to_unicode(e) _logger.exception(error_msg) return self.generate_response( http_status_codes['internal_server_error'], error_msg)
def cron_remind_timesheet_submission(self): user_obj = self.env['res.users'] notification_obj = self.env['timesheet.notification.config'] notification = notification_obj.search([]) day_index = datetime.today().weekday() days_list = list(calendar.day_name) weekday = days_list[day_index] admin = user_obj.browse(self._uid) if notification: if weekday == str(notification.reminder_day): timesheets_objs = self.search([('state', '=', 'draft')]) #timesheet_emps = [tobj.employee_id for tobj in timesheets_objs] self._cr.execute( 'select value from ir_config_parameter where key=%s', ('web.base.url', )) server = str(self._cr.fetchone()[0]) for tobj in timesheets_objs: #for emp in timesheet_emps: emp = tobj.employee_id url = server + '/web#id=%s&view_type=%s&model=%s' % ( tobj.id, 'form', 'hr_timesheet_sheet.sheet') mail_values = { 'subject': 'Please Fill Timesheet Today', 'author_id': self._uid, 'email_from': admin.partner_id.email or '', 'email_to': emp.user_id.partner_id.email, 'recipient_ids': emp.user_id.partner_id, 'reply_to': admin.partner_id.email or '', 'body_html': ustr(notification.reminder_message) % (emp.name, tobj.date_from, tobj.date_to, url, emp.parent_id.name), } mail_sent = self.env['mail.mail'].create( mail_values).send() if weekday == str(notification.notify_day): date_to = (datetime.today().date() - relativedelta(days=1)).strftime("%Y-%m-%d") date_to = datetime.strptime(date_to, "%Y-%m-%d") date_from = (date_to - relativedelta(days=6)).strftime("%Y-%m-%d") date_from = datetime.strptime(date_from, "%Y-%m-%d") date_from = str(date_from).split(' ')[0] date_to = str(date_to).split(' ')[0] timesheets_objs = self.search([('date_from', '=', date_from), ('date_to', '=', date_to), ('state', '=', 'draft')]) timesheet_emps = [tobj.employee_id for tobj in timesheets_objs] for tobj in timesheets_objs: #for emp in timesheet_emps: emp = tobj.employee_id man_email = emp.parent_id and emp.parent_id.user_id and emp.parent_id.user_id.partner_id.email or '' mail_values = { 'subject': '%s did not submit timesheet' % (emp.name), 'author_id': self._uid, 'email_from': admin.partner_id.email or '', 'email_to': user.partner_id.email, 'email_cc': man_email, 'recipient_ids': emp.user_id.partner_id, 'reply_to': admin.partner_id.email, 'body_html': ustr(notification.notify_message) % (emp.name, tobj.date_from, tobj.date_to, emp.parent_id.name), } mail_sent = self.env['mail.mail'].create( mail_values).send() return True
def _paypal_convert_input_method(self, atts, options=None): output_vals = {} if atts.mimetype == 'text/csv': options = options or {} csv_data = base64.b64decode(atts.datas) if not PY2: csv_data = ustr(csv_data) dialect = csv.Sniffer().sniff(csv_data) dialect.lineterminator = '\n' encoding = options.get('encoding', 'utf-8') if encoding != 'utf-8': csv_data = csv_data.decode(encoding).encode('utf-8') fieldnames = [ "date", "Uhrzeit", "Zeitzone", "note", "currency_id", "amount", "Gebühr", "Netto", "Guthaben", "name", "DO NOT IMPORT", "partner_name", "Name der Bank", "DO NOT IMPORT", "Versand- und Bearbeitungsgebühr", "Umsatzsteuer", "Rechnungsnummer", "ref" ] paypal_dict = csv.DictReader(StringIO(csv_data), fieldnames=fieldnames, dialect=dialect) paypal = {} fees = {} dates = {} fieldnames_new = fieldnames[:] fieldnames_new.insert(0, 'id') all_dates = [] for row in itertools.islice(paypal_dict, 1, None): try: key = row['currency_id'] if key not in paypal: paypal[key] = [] fees[key] = [] dates[key] = [] fee = Decimal(row['Gebühr'].replace(',', '')) date_v = datetime.datetime.strptime( row['date'], '%m/%d/%Y') date = date_v.strftime('%Y-%m-%d') amount = Decimal(row['amount'].replace(',', '')) except Exception as e: raise UserError( 'It seems that you have chosen a wrong file or a wrong conversion type!\n\n%s' % (e)) direction = 'pos' if amount < 0: direction = 'neg' row['id'] = 'txn_%s_%s%s%s_%s' % (row['name'], date_v.year, date_v.month, date_v.day, direction) row['date'] = date row['amount'] = amount row['Gebühr'] = fee fees[key].append(fee) dates[key].append(date) all_dates.append(date) paypal[key].append(row) # Min/Max date from all dates min_date = min(all_dates) max_date = max(all_dates) for key in paypal.keys(): if not dates[key]: continue if sum(fees[key]) != 0: fee_vals = dict( id='txn_fees_paypal_%s_%s%s' % (key.lower(), min_date.replace( '-', ''), max_date.replace('-', '')), date=max_date, name='PayPal Gebühren %s - %s (%s)' % (min_date.replace('-', ' '), max_date[-2:], key), amount=sum(fees[key]), currency_id=key, ref='Automatische Berechnung (Transaktionen)', note='') paypal[key].append(fee_vals) for currency, lines in paypal.items(): if len(lines) == 0: continue output = StringIO() writer = csv.DictWriter(output, fieldnames=fieldnames_new, dialect=dialect) writer.writeheader() for line in lines: writer.writerow(line) filename = '%s - %s (%s) - PayPal Import (Odoo).csv' % ( min_date.replace('-', ' '), max_date[-2:], currency) output_vals[filename] = output # output.getvalue().strip('\n') _logger.info('File %s with %s lines to be created', currency, len(lines)) return output_vals