diff --git a/app_saas/__init__.py b/app_saas/__init__.py new file mode 100644 index 00000000..ef83fef4 --- /dev/null +++ b/app_saas/__init__.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +# please comment follow for produce +from . import models +from . import report +from . import controllers + +# hook form install and uninstall + +from .hooks import pre_init_hook +from .hooks import post_init_hook +from .hooks import uninstall_hook diff --git a/app_saas/__manifest__.py b/app_saas/__manifest__.py new file mode 100644 index 00000000..fa4e2591 --- /dev/null +++ b/app_saas/__manifest__.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +# Created on 2023-10-06 +# author: 欧度智能,https://www.odooai.cn +# email: 300883@qq.com +# Copyright (C) 2009~2024 odooAi.cn + +# Odoo16在线用户手册(长期更新) +# https://www.odooai.cn/documentation/16.0/zh_CN/index.html + +# Odoo16在线开发者手册(长期更新) +# https://www.odooai.cn/documentation/16.0/zh_CN/developer.html + +# 行业应用说明,应该是带 Industry 的就会放入 + +############################################################################## +# Copyright (C) 2009-TODAY odooAi.cn Ltd. https://www.odooai.cn +# Author: Ivan Deng,300883@qq.com +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# See . +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. +############################################################################## + +{ + 'name': 'odooapp.cn SaaS Client-Ai Passport.Odoo中文应用商店SaaS云服务客户端', + 'version': '17.0.24.12.06', + 'author': 'odooai.cn', + 'category': 'Base', + 'website': 'https://www.odooai.cn', + 'live_test_url': 'https://demo.odooapp.cn', + 'license': 'OPL-1', + 'sequence': 2, + 'price': 0.00, + 'currency': 'EUR', + 'images': ['static/description/banner.png'], + 'summary': ''' + AiSaas云服务,使用Ai通行证,一键实现全社交媒体统一登录SSO。 + 支持微信、抖音、QQ、淘宝、钉钉、支付宝、企业微信、Facebook、Google、微软Azure等整合登录。 + 在Odoo中获取最新的中文翻译(另行收费),获取当前Odoo模块最新版本更新等。 + 支持Odoo中文版在线更新及 www.odooapp.cn 的信息推送等。 + 安装即代表同意我司云服务用户协议及隐私政策。 https://www.odooapp.cn/conditions + ''', + 'description': ''' + 1. Ai通行证实现全社交媒体登录支持 + 2. 快速访问Odoo中文应用商店并获取独享Odoo中文通行码,可随时断开云服务连接 + 3. 一键获取最新Odoo中文应用模块与主题,最新行业服务包 + 4. 一键获取Odoo中文翻译更新(收费) + 5. 快速获取Odoo服务,Odoo升级评估 + 6. 系统出错时一键提交,获取技术支持(会员专属) + 11.多语言支持,多公司支持 + 12.仅从Odoo18-16企业版,社区版版本开始支持 + 13.代码完全开源 + ''', + 'depends': [ + 'app_common', + 'auth_oauth', + # 'website', + ], + 'data': [ + 'data/auth_oauth_data.xml', + 'views/auth_oauth_provider_views.xml', + 'views/res_config_settings_views.xml', + ], + 'assets': { + 'web.assets_frontend': [ + # 'app_/static/src/scss/style.scss', + ], + 'web.assets_backend': [ + # 'app_/static/src/js/*.js', + ], + }, + 'demo': [ + ], + # 'pre_init_hook': 'pre_init_hook', + # 'post_init_hook': 'post_init_hook', + # 'uninstall_hook': 'uninstall_hook', + 'installable': True, + 'application': True, + 'auto_install': False, +} diff --git a/app_saas/controllers/__init__.py b/app_saas/controllers/__init__.py new file mode 100644 index 00000000..83118e09 --- /dev/null +++ b/app_saas/controllers/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + +# from . import main diff --git a/app_saas/controllers/main.py b/app_saas/controllers/main.py new file mode 100644 index 00000000..1e0963f0 --- /dev/null +++ b/app_saas/controllers/main.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# +# from odoo import http +# from odoo.addons.portal.controllers.portal import CustomerPortal +# +# +# class appCustomerPortal(CustomerPortal): +# +# # Controler sample +# @http.route('/my/webclient/locale/', type='http', auth="none") +# def index(self, **kw): +# return "Hello, world" +# +# @http.route('/default/default/objects/', auth='public') +# def list(self, **kw): +# return http.request.render('default.listing', { +# 'root': '/default/default', +# 'objects': http.request.env['default.default'].search([]), +# }) +# +# @http.route('/default/default/objects//', auth='public') +# def object(self, obj, **kw): +# return http.request.render('default.object', { +# 'object': obj +# }) diff --git a/app_saas/data/auth_oauth_data.xml b/app_saas/data/auth_oauth_data.xml new file mode 100644 index 00000000..47e82663 --- /dev/null +++ b/app_saas/data/auth_oauth_data.xml @@ -0,0 +1,24 @@ + + + + + Ai Passport of odooapp.cn + Ai通行证-Odoo中文应用商店 + https://www.odooapp.cn/oauth/authorize + https://www.odooapp.cn/oauth/token + odoo,profile + https://www.odooapp.cn/oauth/profile + + + fa fa-2x fa-fw fa-sign-in text-primary + + + + + + + + + diff --git a/app_saas/hooks.py b/app_saas/hooks.py new file mode 100644 index 00000000..8f76cdea --- /dev/null +++ b/app_saas/hooks.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- + +# Created on 2023-10-06 +# author: 欧度智能,https://www.odooai.cn +# email: 300883@qq.com +# Copyright (C) 2009~2024 odooAi.cn + +# Odoo16在线用户手册(长期更新) +# https://www.odooai.cn/documentation/16.0/zh_CN/index.html + +# Odoo16在线开发者手册(长期更新) +# https://www.odooai.cn/documentation/16.0/zh_CN/developer.html + +from odoo import api, SUPERUSER_ID, _ + + +def pre_init_hook(env): + pass + # cr.execute("") + + +def post_init_hook(env): + pass + # cr.execute("") + + +def uninstall_hook(env): + pass + # cr.execute("") diff --git a/app_saas/i18n/README.txt b/app_saas/i18n/README.txt new file mode 100644 index 00000000..222b84cd --- /dev/null +++ b/app_saas/i18n/README.txt @@ -0,0 +1,2 @@ +Please follow this tutorial for more guides: +https://www.odoo.com/documentation/master/developer/misc/i18n/translations.html \ No newline at end of file diff --git a/app_saas/i18n/zh_CN.po b/app_saas/i18n/zh_CN.po new file mode 100644 index 00000000..51835a3a --- /dev/null +++ b/app_saas/i18n/zh_CN.po @@ -0,0 +1,48 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * app_saas +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 18.0+e-20241031\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-11-08 10:21+0000\n" +"PO-Revision-Date: 2024-11-08 10:21+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: app_saas +#: model_terms:ir.ui.view,arch_db:app_saas.app_res_config_settings_view_form +msgid "Save to Install Chinese PO App if downloaded." +msgstr "保存 后即可安装Odoo中文云翻译模块。本模块可至Odoo中文应用商店下载。" + +#. module: app_saas +#: model:ir.model.fields,help:app_saas.field_res_config_settings__module_app_cn_po +#: model_terms:ir.ui.view,arch_db:app_saas.app_res_config_settings_view_form +msgid "Checked to Sync Odoo Chinese from www.odooapp.cn" +msgstr "勾选后即可启用Odoo中文云翻译,相关服务由 www.odooapp.cn 提供" + +#. module: app_saas +#: model:ir.model,name:app_saas.model_res_config_settings +msgid "Config Settings" +msgstr "设置" + +#. module: app_saas +#: model_terms:ir.ui.view,arch_db:app_saas.app_res_config_settings_view_form +msgid "Or get the app from" +msgstr "您可以在此获取本应用模块" + +#. module: app_saas +#: model:ir.model.fields,field_description:app_saas.field_res_config_settings__module_app_cn_po +#: model_terms:ir.ui.view,arch_db:app_saas.app_res_config_settings_view_form +msgid "SaaS Chinese PO" +msgstr "中文云翻译PO" + +#. module: app_saas +#: model_terms:ir.ui.view,arch_db:app_saas.app_res_config_settings_view_form +msgid "https://www.odooapp.cn/apps/modules/app_cn_po" +msgstr "https://www.odooapp.cn/apps/modules/app_cn_po" diff --git a/app_saas/models/__init__.py b/app_saas/models/__init__.py new file mode 100644 index 00000000..94facece --- /dev/null +++ b/app_saas/models/__init__.py @@ -0,0 +1,8 @@ +# -*- coding: utf-8 -*- +# Part of odooAi.cn. See LICENSE file for full copyright and licensing details. + +from . import res_config_settings +from . import auth_oauth_provider +from . import res_users + + diff --git a/app_saas/models/auth_oauth_provider.py b/app_saas/models/auth_oauth_provider.py new file mode 100644 index 00000000..2b9ba53b --- /dev/null +++ b/app_saas/models/auth_oauth_provider.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +from odoo import api, fields, models, modules, tools, _ + +import base64 +from datetime import timedelta + +class AuthOAuthProvider(models.Model): + + _inherit = 'auth.oauth.provider' + _order = 'sequence, name' + + # 取code的url,主要针对国内的先取code,再拿Token的方式 + code_endpoint = fields.Char(string='Token by Code Endpoint', help='Get Token from Code. Only for Code response type.') + user_template_id = fields.Many2one('res.users', string='New User Template', + domain=[('active', '=', False)]) diff --git a/app_saas/models/res_config_settings.py b/app_saas/models/res_config_settings.py new file mode 100644 index 00000000..01c8ed94 --- /dev/null +++ b/app_saas/models/res_config_settings.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- + +import logging + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError, ValidationError + +_logger = logging.getLogger(__name__) + + +class ResConfigSettings(models.TransientModel): + _inherit = 'res.config.settings' + + module_app_cn_po = fields.Boolean('SaaS Chinese PO', help="Checked to Sync Odoo Chinese from www.odooapp.cn") diff --git a/app_saas/models/res_users.py b/app_saas/models/res_users.py new file mode 100644 index 00000000..66099fd7 --- /dev/null +++ b/app_saas/models/res_users.py @@ -0,0 +1,133 @@ +# -*- coding: utf-8 -*- + +try: + import urlparse +except: + from urllib.parse import urlparse +try: + import urllib2 +except: + from urllib import request as urllib2 + + + +from odoo import api, fields, models, _ +from odoo.exceptions import AccessDenied, UserError +from odoo.addons.auth_signup.models.res_users import SignupError +from odoo.http import request, Response +from odoo.tools.misc import ustr + +from ast import literal_eval +import json +import requests +from datetime import timedelta +import random + +import logging +_logger = logging.getLogger(__name__) + +class OauthBindError(Exception): + # 增加一种错误类型 + pass + +class ResUsers(models.Model): + _inherit = 'res.users' + + @api.model + def auth_oauth(self, provider, params): + # 这里原生是没处理code模式,此处将增加使用code取token,不在 controller 中处理 + code = params.get('code', False) + access_token = params.get('access_token') + oauth_provider = self.env['auth.oauth.provider'].sudo().browse(provider) + + kw = {} + if oauth_provider.code_endpoint and code and not access_token: + # odoo 特殊处理,用code取token + params.update({ + 'scope': oauth_provider.scope or '', + 'client_id': oauth_provider.client_id or '', + }) + if hasattr(oauth_provider, 'client_secret') and oauth_provider.client_secret: + params.update({ + 'client_secret': oauth_provider.client_secret or '', + }) + response = requests.get(oauth_provider.code_endpoint, params=params, timeout=30) + if response.ok: + ret = response.json() + # todo: 客户机首次连接时,取到的 server 端 key 写入 provider 的 client_secret + if ret.get('push_client_secret') and hasattr(oauth_provider, 'client_secret'): + oauth_provider.write({'client_secret': ret.get('push_client_secret')}) + self._cr.commit() + kw = {**ret, **params} + kw.pop('code', False) + self = self.with_context(auth_extra=kw) + res = super(ResUsers, self).auth_oauth(provider, kw) + return res + + def _auth_oauth_signin(self, provider, validation, params): + # 用户绑定的额外处理,如果有同 login 用户则直接绑定 + # todo: 当前不管多公司,在 social_login 里有更细节判断,后续优化 + # todo: 当前同名就写 oauth 信息,不安全,要优化 + oauth_provider = self.env['auth.oauth.provider'].sudo().browse(provider) + if oauth_provider and oauth_provider.scope.find('odoo') >= 0: + oauth_uid =validation.get('user_id') + if oauth_uid: + odoo_user = self.sudo().search([('login', '=', oauth_uid)], limit=1) + if odoo_user and not (odoo_user.oauth_access_token and odoo_user.oauth_provider_id and odoo_user.oauth_uid): + vals = { + 'oauth_provider_id': provider, + 'oauth_access_token': params.get('access_token'), + 'oauth_uid': oauth_uid, + } + odoo_user.write(vals) + _logger.info('========= _auth_oauth_signin res.users write:%s' % vals) + self._cr.commit() + return odoo_user.user_id.login + res = super(ResUsers, self)._auth_oauth_signin(provider, validation, params) + return res + + def _create_user_from_template(self, values): + # 处理odooapp.cn 为 server 时 默认为内部用户 + oauth_provider_id = values.get('oauth_provider_id') + if oauth_provider_id: + provider = request.env['auth.oauth.provider'].sudo().browse(int(oauth_provider_id)) + if provider: + template_user = provider.user_template_id + if not template_user and provider.scope.find('odoo') >= 0: + template_user = self.sudo().env.ref('base.default_user', False) + if not template_user: + template_user_id = literal_eval(self.env['ir.config_parameter'].sudo().get_param('base.template_portal_user_id', 'False')) + template_user = self.sudo().browse(template_user_id) + + 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.sudo().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)) + res = super(ResUsers, self)._create_user_from_template(values) + self._cr.commit() + return res + + @api.model + def _generate_signup_values(self, provider, validation, params): + # 此处生成 创建 odoo user 的初始值,增加字段如头像 + res = super()._generate_signup_values(provider, validation, params) + # 后置增加字段,包括 headimgurl + if validation.get('mobile'): + res['mobile'] = validation.get('mobile') + if validation.get('headimgurl'): + res['image_1920'] = self.sudo()._get_image_from_url(validation.get('headimgurl')) + return res + + def _rpc_api_keys_only(self): + # 可直接使用 oauth_access_token 作为 password 登录 + self.ensure_one() + return self.oauth_access_token or super()._rpc_api_keys_only() diff --git a/app_saas/report/__init__.py b/app_saas/report/__init__.py new file mode 100644 index 00000000..1735152f --- /dev/null +++ b/app_saas/report/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +# from . import model_new_report + diff --git a/app_saas/report/model_new_report.py b/app_saas/report/model_new_report.py new file mode 100644 index 00000000..1789c71b --- /dev/null +++ b/app_saas/report/model_new_report.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 -*- +############################################################################## +# Copyright (C) 2009-TODAY odooai.cn Ltd. https://www.odooai.cn +# Author: Ivan Deng,300883@qq.com +# You can modify it under the terms of the GNU LESSER +# GENERAL PUBLIC LICENSE (LGPL v3), Version 3. +# See . +# +# It is forbidden to publish, distribute, sublicense, or sell copies +# of the Software or modified copies of the Software. + +# Create on 2023-10-06 +############################################################################## + +from odoo import fields, models, tools, api + + +class ModelNewReport(models.Model): + + # Model New Analysis + _name = 'model.new.report' + _auto = False + _description = 'Model New Analysis' + _rec_name = 'name' + + # Base field + name = fields.Char(string='Name', readonly=True) + ref = fields.Char(string='Reference', readonly=True) + amount = fields.Float(string="Amount", readonly=True) + date = fields.Datetime(string="Date", readonly=True) + user_id = fields.Many2one('res.users', string='User', readonly=True) + user_login = fields.Char(string='User Login', readonly=True) + company_id = fields.Many2one('res.company', 'Company', readonly=True) + active = fields.Boolean(string="Active", readonly=True) + + @api.model + def _select(self): + return ''' + SELECT + m.id, + m.name, + m.ref, + m.amount, + m.date, + m.user_id, + u.login AS user_login, + m.company_id, + m.active + ''' + + @api.model + def _from(self): + return ''' + FROM model_new AS m + ''' + + @api.model + def _join(self): + return ''' + JOIN res_users AS u ON m.user_id = u.id + ''' + + @api.model + def _where(self): + return '' + + def init(self): + tools.drop_view_if_exists(self._cr, self._table) + sql = ''' + CREATE OR REPLACE VIEW %s AS ( + %s + %s + %s + %s + ) + ''' % (self._table, self._select(), self._from(), self._join(), self._where()) + self._cr.execute(sql) diff --git a/app_saas/report/model_new_report_views.xml b/app_saas/report/model_new_report_views.xml new file mode 100644 index 00000000..f04ea2b3 --- /dev/null +++ b/app_saas/report/model_new_report_views.xml @@ -0,0 +1,88 @@ + + + + + app.model.new.report.graph + model.new.report + + + + + + + + + + + app.model.new.report.pivot + model.new.report + + + + + + + + + + + + app.model.new.report.tree + model.new.report + + + + + + + + + + + + + app.model.new.report.search + model.new.report + + + + + + + + + + + + + + + + + + + + + Model New Report + model.new.report + graph,pivot,tree + { + 'pivot_column_groupby': ['user_id'], + 'pivot_row_groupby': ['date:month'], + 'graph_mode': 'bar', + 'graph_groupbys': ['date:month', 'user_id'], + } + + [] + +

