forked from Mapan/odoo17e
107 lines
6.0 KiB
Python
107 lines
6.0 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
from odoo import models, fields, _, api
|
|
from odoo.exceptions import UserError
|
|
import uuid
|
|
from random import choice
|
|
|
|
|
|
class PosConfig(models.Model):
|
|
_inherit = 'pos.config'
|
|
# Due to the new broken changes of the Fiskaly API, only the v2 of the api is compliant. This version introduced two new fields that cannot be
|
|
# added in stable. Therefore the `l10n_de_fiskaly_tss_id` will be composed of `tss_id|tss_puk|tss_pin`
|
|
l10n_de_fiskaly_tss_id = fields.Char(string="TSS ID", readonly=True, copy=False, help="The TSS ID at Fiskaly side linked to the pos.config. "
|
|
"Due to some new broken changes, this field also includes the tss puk and pin separated by `|`")
|
|
l10n_de_fiskaly_client_id = fields.Char(string="Client ID", readonly=True, copy=False,
|
|
help="The Client ID refers to the client at Fiskaly which is mapped to a pos.config.")
|
|
l10n_de_create_tss_flag = fields.Boolean(string="Create TSS", help="This allows to send a request to Fiskaly in order to create and link a TSS to the pos.config")
|
|
is_company_country_germany = fields.Boolean(string="Company located in Germany", related='company_id.is_country_germany')
|
|
|
|
def _l10n_de_check_fiskaly_api_key_secret(self):
|
|
if not self.company_id.sudo().l10n_de_fiskaly_api_key or not self.company_id.sudo().l10n_de_fiskaly_api_secret:
|
|
raise UserError(_("You have to set your Fiskaly key and secret in your company settings."))
|
|
|
|
def _l10n_de_check_fiskaly_tss_client_ids(self):
|
|
if not self.l10n_de_fiskaly_tss_id or not self.l10n_de_fiskaly_client_id:
|
|
raise UserError(_("You have to set your Fiskaly TSS ID and Client ID in your PoS settings."))
|
|
|
|
def _l10n_de_get_tss_id(self):
|
|
return self.l10n_de_fiskaly_tss_id.split('|')[0]
|
|
|
|
def open_ui(self):
|
|
if not self.company_id.country_id:
|
|
raise UserError(_("You have to set a country in your company setting."))
|
|
if self.company_id.l10n_de_is_germany_and_fiskaly():
|
|
self._l10n_de_check_fiskaly_api_key_secret()
|
|
self._l10n_de_check_fiskaly_tss_client_ids()
|
|
return super().open_ui()
|
|
|
|
@api.model
|
|
def l10n_de_get_fiskaly_urls_and_keys(self, config_id):
|
|
self.check_access_rights('read')
|
|
company = self.browse(config_id).company_id.sudo()
|
|
return {
|
|
'kassensichv_url': self.env['res.company']._l10n_de_fiskaly_kassensichv_url(),
|
|
'dsfinvk_url': self.env['res.company']._l10n_de_fiskaly_dsfinvk_api_url(),
|
|
'api_key': company.l10n_de_fiskaly_api_key,
|
|
'api_secret': company.l10n_de_fiskaly_api_secret
|
|
}
|
|
|
|
@api.model_create_multi
|
|
def create(self, vals_list):
|
|
pos_configs = super().create(vals_list)
|
|
for pos_config in pos_configs:
|
|
if pos_config.l10n_de_create_tss_flag:
|
|
pos_config._l10n_de_create_tss_process()
|
|
return pos_configs
|
|
|
|
def write(self, values):
|
|
res = super().write(values)
|
|
for config in self:
|
|
if values.get('l10n_de_create_tss_flag') and not config.l10n_de_fiskaly_tss_id:
|
|
config._l10n_de_create_tss_process()
|
|
return res
|
|
|
|
def unlink(self):
|
|
# Those values are needed when disabling a TSS at Fiskaly, we store them before deleting the configs
|
|
tss_to_disable_data = [(config.company_id, config.l10n_de_fiskaly_tss_id)
|
|
for config in self if config.l10n_de_create_tss_flag]
|
|
res = super().unlink()
|
|
|
|
# We want to first delete them in Odoo in case there's an issue and since we can't rollback with Fiskaly
|
|
|
|
for tss_data in tss_to_disable_data:
|
|
pos_config, tss_id_admin_puk_pin = tss_data
|
|
tss_id = tss_id_admin_puk_pin.split('|')[0]
|
|
# We differentiate if the TSS was created under the v2 or v1 api
|
|
if '|' in tss_id_admin_puk_pin:
|
|
admin_pin = tss_id_admin_puk_pin.split('|')[2]
|
|
pos_config._l10n_de_fiskaly_kassensichv_rpc('POST', '/tss/%s/admin/auth' % tss_id, {'admin_pin': admin_pin})
|
|
pos_config._l10n_de_fiskaly_kassensichv_rpc('PATCH', '/tss/%s' % tss_id, {'state': 'DISABLED'})
|
|
else:
|
|
pos_config._l10n_de_fiskaly_kassensichv_rpc('PUT', '/tss/%s' % tss_id, {'state': 'DISABLED'}, version=1)
|
|
|
|
return res
|
|
|
|
def _l10n_de_create_tss_process(self):
|
|
tss_id = str(uuid.uuid4())
|
|
local_tss = self.search([('company_id', '=', self.company_id.id), ('l10n_de_fiskaly_tss_id', '!=', False)])
|
|
db_uuid = self.env['ir.config_parameter'].sudo().get_param('database.uuid')
|
|
self.company_id._l10n_de_fiskaly_iap_rpc('/tss', {'tss_id': tss_id, 'db_uuid': db_uuid, 'tss': len(local_tss)})
|
|
|
|
tss_creation_resp = self.company_id._l10n_de_fiskaly_kassensichv_rpc('PUT', '/tss/%s' % tss_id, {}) # Yes, Fiskaly is asking for a empty object...
|
|
tss_puk = tss_creation_resp.json()['admin_puk']
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('PATCH', '/tss/%s' % tss_id, {'state': 'UNINITIALIZED'})
|
|
tss_pin = ''.join(choice('0123456789') for _ in range(6))
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('PATCH', '/tss/%s/admin' % tss_id,
|
|
{'admin_puk': tss_puk, 'new_admin_pin': tss_pin})
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('POST', '/tss/%s/admin/auth' % tss_id, {'admin_pin': tss_pin})
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('PATCH', '/tss/%s' % tss_id, {'state': 'INITIALIZED'})
|
|
|
|
# Client
|
|
client_id = str(uuid.uuid4())
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('PUT', '/tss/%s/client/%s' % (tss_id, client_id), {'serial_number': self.uuid})
|
|
self.company_id._l10n_de_fiskaly_kassensichv_rpc('POST', '/tss/%s/admin/logout' % tss_id, {'admin_pin': tss_pin})
|
|
|
|
self.write({'l10n_de_fiskaly_tss_id': '|'.join([tss_id, tss_puk, tss_pin]), 'l10n_de_fiskaly_client_id': client_id})
|