class hr_language(orm.Model): _name = 'hr.language' _columns = { 'name': fields.selection( tools.scan_languages(), 'Language', required=True, ), 'description': fields.char( 'Description', size=64, required=True, translate=True, ), 'employee_id': fields.many2one( 'hr.employee', 'Employee', required=True, ), 'read': fields.boolean('Read', ), 'write': fields.boolean('Write', ), 'speak': fields.boolean('Speak', ), } _defaults = { 'read': True, 'write': True, 'speak': True, }
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template', ondelete='restrict') demo = fields.Boolean('Install Demo Data') maximum_allowed_dbs_per_partner = fields.Integer(help='maximum allowed non-trial databases per customer', require=True, default=0) maximum_allowed_trial_dbs_per_partner = fields.Integer(help='maximum allowed trial databases per customer', require=True, default=0) max_users = fields.Char('Initial Max users', default='0') total_storage_limit = fields.Integer('Total storage limit (MB)') block_on_expiration = fields.Boolean('Block clients on expiration', default=False) block_on_storage_exceed = fields.Boolean('Block clients on storage exceed', default=False) def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') _order = 'sequence' dbname_template = fields.Char('DB Names', help='Used for generating client database domain name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', ondelete='restrict', help='User this saas server or choose random') website_description = fields.Html('Website description') logo = fields.Binary('Logo') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.one def _new_database_vals(self, vals): vals['max_users'] = self.max_users vals['total_storage_limit'] = self.total_storage_limit vals['block_on_expiration'] = self.block_on_expiration vals['block_on_storage_exceed'] = self.block_on_storage_exceed return vals @api.multi def create_new_database(self, **kwargs): return self._create_new_database(**kwargs) @api.multi def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=False, trial=False, support_team_id=None, async=None, owner_password=None):
class PartnerLanguange(models.Model): _name = "partner.language" name = fields.Selection(selection=tools.scan_languages(), string=u"Language", required=True) description = fields.Char(string=u"Description", size=64, required=True) partner_id = fields.Many2one(comodel_name="res.partner", string=u"Partner", required=True) can_read = fields.Boolean(string=u"Read", default=True, oldname="read") can_write = fields.Boolean(string=u"Write", default=True, oldname="write") can_speak = fields.Boolean(string=u"Speak", default=True, oldname="speak")
class hr_language(models.Model): _name = 'hr.language' name = fields.Selection(tools.scan_languages(), string=u"Language", required=True) description = fields.Char(string=u"Description", size=64, required=True) employee_id = fields.Many2one('hr.employee', string=u"Employee", required=True) can_read = fields.Boolean(u"Read", default=True, oldname='read') can_write = fields.Boolean(u"Write", default=True, oldname='write') can_speak = fields.Boolean(u"Speak", default=True, oldname='speak')
class base_language_install(osv.osv_memory): """ Install Language""" _name = "base.language.install" _description = "Install Language" _columns = { 'lang': fields.selection(tools.scan_languages(), 'Language', required=True), 'overwrite': fields.boolean( 'Overwrite Existing Terms', help= "If you check this box, your customized translations will be overwritten and replaced by the official ones." ), 'state': fields.selection([('init', 'init'), ('done', 'done')], 'Status', readonly=True), } _defaults = {'state': 'init', 'overwrite': False} def lang_install(self, cr, uid, ids, context=None): if context is None: context = {} language_obj = self.browse(cr, uid, ids)[0] lang = language_obj.lang if lang: modobj = self.pool.get('ir.module.module') mids = modobj.search(cr, uid, [('state', '=', 'installed')]) if language_obj.overwrite: context = {'overwrite': True} modobj.update_translations(cr, uid, mids, lang, context or {}) self.write(cr, uid, ids, {'state': 'done'}, context=context) return { 'name': _('Language Pack'), 'view_type': 'form', 'view_mode': 'form', 'view_id': False, 'res_model': 'base.language.install', 'domain': [], 'context': dict(context, active_ids=ids), 'type': 'ir.actions.act_window', 'target': 'new', 'res_id': ids and ids[0] or False, }
class employee_idioma(osv.Model): _name = 'employee.idioma' _description = 'Idiomas' _order = 'date_start desc' _columns = { 'employee_id': fields.many2one('hr.employee', 'Employee', required=True), 'idioma': fields.selection(tools.scan_languages(), 'Idioma', required=True), 'instituicao': fields.many2one('hr.instituicao', u'Instituição', required=True), 'curso': fields.char('Curso', size=128, required=True), 'status': fields.selection(AVAILABLE_LANGUAGE_STATUS, 'Status', required=True, translate=True), 'date_start': fields.date(u'Data Início', required=True), 'date_end': fields.date(u'Data Conclusão'), 'observations': fields.text(u'Observações'), } _sql_constraints = [ ('date_sequence', 'CHECK ((date_end IS NOT NULL AND date_start <= date_end) OR date_end IS NULL)', u'A data de início deve ser menor que a data de finalização !'), ]
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template', ondelete='restrict') demo = fields.Boolean('Install Demo Data') maximum_allowed_db_per_partner = fields.Integer( help='maximum allowed databases per customer', default=0) max_users = fields.Char('Initial Max users', default='0') total_storage_limit = fields.Integer('Total storage limit (MB)') block_on_expiration = fields.Boolean('Block clients on expiration', default=False) block_on_storage_exceed = fields.Boolean('Block clients on storage exceed', default=False) def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') _order = 'sequence' dbname_template = fields.Char( 'DB Names', help= 'Used for generating client database domain name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', ondelete='restrict', help='User this saas server or choose random') website_description = fields.Html('Website description') logo = fields.Binary('Logo') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.one def _new_database_vals(self, vals): vals['max_users'] = self.max_users vals['total_storage_limit'] = self.total_storage_limit vals['block_on_expiration'] = self.block_on_expiration vals['block_on_storage_exceed'] = self.block_on_storage_exceed return vals @api.multi def create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=False, trial=False, support_team_id=None): self.ensure_one() db_count = self.env['saas_portal.client'].search_count([ ('partner_id', '=', partner_id), ('state', '=', 'open'), ('plan_id', '=', self.id) ]) if self.maximum_allowed_db_per_partner != 0 and db_count >= self.maximum_allowed_db_per_partner: raise MaximumDBException server = self.server_id if not server: server = self.env['saas_portal.server'].get_saas_server() server.action_sync_server() vals = { 'name': dbname or self.generate_dbname()[0], 'server_id': server.id, 'plan_id': self.id, 'partner_id': partner_id, 'trial': trial, 'support_team_id': support_team_id, } client = None if client_id: vals['client_id'] = client_id client = self.env['saas_portal.client'].search([('client_id', '=', client_id)]) vals = self._new_database_vals(vals)[0] if client: client.write(vals) else: client = self.env['saas_portal.client'].create(vals) client_id = client.client_id scheme = server.request_scheme port = server.request_port if user_id: owner_user = self.env['res.users'].browse(user_id) else: owner_user = self.env.user owner_user_data = { 'user_id': owner_user.id, 'login': owner_user.login, 'name': owner_user.name, 'email': owner_user.email, } trial_expiration_datetime = datetime.strptime( client.create_date, DEFAULT_SERVER_DATETIME_FORMAT) + timedelta( hours=self.expiration) # for trial state = { 'd': client.name, 'e': trial and trial_expiration_datetime or client.create_date, 'r': '%s://%s:%s/web' % (scheme, client.name, port), 'owner_user': owner_user_data, 't': client.trial, } if self.template_id: state.update({'db_template': self.template_id.name}) scope = ['userinfo', 'force_login', 'trial', 'skiptheuse'] url = server._request_server( path='/saas_server/new_database', scheme=scheme, port=port, state=state, client_id=client_id, scope=scope, )[0] res = requests.get(url, verify=(self.server_id.request_scheme == 'https' and self.server_id.verify_ssl)) if res.status_code != 200: # TODO /saas_server/new_database show more details here raise exceptions.Warning('Error %s' % res.status_code) data = simplejson.loads(res.text) params = { 'state': data.get('state'), 'access_token': client.oauth_application_id._get_access_token(user_id, create=True), } url = '{url}?{params}'.format(url=data.get('url'), params=werkzeug.url_encode(params)) # send email if notify_user: template = self.env.ref('saas_portal.email_template_create_saas') client.message_post_with_template(template.id, composition_mode='comment') if trial: client.expiration_datetime = trial_expiration_datetime client.send_params_to_client_db() client.server_id.action_sync_server() return {'url': url, 'id': client.id, 'client_id': client_id} @api.one def generate_dbname(self, raise_error=True): if not self.dbname_template: if raise_error: raise exceptions.Warning( _('Template for db name is not configured')) return '' sequence = self.env['ir.sequence'].get('saas_portal.plan') return self.dbname_template.replace('%i', sequence) @api.multi def create_template(self): assert len(self) == 1, 'This method is applied only for single record' # TODO use create_new_database function plan = self[0] state = { 'd': plan.template_id.name, 'demo': plan.demo and 1 or 0, 'addons': [], 'lang': plan.lang, 'tz': plan.tz, 'is_template_db': 1, } client_id = plan.template_id.client_id plan.template_id.server_id = plan.server_id params = plan.server_id._request_params( path='/saas_server/new_database', state=state, client_id=client_id)[0] access_token = plan.template_id.oauth_application_id.sudo( )._get_access_token(create=True) params.update({ 'token_type': 'Bearer', 'access_token': access_token, 'expires_in': 3600, }) url = '{scheme}://{saas_server}:{port}{path}?{params}'.format( scheme=plan.server_id.request_scheme, saas_server=plan.server_id.name, port=plan.server_id.request_port, path='/saas_server/new_database', params=werkzeug.url_encode(params)) res = requests.get(url, verify=(plan.server_id.request_scheme == 'https' and plan.server_id.verify_ssl)) if res.ok != True: msg = """Status Code - %s Reason - %s URL - %s """ % (res.status_code, res.reason, res.url) raise Warning(msg) return self.action_sync_server() @api.multi def action_sync_server(self): for r in self: r.server_id.action_sync_server() return True @api.multi def edit_template(self): return self[0].template_id.edit_database() @api.multi def upgrade_template(self): return self[0].template_id.upgrade_database() @api.multi def delete_template(self): res = self[0].template_id.delete_database() return res
def exp_list_lang(self): return tools.scan_languages()
def exp_list_lang(self): return tools.scan_languages()
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template', ondelete='restrict') demo = fields.Boolean('Install Demo Data') maximum_allowed_dbs_per_partner = fields.Integer( help='maximum allowed non-trial databases per customer', require=True, default=0) maximum_allowed_trial_dbs_per_partner = fields.Integer( help='maximum allowed trial databases per customer', require=True, default=0) max_users = fields.Char('Initial Max users', default='0', help='leave 0 for no limit') total_storage_limit = fields.Integer('Total storage limit (MB)') block_on_expiration = fields.Boolean('Block clients on expiration', default=False) block_on_storage_exceed = fields.Boolean('Block clients on storage exceed', default=False) def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') _order = 'sequence' grace_period = fields.Integer('Grace period (days)', help='initial days before expiration') dbname_template = fields.Char( 'DB Names', help= 'Used for generating client database domain name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', ondelete='restrict', help='User this saas server or choose random') website_description = fields.Html('Website description') logo = fields.Binary('Logo') on_create = fields.Selection([ ('login', 'Log into just created instance'), ], string="Workflow on create", default='login') on_create_email_template = fields.Many2one('email.template') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.multi def _new_database_vals(self, vals): self.ensure_one() vals['max_users'] = self.max_users vals['total_storage_limit'] = self.total_storage_limit vals['block_on_expiration'] = self.block_on_expiration vals['block_on_storage_exceed'] = self.block_on_storage_exceed return vals @api.multi def _prepare_owner_user_data(self, user_id): """ Prepare the dict of values to update owner user data in client instalnce. This method may be overridden to implement custom values (making sure to call super() to establish a clean extension chain). """ self.ensure_one() owner_user = self.env['res.users'].browse(user_id) or self.env.user owner_user_data = { 'user_id': owner_user.id, 'login': owner_user.login, 'name': owner_user.name, 'email': owner_user.email, 'password_crypt': owner_user.password_crypt, } return owner_user_data @api.multi def _get_expiration(self, trial): self.ensure_one() trial_hours = trial and self.expiration initial_expiration_datetime = datetime.now() trial_expiration_datetime = (initial_expiration_datetime + timedelta( hours=trial_hours)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) return trial and trial_expiration_datetime or initial_expiration_datetime.strftime( DEFAULT_SERVER_DATETIME_FORMAT) @api.multi def create_new_database(self, **kwargs): return self._create_new_database(**kwargs) @api.multi def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=False, trial=False, support_team_id=None, async=None): self.ensure_one() server = self.server_id if not server: server = self.env['saas_portal.server'].get_saas_server() # server.action_sync_server() if not partner_id and user_id: user = self.env['res.users'].browse(user_id) partner_id = user.partner_id.id if not trial and self.maximum_allowed_dbs_per_partner != 0: db_count = self.env['saas_portal.client'].search_count([ ('partner_id', '=', partner_id), ('state', '=', 'open'), ('plan_id', '=', self.id), ('trial', '=', False) ]) if db_count >= self.maximum_allowed_dbs_per_partner: raise MaximumDBException( "Limit of databases for this plan is %(maximum)s reached" % {'maximum': self.maximum_allowed_dbs_per_partner}) if trial and self.maximum_allowed_trial_dbs_per_partner != 0: trial_db_count = self.env['saas_portal.client'].search_count([ ('partner_id', '=', partner_id), ('state', '=', 'open'), ('plan_id', '=', self.id), ('trial', '=', True) ]) if trial_db_count >= self.maximum_allowed_trial_dbs_per_partner: raise MaximumTrialDBException( "Limit of trial databases for this plan is %(maximum)s reached" % {'maximum': self.maximum_allowed_trial_dbs_per_partner}) client_expiration = self._get_expiration(trial) vals = { 'name': dbname or self.generate_dbname(), 'server_id': server.id, 'plan_id': self.id, 'partner_id': partner_id, 'trial': trial, 'support_team_id': support_team_id, 'expiration_datetime': client_expiration, } client = None if client_id: vals['client_id'] = client_id client = self.env['saas_portal.client'].search([('client_id', '=', client_id)]) vals = self._new_database_vals(vals) if client: client.write(vals) else: client = self.env['saas_portal.client'].create(vals) client_id = client.client_id owner_user_data = self._prepare_owner_user_data(user_id) state = { 'd': client.name, 'public_url': client.public_url, 'e': client_expiration, 'r': client.public_url + 'web', 'owner_user': owner_user_data, 't': client.trial, } if self.template_id: state.update({'db_template': self.template_id.name}) scope = ['userinfo', 'force_login', 'trial', 'skiptheuse'] req, req_kwargs = server._request_server( path='/saas_server/new_database', state=state, client_id=client_id, scope=scope, ) res = requests.Session().send(req, **req_kwargs) if res.status_code != 200: raise Warning('Error on request: %s\nReason: %s \n Message: %s' % (req.url, res.reason, res.content)) data = simplejson.loads(res.text) params = { 'state': data.get('state'), 'access_token': client.oauth_application_id._get_access_token(user_id, create=True), } url = '{url}?{params}'.format(url=data.get('url'), params=werkzeug.url_encode(params)) auth_url = url # send email # TODO: get rid of such attributes as ``notify_user``, ``trial`` - move them on plan settings (use different plans for trials and non-trials) if notify_user or self.on_create == 'email': template = self.on_create_email_template if template: email_ctx = { 'default_model': 'saas_portal.client', 'default_res_id': client.id, 'default_use_template': bool(template), 'default_template_id': template.id, 'default_composition_mode': 'comment', } client.send_params_to_client_db() # TODO make async call of action_sync_server here # client.server_id.action_sync_server() client.sync_client() return { 'url': url, 'id': client.id, 'client_id': client_id, 'auth_url': auth_url }
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template', ondelete='restrict') demo = fields.Boolean('Install Demo Data') maximum_allowed_dbs_per_partner = fields.Integer( help='maximum allowed non-trial databases per customer', require=True, default=0) maximum_allowed_trial_dbs_per_partner = fields.Integer( help='maximum allowed trial databases per customer', require=True, default=0) max_users = fields.Char('Initial Max users', default='0') total_storage_limit = fields.Integer('Total storage limit (MB)') block_on_expiration = fields.Boolean('Block clients on expiration', default=False) block_on_storage_exceed = fields.Boolean('Block clients on storage exceed', default=False) def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') _order = 'sequence' dbname_template = fields.Char( 'DB Names', help= 'Used for generating client database domain name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', ondelete='restrict', help='User this saas server or choose random') website_description = fields.Html('Website description') logo = fields.Binary('Logo') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.one def _new_database_vals(self, vals): vals['max_users'] = self.max_users vals['total_storage_limit'] = self.total_storage_limit vals['block_on_expiration'] = self.block_on_expiration vals['block_on_storage_exceed'] = self.block_on_storage_exceed return vals @api.multi def create_new_database(self, **kwargs): return self._create_new_database(**kwargs) @api.multi def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=False, trial=False, support_team_id=None, async=None): self.ensure_one() server = self.server_id if not server: server = self.env['saas_portal.server'].get_saas_server() server.action_sync_server() if not partner_id and user_id: user = self.env['res.users'].browse(user_id) partner_id = user.partner_id.id if not trial and self.maximum_allowed_dbs_per_partner != 0: db_count = self.env['saas_portal.client'].search_count([ ('partner_id', '=', partner_id), ('state', '=', 'open'), ('plan_id', '=', self.id), ('trial', '=', False) ]) if db_count >= self.maximum_allowed_dbs_per_partner: raise MaximumDBException( "Limit of databases for this plan is %(maximum)s reached" % {'maximum': self.maximum_allowed_dbs_per_partner}) if trial and self.maximum_allowed_trial_dbs_per_partner != 0: trial_db_count = self.env['saas_portal.client'].search_count([ ('partner_id', '=', partner_id), ('state', '=', 'open'), ('plan_id', '=', self.id), ('trial', '=', True) ]) if trial_db_count >= self.maximum_allowed_trial_dbs_per_partner: raise MaximumTrialDBException( "Limit of trial databases for this plan is %(maximum)s reached" % {'maximum': self.maximum_allowed_trial_dbs_per_partner}) vals = { 'name': dbname or self.generate_dbname()[0], 'server_id': server.id, 'plan_id': self.id, 'partner_id': partner_id, 'trial': trial, 'support_team_id': support_team_id, } client = None if client_id: vals['client_id'] = client_id client = self.env['saas_portal.client'].search([('client_id', '=', client_id)]) vals = self._new_database_vals(vals)[0] if client: client.write(vals) else: client = self.env['saas_portal.client'].create(vals) client_id = client.client_id scheme = server.request_scheme port = server.request_port if user_id: owner_user = self.env['res.users'].browse(user_id) else: owner_user = self.env.user owner_user_data = { 'user_id': owner_user.id, 'login': owner_user.login, 'name': owner_user.name, 'email': owner_user.email, } trial_expiration_datetime = ( datetime.strptime(client.create_date, DEFAULT_SERVER_DATETIME_FORMAT) + timedelta(hours=self.expiration)).strftime( DEFAULT_SERVER_DATETIME_FORMAT) # for trial state = { 'd': client.name, 'e': trial and trial_expiration_datetime or client.create_date, 'r': '%s://%s:%s/web' % (scheme, client.name, port), 'owner_user': owner_user_data, 't': client.trial, } if self.template_id: state.update({'db_template': self.template_id.name}) scope = ['userinfo', 'force_login', 'trial', 'skiptheuse'] url = server._request_server( path='/saas_server/new_database', scheme=scheme, port=port, state=state, client_id=client_id, scope=scope, )[0] res = requests.get(url, verify=(self.server_id.request_scheme == 'https' and self.server_id.verify_ssl)) if res.status_code != 200: # TODO /saas_server/new_database show more details here raise exceptions.Warning('Error %s' % res.status_code) data = simplejson.loads(res.text) params = { 'state': data.get('state'), 'access_token': client.oauth_application_id._get_access_token(user_id, create=True), } url = '{url}?{params}'.format(url=data.get('url'), params=werkzeug.url_encode(params)) # send email if notify_user: template = self.env.ref('saas_portal.email_template_create_saas') client.message_post_with_template(template.id, composition_mode='comment') if trial: client.expiration_datetime = trial_expiration_datetime client.send_params_to_client_db() client.server_id.action_sync_server() return {'url': url, 'id': client.id, 'client_id': client_id}
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template') demo = fields.Boolean('Install Demo Data') def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') required_addons_ids = fields.Many2many('ir.module.module', relation='plan_required_addons_rel', column1='plan_id', column2='module_id', string='Required Addons') optional_addons_ids = fields.Many2many('ir.module.module', relation='plan_optional_addons_rel', column1='plan_id', column2='module_id', string='Optional Addons') _order = 'sequence' dbname_template = fields.Char( 'DB Names', help= 'Template for db name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', help='User this saas server or choose random') website_description = fields.Text('Website description') logo = fields.Binary('Logo') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.one def _new_database_vals(self, vals): if self.expiration: now = datetime.now() delta = timedelta(hours=self.expiration) vals['expiration_datetime'] = ( now + delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT) return vals @api.one def _create_new_database(self, dbname=None, client_id=None, partner_id=None): server = self.server_id if not server: server = self.env['saas_portal.server'].get_saas_server() server.action_sync_server() vals = { 'name': dbname or self.generate_dbname()[0], 'server_id': server.id, 'plan_id': self.id, 'partner_id': partner_id, } client = None if client_id: vals['client_id'] = client_id client = self.env['saas_portal.client'].search([('client_id', '=', client_id)]) vals = self._new_database_vals(vals)[0] if client: client.write(vals) else: client = self.env['saas_portal.client'].create(vals) client_id = client.client_id scheme = server.request_scheme port = server.request_port state = { 'd': client.name, 'e': client.expiration_datetime, 'r': '%s://%s:%s/web' % (scheme, port, client.name), } if self.template_id: state.update({'db_template': self.template_id.name}) scope = ['userinfo', 'force_login', 'trial', 'skiptheuse'] url = server._request( path='/saas_server/new_database', scheme=scheme, port=port, state=state, client_id=client_id, scope=scope, )[0] return url @api.one def generate_dbname(self, raise_error=True): if not self.dbname_template: if raise_error: raise exceptions.Warning( _('Template for db name is not configured')) return '' sequence = self.env['ir.sequence'].get('saas_portal.plan') return self.dbname_template.replace('%i', sequence) @api.multi def create_template(self): assert len(self) == 1, 'This method is applied only for single record' plan = self[0] addons = [x.name for x in plan.required_addons_ids] state = { 'd': plan.template_id.name, 'demo': plan.demo and 1 or 0, 'addons': addons, 'lang': plan.lang, 'tz': plan.tz, 'is_template_db': 1, } client_id = plan.template_id.client_id plan.template_id.server_id = plan.server_id url = plan.server_id._request(path='/saas_server/new_database', state=state, client_id=client_id) return { 'type': 'ir.actions.act_url', 'target': 'new', 'name': 'Create Template', 'url': url } @api.one def action_sync_server(self): self.server_id.action_sync_server() @api.multi def edit_template(self): return self[0].template_id.edit_database() def upgrade_template(self, cr, uid, ids, context=None): obj = self.browse(cr, uid, ids[0]) return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'saas.config', 'target': 'new', 'context': { 'default_action': 'upgrade', 'default_database': obj.template_id.name } } @api.multi def delete_template(self): return self[0].template_id.delete_database()
class database_type(models.Model): _name = 'infrastructure.database_type' _description = 'database_type' _order = 'sequence' sequence = fields.Integer( 'Sequence', default=10, ) name = fields.Char(string='Name', required=True) description = fields.Text(string='Description', ) is_production = fields.Boolean( help='Databases of this type are used to get data to invoice on ' 'contracts and also used to get priority when duplicating') backups_enable = fields.Boolean('Backups Enable?', ) check_database = fields.Boolean( 'Check Databse with cron', help="Suggest Check Databases Automatically. Suggested for instances " "that restart automatically") demo_data = fields.Boolean(string='Demo Data?', help='Use demo data by default on databases?') prefix = fields.Char(string='Prefix', required=True, size=8) max_dbs_per_contract = fields.Integer( string='Max. Dbs per contract', # TODO we should use contracts instead of environment # TODO we should use max dbs instead of instance help='Maximum instances of this type that can exist per environment', ) odoo_run_prefix = fields.Char(string='Odoo Run Prefix', help='For eg. used for resources limitation') postgres_run_prefix = fields.Char( string='Postgres Run Prefix', help='For eg. used for resources limitation') url_prefix = fields.Char(string='URL Prefix') service_type = fields.Selection( [ ('docker', 'Docker Restart'), # ('upstart', 'Upstart Service'), ('no_service', 'No Service') ], default='docker', required=True, ) type = fields.Selection( [('normal', 'Normal'), ('protected', 'Protected'), ('auto_deactivation', 'Auto Deactivation'), ('auto_drop', 'Auto Drop'), ('auto_deact_and_drop', 'Auto Deactivation and Drop')], 'Type', help="Depending on the type:" "* Normal: nothing special is made" "* Protected: needs special confirmation before some operations" "* Auto Deactivation: automatically deactivated on deactivation date" "* Auto Drop: automatically dropped on deactivation date" "* Auto Deactivation and Drop: automatically deactivated on" "deactivation date and automatically dropped on deactivation date", required=True, default='normal') sources_type = fields.Selection( [('own', 'Own'), ('clone_from', 'Clone From'), ('use_from', 'Use From')], 'Sources Type', required=True, default='own', help='* own: sources are cloned from host (git, bitbucet, etc)\n' '* clone_from: sources are cloned from another instance' '* use_from: sources are used from another instance') sources_from_id = fields.Many2one( 'infrastructure.database_type', string='Sources From', ) color = fields.Integer(string='Color') auto_drop_days = fields.Integer(string='Automatic Drop Days') protect_db = fields.Boolean(string='Protect Databases?') auto_deactivation_days = fields.Integer( string='Automatic Deactivation Days') install_lang_id = fields.Selection( tools.scan_languages(), string='Install Language', ) db_filter = fields.Many2one( 'infrastructure.db_filter', string='DB Filter', help='It will be used as default on Instances', ) workers = fields.Selection( [('clasic_rule', 'Clasic Rule'), ('fix_number', 'Fix Number')], string='Workers Filter', required=True, default='clasic_rule', help='Clasic Rule means workers = server_processors * 2 + 1') workers_number = fields.Integer('Workers Number', ) server_mode_value = fields.Char('Server Mode Value', ) instance_log_level = fields.Selection( [(u'info', 'info'), (u'debug_rpc', 'debug_rpc'), (u'warn', 'warn'), (u'test', 'test'), (u'critical', 'critical'), (u'debug_sql', 'debug_sql'), (u'error', 'error'), (u'debug', 'debug'), (u'debug_rpc_answer', 'debug_rpc_answer')], string='Default Instance Log Level', default='info', required=True, ) @api.onchange('service_type') def change_service_type(self): if self.service_type != 'no_service': self.check_database = True else: self.check_database = False @api.multi def get_password(self): self.ensure_one() # TODO depreciar db_admin_pass e instance_admin_pass que ya no los # usamos chars = string.ascii_letters + string.digits # no usamos estas porque nos dan error con docker # + '!@#$%^&*()' random.seed = (os.urandom(1024)) return ''.join(random.choice(chars) for i in range(20))
def _get_lang(self): return tools.scan_languages()
def _langsel(self): return tools.scan_languages()
class RunbotBuild(models.Model): ''' Inherit class runbot_build to add field to select the language & the function with a job to install and assign the language to users if this is captured too is added with an super the function create to assign the language from repo in the builds. ''' _inherit = "runbot.build" lang = fields.Selection( tools.scan_languages(), 'Language', help='Language to change ' 'instance after of run test.', copy=True) @api.multi def cmd(self): """Return a list describing the command to start the build""" cmd, modules = super(RunbotBuild, self).cmd() for build in self: if build.lang and build.job == 'job_30_run': cmd.append("--load-language=%s" % (build.lang)) return cmd, modules @api.one def update_lang(self): """Set lang to all users into '-all' database""" if self.lang: db_name = "%s-all" % self.dest # All odoo versions has openerp/release.py file sys.path.insert(0, self.server("openerp")) try: release = __import__("release") finally: sys.path.pop(0) if release.version_info < (7, 0): # Old version used `res_users` table to set `lang` run(['psql', db_name, '-c', "UPDATE res_users SET lang='{lang}';".format( lang=self.lang)]) else: # New version use `res_partner` table to set `lang` run(['psql', db_name, '-c', "UPDATE res_partner SET lang='{lang}' ".format( lang=self.lang) + "WHERE id IN (SELECT partner_id FROM res_users);"]) return True def job_30_run(self, cr, uid, build, lock_path, log_path): res = super(RunbotBuild, self).job_30_run(cr, uid, build, lock_path, log_path) self.update_lang(cr, uid, build.id) return res @api.model def create(self, values): """ This method set language from repo in the build. """ if values.get('branch_id', False) and 'lang' not in values: lang = self.env['runbot.branch'].browse( values['branch_id']).repo_id.lang values.update({ 'lang': lang, }) return super(RunbotBuild, self).create(values)
class SaasPortalPlan(models.Model): _name = 'saas_portal.plan' name = fields.Char('Plan', required=True) summary = fields.Char('Summary') template_id = fields.Many2one('saas_portal.database', 'Template') demo = fields.Boolean('Install Demo Data') def _get_default_lang(self): return self.env.lang def _default_tz(self): return self.env.user.tz lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang) tz = fields.Selection(_tz_get, 'TimeZone', default=_default_tz) sequence = fields.Integer('Sequence') state = fields.Selection([('draft', 'Draft'), ('confirmed', 'Confirmed')], 'State', compute='_get_state', store=True) expiration = fields.Integer('Expiration (hours)', help='time to delete database. Use for demo') _order = 'sequence' dbname_template = fields.Char( 'DB Names', help= 'Template for db name. Use %i for numbering. Ignore if you use manually created db names', placeholder='crm-%i.odoo.com') server_id = fields.Many2one('saas_portal.server', string='SaaS Server', help='User this saas server or choose random') website_description = fields.Text('Website description') logo = fields.Binary('Logo') @api.one @api.depends('template_id.state') def _get_state(self): if self.template_id.state == 'template': self.state = 'confirmed' else: self.state = 'draft' @api.one def _new_database_vals(self, vals): if self.expiration: now = datetime.now() delta = timedelta(hours=self.expiration) vals['expiration_datetime'] = ( now + delta).strftime(DEFAULT_SERVER_DATETIME_FORMAT) return vals @api.one def create_new_database(self, dbname=None, client_id=None, partner_id=None): server = self.server_id if not server: server = self.env['saas_portal.server'].get_saas_server() server.action_sync_server() vals = { 'name': dbname or self.generate_dbname()[0], 'server_id': server.id, 'plan_id': self.id, 'partner_id': partner_id, } client = None if client_id: vals['client_id'] = client_id client = self.env['saas_portal.client'].search([('client_id', '=', client_id)]) vals = self._new_database_vals(vals)[0] if client: client.write(vals) else: client = self.env['saas_portal.client'].create(vals) client_id = client.client_id scheme = server.request_scheme port = server.request_port state = { 'd': client.name, 'e': client.expiration_datetime, 'r': '%s://%s:%s/web' % (scheme, client.name, port), } if self.template_id: state.update({'db_template': self.template_id.name}) scope = ['userinfo', 'force_login', 'trial', 'skiptheuse'] url = server._request( path='/saas_server/new_database', scheme=scheme, port=port, state=state, client_id=client_id, scope=scope, )[0] return url @api.one def generate_dbname(self, raise_error=True): if not self.dbname_template: if raise_error: raise exceptions.Warning( _('Template for db name is not configured')) return '' sequence = self.env['ir.sequence'].get('saas_portal.plan') return self.dbname_template.replace('%i', sequence) @api.multi def create_template(self): assert len(self) == 1, 'This method is applied only for single record' plan = self[0] state = { 'd': plan.template_id.name, 'demo': plan.demo and 1 or 0, 'addons': [], 'lang': plan.lang, 'tz': plan.tz, 'is_template_db': 1, } client_id = plan.template_id.client_id plan.template_id.server_id = plan.server_id params = plan.server_id._request_params( path='/saas_server/new_database', state=state, client_id=client_id)[0] domain = [('application_id', '=', plan.template_id.oauth_application_id.id)] access_token = self.env['oauth.access_token'].sudo().search( domain, order='id DESC', limit=1) if access_token: access_token = access_token[0].token else: token_obj = plan.server_id.create_access_token( plan.template_id.oauth_application_id.id) access_token = token_obj.token params.update({ 'token_type': 'Bearer', 'access_token': access_token, 'expires_in': 3600, }) url = '{scheme}://{saas_server}:{port}{path}?{params}'.format( scheme=plan.server_id.request_scheme, saas_server=plan.server_id.name, port=plan.server_id.request_port, path='/saas_server/new_database', params=werkzeug.url_encode(params)) res = requests.get(url, verify=(plan.server_id.request_scheme == 'https' and plan.server_id.verify_ssl)) if res.ok != True: msg = """Status Code - %s Reason - %s URL - %s """ % (res.status_code, res.reason, res.url) raise Warning(msg) return self.action_sync_server() @api.one def action_sync_server(self): self.server_id.action_sync_server() @api.multi def edit_template(self): return self[0].template_id.edit_database() @api.multi def upgrade_template(self): return self[0].template_id.upgrade_database() @api.multi def delete_template(self): res = self[0].template_id.delete_database() return res
class database_type(models.Model): _name = 'infrastructure.database_type' _description = 'database_type' _order = 'sequence' sequence = fields.Integer( 'Sequence', default=10, ) name = fields.Char(string='Name', required=True) description = fields.Text(string='Description', ) backups_enable = fields.Boolean('Backups Enable?', ) check_database = fields.Boolean( 'Check Databse with cron', help="Suggest Check Databases Automatically. Suggested for instances " "that restart automatically") demo_data = fields.Boolean(string='Demo Data?', help='Use demo data by default on databases?') prefix = fields.Char(string='Prefix', required=True, size=8) url_prefix = fields.Char(string='URL Prefix') service_type = fields.Selection( [ ('docker', 'Docker Restart'), # ('upstart', 'Upstart Service'), ('no_service', 'No Service') ], default='docker', required=True, ) type = fields.Selection( [('normal', 'Normal'), ('protected', 'Protected'), ('auto_deactivation', 'Auto Deactivation'), ('auto_drop', 'Auto Drop'), ('auto_deact_and_drop', 'Auto Deactivation and Drop')], 'Type', help="Depending on the type:\ * Normal: nothing special is made\ * Protected: needs special confirmation before some operations\ * Auto Deactivation: automatically deactivated on deactivation date\ * Auto Drop: automatically dropped on deactivation date\ * Auto Deactivation and Drop: automatically deactivated on\ deactivation date and automatically dropped on deactivation date\ ", required=True, default='normal') sources_type = fields.Selection( [('own', 'Own'), ('clone_from', 'Clone From'), ('use_from', 'Use From')], 'Sources Type', required=True, default='own', help='* own: sources are cloned from host (git, bitbucet, etc)\n' '* clone_from: sources are cloned from another instance' '* use_from: sources are used from another instance') sources_from_id = fields.Many2one( 'infrastructure.database_type', string='Sources From', ) color = fields.Integer(string='Color') auto_drop_days = fields.Integer(string='Automatic Drop Days') protect_db = fields.Boolean(string='Protect Databases?') auto_deactivation_days = fields.Integer( string='Automatic Deactivation Days') install_lang_id = fields.Selection( tools.scan_languages(), string='Install Language', ) instance_admin_pass = fields.Char( 'Instance Admin Password', help='It will be used on OWN SERVERS as default on Instance Admin\ Password, if not value defined instance name will be suggested', ) db_admin_pass = fields.Char( 'DB Admin Password', # esta si la usamos siempre porque total va encriptada help='It will be used as default on Database Admin Password,\ if not value defined instance name will be suggested', ) db_filter = fields.Many2one( 'infrastructure.db_filter', string='DB Filter', help='It will be used as default on Instances', ) workers = fields.Selection( [('clasic_rule', 'Clasic Rule'), ('fix_number', 'Fix Number')], string='Workers Filter', required=True, default='clasic_rule', help='Clasic Rule means workers = server_processors * 2 + 1') workers_number = fields.Integer('Workers Number', ) server_mode_value = fields.Char('Server Mode Value', ) instance_log_level = fields.Selection( [(u'info', 'info'), (u'debug_rpc', 'debug_rpc'), (u'warn', 'warn'), (u'test', 'test'), (u'critical', 'critical'), (u'debug_sql', 'debug_sql'), (u'error', 'error'), (u'debug', 'debug'), (u'debug_rpc_answer', 'debug_rpc_answer')], string='Default Instance Log Level', default='info', required=True, ) @api.multi def show_instance_admin_pass(self): raise Warning(_("Password: '******'") % self.instance_admin_pass) @api.multi def show_db_admin_pass(self): raise Warning(_("Password: '******'") % self.db_admin_pass) @api.onchange('service_type') def change_service_type(self): if self.service_type != 'no_service': self.check_database = True else: self.check_database = False