+ No data yet! +

+

+ Start Analysis +

+
+
+
diff --git a/app_saas/security/app_security.xml b/app_saas/security/app_security.xml new file mode 100644 index 00000000..99b55a21 --- /dev/null +++ b/app_saas/security/app_security.xml @@ -0,0 +1,41 @@ + + + + + + App... + Helps you manage your ... + 8 + + + + + App User + + + The user will be able to ... + + + + + App Admin + + + The user will be able to config ... + + + + + + + + + + + + + + + + + diff --git a/app_saas/security/ir.model.access.csv b/app_saas/security/ir.model.access.csv new file mode 100644 index 00000000..fc156047 --- /dev/null +++ b/app_saas/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_model_new,access_model_new,model_model_new,base.group_user,1,1,1,1 +access_model_new_report,access_model_new_report,model_model_new_report,base.group_user,1,1,1,1 diff --git a/app_saas/static/description/banner.png b/app_saas/static/description/banner.png new file mode 100644 index 00000000..d24cc22d Binary files /dev/null and b/app_saas/static/description/banner.png differ diff --git a/app_saas/static/description/banner1.png b/app_saas/static/description/banner1.png new file mode 100644 index 00000000..95692152 Binary files /dev/null and b/app_saas/static/description/banner1.png differ diff --git a/app_saas/static/description/banner2.png b/app_saas/static/description/banner2.png new file mode 100644 index 00000000..8557815e Binary files /dev/null and b/app_saas/static/description/banner2.png differ diff --git a/app_saas/static/description/banner3.png b/app_saas/static/description/banner3.png new file mode 100644 index 00000000..de86dec9 Binary files /dev/null and b/app_saas/static/description/banner3.png differ diff --git a/app_saas/static/description/cnreadme.jpg b/app_saas/static/description/cnreadme.jpg new file mode 100644 index 00000000..67004a79 Binary files /dev/null and b/app_saas/static/description/cnreadme.jpg differ diff --git a/app_saas/static/description/demo1.jpg b/app_saas/static/description/demo1.jpg new file mode 100644 index 00000000..f9ebf635 Binary files /dev/null and b/app_saas/static/description/demo1.jpg differ diff --git a/app_saas/static/description/demo2.jpg b/app_saas/static/description/demo2.jpg new file mode 100644 index 00000000..f53cf780 Binary files /dev/null and b/app_saas/static/description/demo2.jpg differ diff --git a/app_saas/static/description/demo3.jpg b/app_saas/static/description/demo3.jpg new file mode 100644 index 00000000..e8d83662 Binary files /dev/null and b/app_saas/static/description/demo3.jpg differ diff --git a/app_saas/static/description/demo4.jpg b/app_saas/static/description/demo4.jpg new file mode 100644 index 00000000..46fd516d Binary files /dev/null and b/app_saas/static/description/demo4.jpg differ diff --git a/app_saas/static/description/demo5.jpg b/app_saas/static/description/demo5.jpg new file mode 100644 index 00000000..9cfee165 Binary files /dev/null and b/app_saas/static/description/demo5.jpg differ diff --git a/app_saas/static/description/icon.png b/app_saas/static/description/icon.png new file mode 100644 index 00000000..8c7b0fbb Binary files /dev/null and b/app_saas/static/description/icon.png differ diff --git a/app_saas/static/description/index.html b/app_saas/static/description/index.html new file mode 100644 index 00000000..3d64d99c --- /dev/null +++ b/app_saas/static/description/index.html @@ -0,0 +1,136 @@ + + + + +
+

