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' 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( 'mail.template', default=lambda self: self.env.ref( 'saas_portal.email_template_create_saas')) @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 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(), '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) 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) client.period_initial = trial and self.expiration trial_expiration_datetime = ( fields.Datetime.from_string(client.create_date) + timedelta(hours=client.period_initial) ).strftime(DEFAULT_SERVER_DATETIME_FORMAT) initial_expiration_datetime = ( fields.Datetime.from_string(client.create_date) + timedelta( self.grace_period)).strftime(DEFAULT_SERVER_DATETIME_FORMAT) state = { 'd': client.name, 'public_url': client.public_url, 'e': trial and trial_expiration_datetime or initial_expiration_datetime, '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 if there is mail template record template = self.on_create_email_template if template: client.message_post_with_template(template.id, composition_mode='comment') client.write({ 'expiration_datetime': trial and trial_expiration_datetime or initial_expiration_datetime }) 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 }
def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=True, trial=False, support_team_id=None, async_=None): self.ensure_one() p_client = self.env['saas_portal.client'] p_server = self.env['saas_portal.server'] server = self.server_id if not server: server = p_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 = p_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 = p_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 = p_client.search( [('client_id', '=', client_id)]) vals = self._new_database_vals(vals) if client: client.write(vals) else: client = p_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', 'h': client.host, '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 if there is mail template record template = self.on_create_email_template if template and notify_user: # we have to have a user in this place (how to user without a user?) user = self.env['res.users'].browse(user_id) client.with_context(user=user).message_post_with_template( template.id, 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}
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)])
class saas_portal_plan(models.Model): _inherit = 'saas_portal.plan' @api.multi # @api.constrains('installed_module_ids', 'plan_type') def _module_ids(self): # Check the module list in plan. # Raise warning if there is no product added in package. # Raise warning if you add more than 1 trial record per plan for rec in self: if not rec.installed_module_ids: raise Warning(_('Please add product in package')) trial_plan_rec = rec.search_count([('plan_type', '=', 'trial'), ('server_id', '=', rec.server_id.id)]) if rec.plan_type == 'trial': if trial_plan_rec > 1: raise Warning(_('You Cannot Add More then 1 Trial Plan ' 'Record')) @api.model def _get_buy_route(self): # Adding some required module in Installed Module list. mod_ids = self.env['ir.module.module'].search( [('name', 'in', ['hr', 'saas_custom_mail_config','sale', 'mint_client_product_catelog', 'client_sync_category'])]) if mod_ids: return mod_ids.ids return [] active = fields.Boolean('Active', default=True) plan_features_ids = fields.One2many('plan.features.master', 'plan_id', string='Plan Features', help="""Add your Features of the plan related to server and define what features will be available in this plan.""") plan_subscription_ids = fields.One2many('bista.plan.subscription', 'subscription_id', string='Plan Subscription', required = True, ) plan_description_ids = fields.One2many('plan.description', 'plan_description_id', string='Plan Description') plan_price = fields.Float( compute='_compute_plan_cost', readonly=True, string='Plan Price', store=True, digits=dp.get_precision('Product Price'), help="Total Cost for the plan calculated from all the service products") sub_period = fields.Selection( [('monthly', 'Month(s)'), ('yearly', 'Year(s)')], default = 'monthly', string = 'Subscription', required = True, help = "Specify Interval for automatic invoice generation.") recurring_rule_type = fields.Selection( [('monthly', 'Month(s)'), ('yearly', 'Year(s)')], default='monthly', string='Recurrency', help="Specify Interval for automatic invoice generation.") plan_type = fields.Selection( [('subscription', 'Subscription'), ('trial', 'Trial')], string='Plan Type', default= 'subscription', required = True) required_module_ids = fields.Many2many('ir.module.module', 'req_mod_rel', 'req_module_id', 'plan_id', string='Installed Module', default= lambda self: self._get_buy_route()) installed_module_ids = fields.Many2many('ir.module.module', 'ext_mod_rel', 'ext_module_id', 'plan_id', string='Extra Module') expiration = fields.Integer('Expiration (hours)', default = 730, help = 'time to delete database. Use for demo') button_text = fields.Selection( [('select_plan', 'Select Plan'), ('select_free_trial', 'Select Free Trial')], default='select_plan', string='WP Button Text', help="Specify what text you want to show belw the feature list to " "customer as per plan type (free or paid).") # This function will change the expiration hours based on the # subscription period selection @api.onchange('sub_period') def _onchange_sub_period(self) : # if self.sub_period == 'monthly' : self.expiration = 730 if self.sub_period == 'yearly' : self.expiration = 730 * 12 # This method will integrate all the master list define in the # server into the plan feature list where it will create new record # related to individual plan. @api.multi def update_plan_feature_master(self) : if self.server_id : feature_list = [] for rec in self.plan_features_ids: if rec: rec.unlink() if self.server_id.feature_ids: for features in self.server_id.feature_ids : feature_child_list = [] for featuer_list_id in features.feature_list_ids : feature_child_list.append((0, 0, {'name' : featuer_list_id.name, 'pfeature_list_id' : featuer_list_id.id })) feature_list.append((0, 0, { 'name' : features.name, 'pfeature_master_id' : features.id, 'feature_list_ids' : feature_child_list, })) self.plan_features_ids = feature_list return True @api.multi def create_template(self, addons=None): # Inherite method for updating Installed Module list on creation of # plan. mod_lst = [] if self.required_module_ids: for module_name in self.required_module_ids: mod_lst.append(module_name.name) if self.installed_module_ids: for ins_name in self.installed_module_ids: mod_lst.append(ins_name.name) addons = mod_lst return super(saas_portal_plan, self).create_template(addons=addons) @api.multi def _create_new_database(self, dbname=None, client_id=None, partner_id=None, user_id=None, notify_user=True, trial=False, support_team_id=None, async=None): # Inherit method for setting company data to the register user'd # company in client instance. 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}) if trial: client_expiration = self._get_expiration(trial) else: client_expiration = self._get_expiration(trial=True) 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', 'h': client.host, '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) if self._context.get('active_model') == 'saas_portal.plan': if data and data.get('state'): new_db_name = ast.literal_eval(data.get('state')) f_name = new_db_name.get('d') new_cr = db_connect(str(f_name)).cursor() new_env = Environment(new_cr, SUPERUSER_ID, {}) new_comp = new_env['res.company'].search([], limit=1) new_user_company_vals = { 'logo': '', 'name': client.name, 'rml_header1': client.name, 'website': 'http://yourcomapny.com', 'phone': '', 'email': '*****@*****.**', } new_comp.write(new_user_company_vals) new_cr.commit() 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 if there is mail template record template = self.on_create_email_template if template and notify_user: # we have to have a user in this place(how to user without a user?) user = self.env['res.users'].browse(user_id) client.with_context(user=user).message_post_with_template( template.id, 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}