示例#1
0
class HrEmployeeLanguage(models.Model):
    _name = 'hr.employee.language'
    _description = 'HR Employee Language'

    name = fields.Selection(
        tools.scan_languages(),
        string="Language",
        required=True,
    )
    description = fields.Char(size=64, )
    employee_id = fields.Many2one(
        'hr.employee',
        string="Employee",
        required=True,
    )
    can_read = fields.Boolean(
        string="Read",
        default=True,
    )
    can_write = fields.Boolean(
        string="Write",
        default=True,
    )
    can_speak = fields.Boolean(
        string="Speak",
        default=True,
    )
    can_listen = fields.Boolean(
        string="Listen",
        default=True,
    )
示例#2
0
class HrLanguage(models.Model):
    _name = 'hr.language'

    name = fields.Selection(
        tools.scan_languages(),
        "Language",
        required=True,
    )
    description = fields.Char(
        "Description",
        size=64,
        required=True,
    )
    employee_id = fields.Many2one(
        'hr.employee',
        "Employee",
        required=True,
    )
    can_read = fields.Boolean(
        "Read",
        default=True,
        oldname='read',
    )
    can_write = fields.Boolean(
        "Write",
        default=True,
        oldname='write',
    )
    can_speak = fields.Boolean(
        "Speak",
        default=True,
        oldname='speak',
    )
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):
示例#4
0
class ProductAttributeValueSaaS(models.Model):
    _inherit = "product.attribute.value"

    def _get_default_lang(self):
        return self.env.user.lang

    saas_lang = fields.Selection(scan_languages(), 'Language', default=_get_default_lang)
    template_ids = fields.Many2many('saas_portal.database', 'product_attribute_value_saas_templates', 'value_id', 'template_id', string='SaaS Templates')
示例#5
0
class PartnerLanguange(models.Model):
    _name = "partner.language"
    _description = "Contact Language Proficiency"

    name = fields.Selection(
        selection=tools.scan_languages(), string="Language", required=True
    )
    description = fields.Char(string="Description", size=64, required=False)
    partner_id = fields.Many2one(
        comodel_name="res.partner", string="Partner", required=True
    )
    read_rating = fields.Selection(
        string="Reading",
        selection=LANGUAGE_RATING,
        required=True,
        default="0",
    )
    write_rating = fields.Selection(
        string="Writing",
        selection=LANGUAGE_RATING,
        required=True,
        default="0",
    )
    speak_rating = fields.Selection(
        string="Speaking",
        selection=LANGUAGE_RATING,
        required=True,
        default="0",
    )
    listen_rating = fields.Selection(
        string="Listening",
        selection=LANGUAGE_RATING,
        required=True,
        default="0",
    )

    @api.constrains(
        "partner_id",
        "name",
    )
    def _check_no_duplicate_language(self):
        obj_language = self.env["partner.language"]
        for language in self:
            criteria = [
                ("id", "!=", language.id),
                ("partner_id", "=", language.partner_id.id),
                ("name", "=", language.name),
            ]
            result = obj_language.search_count(criteria)
            if result > 0:
                msg = _("No duplicate language")
                raise UserError(msg)
class SaasPortalAddExistingDatabase(models.TransientModel):
    """
    Model to add an existing template db
    """
    _name = 'saas_portal.add_existing_template'

    @api.model
    def _get_default_name_txt(self):
        return "%s %s" % (self.subdomain or '', self.db_primary_lang or '')

    subdomain = fields.Char(string='Subdomain', required=False)
    name_txt = fields.Char('Name',
                           required=True,
                           default=_get_default_name_txt)
    server_id = fields.Many2one('saas_portal.server',
                                string='Server',
                                required=True)
    domain = fields.Char(related='server_id.name',
                         string='Server Domain',
                         readonly=True)
    db_primary_lang = fields.Selection(scan_languages(),
                                       'Database primary language')
    plan_id = fields.Many2one('saas_portal.plan', string='Add To Plan')
    password = fields.Char(required=True)

    @api.multi
    def add(self):
        new_db = self.subdomain + '.' + self.server_id.domain
        saas_portal_database = self.env['saas_portal.database']
        if saas_portal_database.search([('name', '=', new_db)]):
            raise ValidationError(
                _("This database already exists: "
                  "'%s'") % new_db)
        vals = {
            'subdomain': self.subdomain,
            'name_txt': self.name_txt,
            'server_id': self.server_id.id,
            'state': 'template',
            'db_type': 'template',
            'db_primary_lang': self.db_primary_lang,
            'password': self.password,
        }
        if self.plan_id:
            vals.update(plan_ids=[(4, self.plan_id.id)])

        new_template = saas_portal_database.create(vals)
        if self.plan_id and not self.plan_id.template_id:
            self.plan_id.template_id = new_template.id

        return {'type': 'ir.actions.act_window_close'}