Ai通行证.Odoo中文应用商店SaaS云服务客户端,一键微信QQ淘宝抖音全媒体登录SSO

+

odooapp.cn SaaS Client-Ai Passport.SSO with

+

一键获取最新应用信息,最新行业服务包,一键获取Odoo中文翻译更新,快速获取Odoo服务,Odoo升级评估

+
+ + + +
+
+

1.启用后即可使用 odooapp.cn 提供的全网社交媒体整合登录

+

支持微信、抖音、QQ、淘宝、钉钉、支付宝、企业微信、Facebook、Google、微软Azure等整合登录。

+

未经用户明确同意,本应用不会获取任何用户系统数据.

+

相关内容,请参考用户协议及我们的隐私政策:

+

https://www.odooapp.cn/conditions

+

https://www.odooapp.cn/privacy-policy

+
+ +
+

用户可直接调用SSO一键登录

+
+ +
+
+
+ +
+
+

2. 快速访问Odoo中文应用商店并获取独享Odoo中文通行码,可随时断开云服务连接

+

启用云服务后,即可获取最新功能推送,版本比对信息,提供版本升级建议

+
+ +
+
+
+ +
+
+

标准的Oauth2登录支持,可方便配置

+

安装后,用户即可使用 odooapp.cn 提供的 Ai通行证进行登录

