diff --git a/addons/iap/models/iap_account.py b/addons/iap/models/iap_account.py index a214bf3370f..739d4230635 100644 --- a/addons/iap/models/iap_account.py +++ b/addons/iap/models/iap_account.py @@ -8,6 +8,7 @@ import werkzeug.urls from odoo import api, fields, models from odoo.addons.iap.tools import iap_tools +from odoo.exceptions import AccessError _logger = logging.getLogger(__name__) @@ -19,9 +20,96 @@ class IapAccount(models.Model): _rec_name = 'service_name' _description = 'IAP Account' - service_name = fields.Char() - account_token = fields.Char(default=lambda s: uuid.uuid4().hex) + name = fields.Char() + service_name = fields.Char(readonly=True) + account_token = fields.Char( + default=lambda s: uuid.uuid4().hex, + help="Account token is your authentication key for this service. Do not share it.", + size=43) company_ids = fields.Many2many('res.company') + account_info_id = fields.Many2one( + 'iap.account.info', compute='_compute_info', inverse='_inverse_info', search='_search_info') + account_info_ids = fields.One2many( + 'iap.account.info', 'account_id', + invisible=True, string="Accounts from IAP") + balance = fields.Char(compute='_compute_balance') + description = fields.Char(related='account_info_id.description') + warn_me = fields.Boolean( + related='account_info_id.warn_me', + help="We will send you an email when your balance gets below that threshold", + readonly=False) + warning_threshold = fields.Float(related='account_info_id.warning_threshold', readonly=False) + warning_email = fields.Char(related='account_info_id.warning_email', readonly=False) + show_token = fields.Boolean() + + @api.model + def get_view(self, view_id=None, view_type='form', **kwargs): + res = super().get_view(view_id, view_type, **kwargs) + if view_type == 'tree': + self.env['iap.account'].get_services() + return res + + @api.depends('account_info_ids') + def _compute_info(self): + for account in self: + if account.account_info_ids: + account.account_info_id = account.account_info_ids[-1] + + @api.depends('account_info_id') + def _compute_balance(self): + for account in self: + account.balance = f'{account.account_info_id.balance} {account.account_info_id.unit_name}' if account.account_info_id else "0 Credits" + + def _inverse_info(self): + for account in self: + if account.account_info_ids: + # delete previous reference + account_info = account.env['iap.account.info'].browse(account.account_info_ids[0].id) + account_info.account_id = False + # set new reference + account.account_info_id.account_id = account + + def _search_info(self, operator, value): + return [] + + def write(self, values): + res = super(IapAccount, self).write(values) + iap_edits = ['warn_me', 'warning_threshold', 'warning_email'] + if any(edited_attribute in values for edited_attribute in iap_edits): + try: + route = '/iap/update-warning-odoo' + endpoint = iap_tools.iap_get_endpoint(self.env) + url = endpoint + route + data = { + 'account_token': self.mapped('account_token')[0], + 'dbuuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'), + 'warn_me': values.get('warn_me'), + 'warning_threshold': values.get('warning_threshold'), + 'warning_email': values.get('warning_email'), + } + iap_tools.iap_jsonrpc(url=url, params=data) + except AccessError as e: + _logger.warning('Save service error : %s', str(e)) + return res + + def get_services(self): + try: + route = '/iap/services-token' + endpoint = iap_tools.iap_get_endpoint(self.env) + url = endpoint + route + account_tokens = self.env['iap.account'].sudo().search([]).mapped('account_token') + params = { + 'dbuuid': self.env['ir.config_parameter'].sudo().get_param('database.uuid'), + 'iap_accounts': account_tokens, + } + services = iap_tools.iap_jsonrpc(url=url, params=params) + for service in services: + account_id = self.env['iap.account'].sudo().search( + [('account_token', '=', service['account_token'])]).ids[0] + service['account_id'] = account_id + self.env['iap.account.info'].create(service) + except AccessError as e: + _logger.warning('Get services error : %s', str(e)) @api.model def get(self, service_name, force_create=True): @@ -74,14 +162,15 @@ class IapAccount(models.Model): return accounts[0] @api.model - def get_credits_url(self, service_name, base_url='', credit=0, trial=False): + def get_credits_url(self, service_name, base_url='', credit=0, trial=False, account_token=False): """ Called notably by ajax crash manager, buy more widget, partner_autocomplete, sanilmail. """ dbuuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid') if not base_url: endpoint = iap_tools.iap_get_endpoint(self.env) route = '/iap/1/credit' base_url = endpoint + route - account_token = self.get(service_name).account_token + if not account_token: + account_token = self.get(service_name).account_token d = { 'dbuuid': dbuuid, 'service_name': service_name, @@ -92,6 +181,19 @@ class IapAccount(models.Model): d.update({'trial': trial}) return '%s?%s' % (base_url, werkzeug.urls.url_encode(d)) + def action_buy_credits(self): + for account in self: + return { + 'type': 'ir.actions.act_url', + 'url': self.env['iap.account'].get_credits_url( + account_token=account.account_token, + service_name=account.service_name, + ), + } + + def action_toggle_show_token(self): + for account in self: + account.show_token = not account.show_token @api.model def get_account_url(self): """ Called only by res settings """ @@ -130,8 +232,25 @@ class IapAccount(models.Model): } try: credit = iap_tools.iap_jsonrpc(url=url, params=params) - except Exception as e: + except AccessError as e: _logger.info('Get credit error : %s', str(e)) credit = -1 return credit + + +class IAPAccountInfo(models.TransientModel): + _name = 'iap.account.info' + _description = 'IAP Account Info' + _transient_max_hours = 1 + + account_id = fields.Many2one('iap.account', string='IAP Account') + account_token = fields.Char() + balance = fields.Float(string='Balance', digits=(16, 4), default=0) + account_uuid_hashed = fields.Char(string='Account UUID', invisible=True) + service_name = fields.Char(string='Related Service') + description = fields.Char() + warn_me = fields.Boolean('Warn me', default=False) + warning_threshold = fields.Float('Threshold') + warning_email = fields.Char() + unit_name = fields.Char(default='Credits') diff --git a/addons/iap/security/ir.model.access.csv b/addons/iap/security/ir.model.access.csv index 80fd4e2212f..fa02197e407 100644 --- a/addons/iap/security/ir.model.access.csv +++ b/addons/iap/security/ir.model.access.csv @@ -1,3 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_client_iap_account_manager,iap.account.manager,model_iap_account,base.group_system,1,1,1,1 access_client_iap_account_user,iap.account.user,model_iap_account,base.group_user,1,0,1,0 +access_iap_account_info,access_iap_account_info,iap.model_iap_account_info,base.group_user,1,1,1,1 diff --git a/addons/iap/views/iap_views.xml b/addons/iap/views/iap_views.xml index 129a2f0c296..1a85c07adeb 100644 --- a/addons/iap/views/iap_views.xml +++ b/addons/iap/views/iap_views.xml @@ -9,9 +9,51 @@
- - - + + + + + + + + + +