示例#7
0
class hr_language(models.Model):
    _name = 'hr.language'
    _inherit = ['mail.thread']

    name = fields.Selection(
        tools.scan_languages(),
        string='Language',
        required=True,
    )
    employee_id = fields.Many2one('hr.employee',
                                  string='Employee',
                                  required=True)
    can_read = fields.Selection(AVAILABLE_PRIORITIES, 'Read')
    can_write = fields.Selection(AVAILABLE_PRIORITIES, 'Write')
    can_speak = fields.Selection(AVAILABLE_PRIORITIES, 'Speak')
    date = fields.Date('Update date')
    note = fields.Text('Commentaires', translate=True)
示例#8
0
class SaasClient(models.AbstractModel):
    """
    This model is used or inherited by modules as:  saas_portal.client and saas_server.client
    """
    _name = 'saas_base.client'
    _description = 'SaaS client instances base data'

    users_len = fields.Integer('Count users',
                               readonly=True,
                               help='Actual created internal users')
    max_users = fields.Char('Max users allowed',
                            readonly=True,
                            help='Overall internal user limit')
    file_storage = fields.Integer('File storage (MB)',
                                  readonly=True,
                                  help='Used file storage')
    db_storage = fields.Integer('DB storage (MB)',
                                readonly=True,
                                help='Used database storage')
    total_storage_limit = fields.Integer('Total storage limit (MB)',
                                         readonly=True,
                                         default=0,
                                         help='Overall storage limit')
    # Following fields where in saas_portal.client before
    total_storage = fields.Integer('Used storage (MB)',
                                   compute='_get_storage_client_sum',
                                   help='from Client')
    trial = fields.Boolean('Trial',
                           help='indication of trial clients',
                           default=False,
                           readonly=True)
    client_primary_lang = fields.Selection(scan_languages(),
                                           'Primary language',
                                           readonly=False)
    expiration_datetime = fields.Datetime(string="Expiration")
    expired = fields.Boolean('Expired')

    @api.multi
    #  @api.depends('state')
    def _get_storage_client_sum(self):
        for record in self:
            record.total_storage = record.file_storage + record.db_storage
示例#9
0
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
        }