+
+ +
+

可以使用微信抖音QQ等在Odoo中文应用商店登录,同意并继续后即可登入自有Odoo

+
+ +
+

自定义默认用户模板,为用户启用不同权限

+
+ +
+
+
+ +
+
+

相关服务正在紧张开发中,后续可享用更多服务

+
+ +
+
+
+ + + + +
+

- How to setup and use -

+

This app need no extra module. The price already included

+
+
+
+

+ 1. Buy and Install +

+

+ 2. Read the app description for user guide +

+

+ 3. Enjoy and easy use +

+
+
+ +
+
+

4. More information in our FAQ

+
+ https://www.odooai.cn/faq +
+
+
+ + + + + + +
+
+
+

Technical Help & Support

+
+
+
+

+ For any type of technical help & support requests, Feel free to contact us

+ + odoo@china.com +

+ Via QQ: 300883 (App user would not get QQ or any other IM support. Only for odoo project customize.)

+ + 300883@qq.com +
+
+

Visit our website for more support.

+

https://www.odooai.cn

+
+
+
+
+ + \ No newline at end of file diff --git a/app_saas/static/description/qr.png b/app_saas/static/description/qr.png new file mode 100644 index 00000000..b7433fc9 Binary files /dev/null and b/app_saas/static/description/qr.png differ diff --git a/app_saas/static/img/icon_odooai.png b/app_saas/static/img/icon_odooai.png new file mode 100644 index 00000000..a022f8d0 Binary files /dev/null and b/app_saas/static/img/icon_odooai.png differ diff --git a/app_saas/static/img/icon_odooapp.png b/app_saas/static/img/icon_odooapp.png new file mode 100644 index 00000000..775a12ee Binary files /dev/null and b/app_saas/static/img/icon_odooapp.png differ diff --git a/app_saas/static/img/logo_odooai.png b/app_saas/static/img/logo_odooai.png new file mode 100644 index 00000000..482f2a50 Binary files /dev/null and b/app_saas/static/img/logo_odooai.png differ diff --git a/app_saas/static/src/js/odooai.cn b/app_saas/static/src/js/odooai.cn new file mode 100644 index 00000000..e69de29b diff --git a/app_saas/static/src/scss/odooai.cn b/app_saas/static/src/scss/odooai.cn new file mode 100644 index 00000000..e69de29b diff --git a/app_saas/static/src/scss/style.scss b/app_saas/static/src/scss/style.scss new file mode 100644 index 00000000..210b0a1e --- /dev/null +++ b/app_saas/static/src/scss/style.scss @@ -0,0 +1,3 @@ +// scss sample + + diff --git a/app_saas/static/src/xml/odooai.cn b/app_saas/static/src/xml/odooai.cn new file mode 100644 index 00000000..e69de29b diff --git a/app_saas/views/auth_oauth_provider_views.xml b/app_saas/views/auth_oauth_provider_views.xml new file mode 100644 index 00000000..83fa29b0 --- /dev/null +++ b/app_saas/views/auth_oauth_provider_views.xml @@ -0,0 +1,16 @@ + + + + app.auth.oauth.provider.form + auth.oauth.provider + + + + + + + + + + + diff --git a/app_saas/views/res_config_settings_views.xml b/app_saas/views/res_config_settings_views.xml new file mode 100644 index 00000000..1d9d03d2 --- /dev/null +++ b/app_saas/views/res_config_settings_views.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_saas/wizard/odooai.cn b/app_saas/wizard/odooai.cn new file mode 100644 index 00000000..e69de29b