示例#10
0
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'),
        ('email', 'Go to information page that says to check email for credentials')
    ], string="Workflow on create", default='email')
    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, owner_user, owner_password):
        """
        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_data = {
            'user_id': owner_user.id,
            'login': owner_user.login,
            'password': owner_password,
            'name': owner_user.name,
            'email': owner_user.email,
        }
        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, owner_password=None):
class SaasDuplicateTemplateWizard(models.TransientModel):
    _name = 'saas_portal.duplicate_template.wizard'
    _description = 'SaaS Portal Duplicate Template Wizard'

    @api.model
    def _get_template_id(self):
        return self._context.get('active_id', False)

    template_id = fields.Many2one(comodel_name="saas_portal.database",
                                  string="Template",
                                  required=True,
                                  ondelete="cascade",
                                  default=_get_template_id,
                                  auto_join=True)
    template_domain = fields.Char(related='template_id.domain',
                                  store=True,
                                  string='Domain',
                                  readonly=True)
    new_name = fields.Char(string="New subdomain name")
    lang = fields.Selection(scan_languages(), 'Language')

    @api.multi
    def registry(self, new=False, **kwargs):
        self.ensure_one()
        m = odoo.modules.registry.Registry
        return m.new(self.new_name + '.' + self.template_id.domain, **kwargs)

    @api.multi
    def duplicate_template(self):
        new_db = self.new_name + '.' + self.template_id.domain
        if self.template_id:
            saas_portal_database = self.env['saas_portal.database']
            if saas_portal_database.search([('name', '=', new_db)]):
                raise ValidationError(
                    _("This database already exists: "
                      "'%s'") % new_db)
            db._drop_conn(self.env.cr, self.template_id.name)
            db.exp_duplicate_database(self.template_id.name, new_db)
            new_template = saas_portal_database.create({
                'subdomain':
                self.new_name,
                'server_id':
                self.template_id.server_id.id,
                'db_primary_lang':
                self.lang,
                'state':
                'template',
                'db_type':
                'template'
            })
            if self.lang:
                with self.registry().cursor() as cr:
                    env = api.Environment(cr, SUPERUSER_ID, self._context)
                    # load a new language:
                    load_language(env.cr, self.lang)
                    # set this language for all partner records:
                    for partner in env['res.partner'].search([]):
                        partner.lang = self.lang
                    # if website is installed, also load the language
                    if env['ir.module.module'].search([
                        ('name', '=', 'website')
                    ]).state in ('installed', 'to upgrade'):
                        website = env["website"].get_current_website()
                        wiz = env["base.language.install"].create(
                            {"lang": self.lang})
                        wiz.website_ids = website
                        wiz.lang_install()
                        res_lang_id = env['res.lang'].search([('code', '=',
                                                               self.lang)])
                        if res_lang_id:
                            # make it a default website language
                            website.default_lang_id = res_lang_id

            action = self.env.ref('saas_portal.action_templates').read()[0]
            if action:
                action['views'] = [
                    (self.env.ref('saas_portal.view_databases_form').id,
                     'form')
                ]
                action['res_id'] = new_template.ids[0]
            else:
                action = {'type': 'ir.actions.act_window_close'}
            return action
示例#12
0
 def _get_lang(self):
     return tools.scan_languages()
示例#13
0
class SaasPortalDatabase(models.Model):
    # gets inherited by saas_portal.client
    _name = 'saas_portal.database'
    _description = 'Saas database instances'
    _inherits = {'oauth.application': 'oauth_application_id'}
    _order = 'identifier'

    @api.model
    def _get_default_name_txt(self):
        return "%s %s" % (self.name or '', self.db_primary_lang or '')

    @api.multi
    @api.depends('subdomain', 'domain')
    def _compute_db_name(self):
        for record in self:
            subdomain = record.subdomain
            domain = record.domain
            record.name = "%s.%s" % (subdomain, domain)

    name = fields.Char('Database name', compute='_compute_db_name', store=True)
    name_txt = fields.Char('Name',
                           required=True,
                           default=_get_default_name_txt)
    identifier = fields.Char('Identifier',
                             readonly=True,
                             default=lambda self: _('New'))
    summary = fields.Char('Summary',
                          compute='_get_compose_summary',
                          store=True)
    oauth_application_id = fields.Many2one('oauth.application',
                                           'OAuth Application',
                                           required=True,
                                           ondelete='cascade')
    # Todo needs to be readonly = False for now to work, should be taken from client form.
    server_id = fields.Many2one('saas_portal.server',
                                ondelete='restrict',
                                string='Server',
                                readonly=False,
                                required=True)
    server_db_name = fields.Char(related='server_id.name',
                                 string='Server Database name',
                                 readonly=True)
    subdomain = fields.Char('Sub Domain', required=True)
    domain = fields.Char(related='server_id.name',
                         string='Server Domain',
                         readonly=True)
    server_type = fields.Selection(related='server_id.server_type',
                                   string='SaaS Server Type',
                                   readonly=True)
    product_type = fields.Selection(
        related='server_id.branch_product_type',
        string='Product type',
        readonly=True,
        help='Which product the SaaS Server is hosting')
    odoo_version = fields.Selection(related='server_id.odoo_version',
                                    string='Odoo version',
                                    readonly=True,
                                    help='Which Odoo version is hosted')
    state = fields.Selection([
        ('draft', 'New'),
        ('open', 'Running'),
        ('open_err', 'Running with Error'),
        ('open_failed', 'Running Failed'),
        ('cancelled', 'Cancelled'),
        ('pending', 'Pending'),
        ('deleted', 'Deleted'),
        ('template', 'Template'),
    ],
                             'State',
                             default='draft',
                             track_visibility='onchange')
    db_type = fields.Selection([
        ('client', 'Client'),
        ('template', 'Template'),
        ('other', 'Other'),
    ],
                               'DB Type',
                               default='client',
                               track_visibility='onchange')

    host = fields.Char(related='server_id.name', string='Host', readonly=True)
    db_primary_lang = fields.Selection(scan_languages(),
                                       'Database primary language')
    public_url = fields.Char(compute='_compute_public_url')
    # Todo use of password is not yet clear?
    password = fields.Char('Default Database Password')
    plan_ids = fields.Many2many('saas_portal.plan',
                                'saas_portal_database_templates',
                                'template_id',
                                'plan_id',
                                string='SaaS Plans')

    _sql_constraints = [('name_unique', 'unique(name)',
                         'Database name already exists.')]

    @api.multi
    def name_get(self):
        res = []
        for record in self:
            if record.db_primary_lang:
                res.append((record.id,
                            '%s [%s]' % (record.name, record.db_primary_lang)))
            else:
                res.append((record.id, record.name))
        return res

    @api.multi
    def _get_compose_summary(self):
        for record in self:
            subdomain = record.subdomain or ''
            lang = record.db_primary_lang or ''
            summary = "Template %s, %s" % (subdomain, lang)
            record.summary = summary

    @api.model
    def create(self, vals):
        if vals.get('identifier', _('New')) == _('New'):
            vals['identifier'] = self.env['ir.sequence'].next_by_code(
                'saas_portal.database') or _('New')
        if vals.get('name') and not vals.get(
                'subdomain', False) and not vals.get('name_txt', False):
            vals['subdomain'] = vals['name']
            vals['name_txt'] = vals['name']
        return super(SaasPortalDatabase, self).create(vals)

    @api.multi
    def _compute_public_url(self):
        for record in self:
            scheme = record.server_id.request_scheme
            db_name = record.name
            port = record.server_id.request_port
            public_url = "%s://%s" % (scheme, db_name)
            if scheme == 'http' and port != 80 or scheme == 'https' and port != 443:
                public_url = public_url + ':' + str(port)
            record.public_url = public_url + '/'

    @api.multi
    def _backup(self):
        '''
        call to backup database
        '''
        self.ensure_one()

        state = {
            'd': self.name,
            'client_id': self.client_id,
        }

        req, req_kwargs = self.server_id._request_server(
            path='/saas_server/backup_database',
            state=state,
            client_id=self.client_id)
        res = requests.Session().send(req, **req_kwargs)
        _logger.info('backup database: %s', res.text)
        if not res.ok:
            raise Warning(
                _('Reason: %s \n Message: %s') % (res.reason, res.content))
        data = simplejson.loads(res.text)
        if not isinstance(data[0], dict):
            raise Warning(data)
        if data[0]['status'] != 'success':
            warning = data[0].get(
                'message',
                _('Could not backup database; please check your logs'))
            raise Warning(warning)
        return True

    @api.multi
    def action_sync_server(self):
        for record in self:
            record.server_id.action_sync_server()

    @api.multi
    def duplicate_template_button(self):
        view_id = self.env.ref(
            'saas_portal.saas_plan_duplicate_template_wizard_form')
        context = self._context.copy()
        context.update(active_id=self.id)
        return {
            'name': _('Duplicate A Template'),
            'type': 'ir.actions.act_window',
            'res_model': 'saas_portal.duplicate_template.wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'views': [(view_id.id, 'form')],
            'target': 'new',
            'context': context
        }

    @api.multi
    def delete_template(self):
        self.ensure_one()
        res = self.delete_database_server(force_delete=True)
        return res

    @api.multi
    def login_to_db(self):
        view_id = self.env.ref(
            'saas_portal.saas_plan_duplicate_template_wizard_form')
        context = self._context.copy()
        context.update(active_id=self.id)
        return {
            'name': _('Duplicate A Template'),
            'type': 'ir.actions.act_window',
            'res_model': 'saas_portal.duplicate_template.wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'views': [(view_id.id, 'form')],
            'target': 'new',
            'context': context
        }

    @api.model
    def _proceed_url(self, url):
        return {
            'type': 'ir.actions.act_url',
            'target': 'new',
            'name': 'Redirection',
            'url': url
        }

    @api.multi
    def _request_url(self, path):
        r = self[0]
        state = {
            'd': r.name,
            'host': r.host,
            'public_url': r.public_url,
            'client_id': r.client_id,
        }
        url = r.server_id._request(path=path,
                                   state=state,
                                   client_id=r.client_id)
        return url

    @api.multi
    def _request(self, path):
        url = self._request_url(path)
        return self._proceed_url(url)

    @api.multi
    def edit_database(self):
        """Obsolete. Use saas_portal.edit_database widget instead"""
        for database_obj in self:
            return database_obj._request('/saas_server/edit_database')

    @api.multi
    def delete_database(self):
        for database_obj in self:
            return database_obj._request('/saas_server/delete_database')

    @api.multi
    def upgrade(self, payload=None):
        config_obj = self.env['saas.config']
        res = []

        if payload is not None:
            # maybe use multiprocessing here
            for database_obj in self:
                res.append(
                    config_obj.do_upgrade_database(payload.copy(),
                                                   database_obj))
        return res

    @api.multi
    def delete_database_server(self, **kwargs):
        self.ensure_one()
        return self._delete_database_server(**kwargs)

    @api.multi
    def _delete_database_server(self, force_delete=False):
        for database in self:
            state = {
                'd': database.name,
                'client_id': database.client_id,
            }
            if force_delete:
                state['force_delete'] = 1
            req, req_kwargs = database.server_id._request_server(
                path='/saas_server/delete_database',
                state=state,
                client_id=database.client_id)
            res = requests.Session().send(req, **req_kwargs)
            _logger.info('delete database: %s', res.text)
            if res.status_code != 500:
                database.state = 'deleted'

    @api.multi
    def show_upgrade_wizard(self):
        obj = self[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.name
            }
        }
示例#14
0
class SaasPortalPlan(models.Model):
    _name = 'saas_portal.plan'
    _description = 'SaaS Plan (templates)'
    _order = 'sequence'

    name = fields.Char('Plan', required=True)
    summary = fields.Char('Summary')
    template_id = fields.Many2one('saas_portal.database',
                                  'DB Template',
                                  required=True,
                                  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=10)
    maximum_allowed_trial_dbs_per_partner = fields.Integer(
        help='maximum allowed trial databases per customer',
        require=True,
        default=2)

    max_users = fields.Integer('Initial Max users',
                               default='0',
                               help='leave 0 for no limit')
    max_storage = fields.Integer('Total storage limit (MB)',
                                 Default=200,
                                 help='leave 0 for no limit')
    block_on_expiration = fields.Boolean('Block clients on expiration',
                                         default=True)
    block_on_storage_exceed = fields.Boolean(
        'Block clients when they reach the storage limit', default=True)

    def _get_default_lang(self):
        return self.env.user.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='_compute_get_state',
                             store=True)
    expiration = fields.Integer('Expiration (hours)',
                                default=48,
                                help='time to delete database. Use for trial')
    grace_period = fields.Integer('Grace period (days)',
                                  default=14,
                                  help='initial days before expiration')
    dbname_template = fields.Char(
        'Default DB subdomain',
        help=
        'Used for generating client database subdomain name. Use %i for numbering. '
        'Ignore if you use manually created db names',
        default='trial%i',
        placeholder='trial-crm-%i')
    branch_id = fields.Many2one('saas_portal.server_branch',
                                string='SaaS Server Branch',
                                ondelete='restrict',
                                required=True,
                                help='Use this Server Branch for this plan')
    server_id = fields.Many2one(related='branch_id.active_server',
                                String='Active Server',
                                help="Active Server for new instances")
    active_domain_name = fields.Char(related='branch_id.active_domain_name',
                                     string='Active Domain Name',
                                     help="Active Domain for new instances")
    domain = fields.Char(related='branch_id.active_server.domain',
                         string='Server Domain',
                         readonly=True)
    upgrade_path_ids = fields.Many2many('saas_portal.plan',
                                        'saas_portal_plan_upgrade_rel',
                                        'plan_id',
                                        'upgrade_plan_id',
                                        string='Potential Plans To Upgrade To')
    downgrade_path_ids = fields.Many2many(
        'saas_portal.plan',
        'saas_portal_plan_downgrade_rel',
        'plan_id',
        'downgrade_plan_id',
        string='Potential Plans To Downgrade To')
    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.multi
    @api.depends('template_id.state')
    def _compute_get_state(self):
        for plan in self:
            if plan.template_id.state == 'template':
                plan.state = 'confirmed'
            else:
                plan.state = 'draft'

    @api.multi
    def _new_database_vals(self, vals):
        self.ensure_one()
        vals['max_users'] = vals.get('max_users', self.max_users)
        # vals['total_storage_limit'] = vals.get('total_storage_limit',
        #                                       self.total_storage_limit)
        vals['block_on_expiration'] = vals.get('block_on_expiration',
                                               self.block_on_expiration)
        vals['block_on_storage_exceed'] = vals.get(
            '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=True,
                             order_id=None,
                             trial=False,
                             support_team_id=None,
                             async=None,
                             lang=None,
                             template_db=None):