From dc8f0a2e72deaf2761343c1f891870f46c8523ea Mon Sep 17 00:00:00 2001 From: Alessio Gerace Date: Thu, 14 Nov 2024 13:30:50 +0100 Subject: [PATCH] [FIX] handling tags and readers, updare access register --- .../data/ir_config_parameter_data.xml | 12 +++- .../models/ca_anag_registro_accesso.py | 42 +++++++++++++ .../models/ca_persona.py | 7 ++- .../views/ca_registro_accesso_views.xml | 23 +++++++ inrim_anagrafiche/data/ir.cron.xml | 15 ++++- inrim_anagrafiche/models/ca_persona.py | 2 +- inrim_anagrafiche/models/ca_tag_persona.py | 4 +- inrim_anagrafiche/models/ca_work_info.py | 8 +-- inrim_anagrafiche/views/ca_persona_views.xml | 2 +- .../views/ca_tag_persona_views.xml | 4 +- inrim_controllo_accessi/__manifest__.py | 2 +- .../models/ca_anag_registro_accesso.py | 5 +- .../models/ca_lettore_persona.py | 60 +++++++++++-------- .../models/ca_punto_accesso.py | 6 +- .../models/ca_tag_lettore.py | 48 +++++++++------ inrim_controllo_accessi/tests/test_inrim.py | 2 + ...views.xml => ca_lettore_persona_views.xml} | 12 ++-- .../views/ca_punto_accesso_views.xml | 20 +++++-- .../views/ca_tag_lettore_views.xml | 52 +++++++++------- inrim_controllo_accessi/views/menus.xml | 6 +- .../wizard/ca_registra_ospite.py | 2 +- .../models/ca_punto_accesso.py | 4 +- 22 files changed, 236 insertions(+), 102 deletions(-) create mode 100644 controllo_accessi_inrim_app/models/ca_anag_registro_accesso.py create mode 100644 controllo_accessi_inrim_app/views/ca_registro_accesso_views.xml rename inrim_controllo_accessi/views/{ca_punto_accesso_persona_views.xml => ca_lettore_persona_views.xml} (84%) diff --git a/controllo_accessi_inrim_app/data/ir_config_parameter_data.xml b/controllo_accessi_inrim_app/data/ir_config_parameter_data.xml index eb9146c..2e4a0b0 100755 --- a/controllo_accessi_inrim_app/data/ir_config_parameter_data.xml +++ b/controllo_accessi_inrim_app/data/ir_config_parameter_data.xml @@ -36,9 +36,15 @@ default_ca.internal_people_types ["dipendentit.d._employeetype","assegni_employeetype","dipendentit.i._employeetype","tesisti_employeetype","associazionitipoa_tipopersonale","associazionitipob_tipopersonale", - "associazionitipoc_tipopersonale", - "borse_employeetype","dottorandi_employeetype", - "stage_employeetype"] + "associazionitipoc_tipopersonale", "borse_employeetype","dottorandi_employeetype", "stage_employeetype"] + + + + + inrim_payroll_types + + ["dipendentit.d._employeetype","assegni_employeetype","dipendentit.i._employeetype"] diff --git a/controllo_accessi_inrim_app/models/ca_anag_registro_accesso.py b/controllo_accessi_inrim_app/models/ca_anag_registro_accesso.py new file mode 100644 index 0000000..fd4e383 --- /dev/null +++ b/controllo_accessi_inrim_app/models/ca_anag_registro_accesso.py @@ -0,0 +1,42 @@ +import pytz +from odoo import models, fields + +_tzs = [(tz, tz) for tz in sorted(pytz.all_timezones, + key=lambda tz: tz if not tz.startswith( + 'Etc/') else '_')] + + +def _tz_get(self): + return _tzs + + +class CaAnagRegistroAccesso(models.Model): + _inherit = 'ca.anag_registro_accesso' + + codice_lettore_grum = fields.Integer( + string='Codice Lettore GRUM', + ) + work_id_number = fiels.Char(string='ID Number') + state = fields.Selection([ + ('to_sync', 'To Sync'), + ('sync_done', 'Sync Done'), + ('sync_error', 'Sync Error'), + ], string="Sync State", readonly=True) + + def aggiungi_riga_accesso( + self, ca_punto_accesso_id, + ca_tag_persona_id, datetime_event, type='manual', access_allowed=True, + tz="" + ): + res = super().aggiungi_riga_accesso( + ca_punto_accesso_id, ca_tag_persona_id, datetime_event, type=type, + access_allowed=access_allowed, tz=tz) + todo = {} + if res and ca_punto_accesso_id.typology == 'stamping' and res.access_allowed: + todo['codice_lettore_grum'] = ca_punto_accesso_id.codice_lettore_grum + winfo = ca_tag_persona_id.ca_persona_id.get_current_winfo() + if winfo.ca_work_info_type_id.structured: + todo['work_id_number'] = winfo.work_id_number + todo['state'] = 'to_sync' + res.write(todo) + return res diff --git a/controllo_accessi_inrim_app/models/ca_persona.py b/controllo_accessi_inrim_app/models/ca_persona.py index 12647e6..a33cc40 100644 --- a/controllo_accessi_inrim_app/models/ca_persona.py +++ b/controllo_accessi_inrim_app/models/ca_persona.py @@ -54,8 +54,8 @@ def _cron_people_get_addressbook(self): def update_work_info_type(self, data): logger.info("Update tipo persona work_info_type") - ext_company = 'ditteesterne_tipopersonale' - ext_entity = 'entiesterni_tipopersonale' + payrolls = json.loads(self.env['ir.config_parameter'].sudo().get_param( + 'inrim_payroll_types')) with self.env.cr.savepoint(): try: for dt in data: @@ -67,11 +67,12 @@ def update_work_info_type(self, data): vals = { 'name': dt['name'], 'code': dt['code'], - 'structured': dt['code'] not in [ext_company, ext_entity] + 'structured': dt['code'] not in payrolls } res = self.env['ca.work_info_type'].create(vals) else: work_info_type_id.name = dt['name'] + work_info_type_id.structured = dt['code'] not in payrolls except Exception as e: logger.error(f"Error: {e}", exc_info=True) diff --git a/controllo_accessi_inrim_app/views/ca_registro_accesso_views.xml b/controllo_accessi_inrim_app/views/ca_registro_accesso_views.xml new file mode 100644 index 0000000..db24513 --- /dev/null +++ b/controllo_accessi_inrim_app/views/ca_registro_accesso_views.xml @@ -0,0 +1,23 @@ + + + + ca.registro_accesso.view.tree.inherit + ca.anag_registro_accesso + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inrim_anagrafiche/data/ir.cron.xml b/inrim_anagrafiche/data/ir.cron.xml index 8ebee09..d3f4f8f 100644 --- a/inrim_anagrafiche/data/ir.cron.xml +++ b/inrim_anagrafiche/data/ir.cron.xml @@ -16,7 +16,7 @@ - INRIM: Check Tag Validity + INRIM: Check Tag Persona Validity ir.action.server model._cron_check_validity_tag() @@ -27,5 +27,18 @@ True 5 + + + INRIM: Check Work Info Validity + + ir.action.server + model._cron_check_validity_winfo() + hours + 12 + -1 + 5 + False + True + \ No newline at end of file diff --git a/inrim_anagrafiche/models/ca_persona.py b/inrim_anagrafiche/models/ca_persona.py index db01591..c7d744a 100644 --- a/inrim_anagrafiche/models/ca_persona.py +++ b/inrim_anagrafiche/models/ca_persona.py @@ -20,7 +20,7 @@ class CaPersona(models.Model): vat = fields.Char() type_ids = fields.Many2many('ca.tipo_persona') freshman = fields.Char(groups="controllo_accessi.ca_gdpr") - work_id_number = fields.Char(string="A.C. ID Numeber", + work_id_number = fields.Char(string="A.C. ID Number", groups="controllo_accessi.ca_gdpr") nationality = fields.Many2one('res.country', groups="controllo_accessi.ca_gdpr") birth_date = fields.Date(groups="controllo_accessi.ca_gdpr") diff --git a/inrim_anagrafiche/models/ca_tag_persona.py b/inrim_anagrafiche/models/ca_tag_persona.py index 94ca88e..4a90ffc 100644 --- a/inrim_anagrafiche/models/ca_tag_persona.py +++ b/inrim_anagrafiche/models/ca_tag_persona.py @@ -108,9 +108,7 @@ def check_update_record_by_date_valididty(self): elif self.date_start > now: self.ca_tag_id.in_use = True self.state = 'scheduled' - else: - self.ca_tag_id.in_use = False - self.state = 'returned' + def check_update_by_date_valididty(self): for tag_persona in self.search([]): diff --git a/inrim_anagrafiche/models/ca_work_info.py b/inrim_anagrafiche/models/ca_work_info.py index 3a2a952..700c965 100644 --- a/inrim_anagrafiche/models/ca_work_info.py +++ b/inrim_anagrafiche/models/ca_work_info.py @@ -66,13 +66,14 @@ def rest_get_record(self): 'name': self.name, 'code': self.code, 'description': self.description, + 'structured': self.structured, } return vals def rest_eval_body(self, body): body, msg = super().rest_eval_body( body, [ - 'name', 'code' + 'name', 'code', 'structured' ]) return body, msg @@ -86,8 +87,7 @@ class CaWorkInfo(models.Model): ca_persona_id = fields.Many2one( 'ca.persona', required=True) - work_id_number = fields.Char( - string="A.C. ID Numeber", groups="controllo_accessi.ca_gdpr") + work_id_number = fields.Char(string="ID Number") ca_work_info_type_id = fields.Many2one( 'ca.work_info_type', ondelete='cascade') @@ -126,7 +126,7 @@ def check_update_state(self): self.state = 'expired' def check_update_by_date_valididty(self): - for winfo_persona in self.search([]): + for winfo_persona in self.env['ca.work_info'].search([]): if winfo_persona: winfo_persona.check_update_state() diff --git a/inrim_anagrafiche/views/ca_persona_views.xml b/inrim_anagrafiche/views/ca_persona_views.xml index 4e2aa2d..d251fa4 100755 --- a/inrim_anagrafiche/views/ca_persona_views.xml +++ b/inrim_anagrafiche/views/ca_persona_views.xml @@ -9,9 +9,9 @@ domain="[('type_ids', 'ilike', 'interno')]"/> - + diff --git a/inrim_anagrafiche/views/ca_tag_persona_views.xml b/inrim_anagrafiche/views/ca_tag_persona_views.xml index 3644e22..621630d 100644 --- a/inrim_anagrafiche/views/ca_tag_persona_views.xml +++ b/inrim_anagrafiche/views/ca_tag_persona_views.xml @@ -27,7 +27,7 @@ - + @@ -41,6 +41,8 @@ + diff --git a/inrim_controllo_accessi/__manifest__.py b/inrim_controllo_accessi/__manifest__.py index a35ef52..59f6b19 100644 --- a/inrim_controllo_accessi/__manifest__.py +++ b/inrim_controllo_accessi/__manifest__.py @@ -13,7 +13,7 @@ 'wizard/ca_aggiungi_movimento_accesso_views.xml', 'wizard/ca_registra_ospite_views.xml', 'views/ca_tag_lettore_views.xml', - 'views/ca_punto_accesso_persona_views.xml', + 'views/ca_lettore_persona_views.xml', 'views/punto_accesso_category_view.xml', 'views/ca_punto_accesso_views.xml', 'views/ca_persona_view.xml', diff --git a/inrim_controllo_accessi/models/ca_anag_registro_accesso.py b/inrim_controllo_accessi/models/ca_anag_registro_accesso.py index a9d3d28..9c007ba 100644 --- a/inrim_controllo_accessi/models/ca_anag_registro_accesso.py +++ b/inrim_controllo_accessi/models/ca_anag_registro_accesso.py @@ -1,9 +1,8 @@ import pytz from odoo import models, fields -_tzs = [(tz, tz) for tz in sorted(pytz.all_timezones, - key=lambda tz: tz if not tz.startswith( - 'Etc/') else '_')] +_tzs = [(tz, tz) for tz in sorted( + pytz.all_timezones, key=lambda tz: tz if not tz.startswith('Etc/') else '_')] def _tz_get(self): diff --git a/inrim_controllo_accessi/models/ca_lettore_persona.py b/inrim_controllo_accessi/models/ca_lettore_persona.py index 84d5c1c..9537c18 100644 --- a/inrim_controllo_accessi/models/ca_lettore_persona.py +++ b/inrim_controllo_accessi/models/ca_lettore_persona.py @@ -18,18 +18,17 @@ class CaLettorePersona(models.Model): ca_persona_id = fields.Many2one( related="ca_tag_persona.ca_persona_id", store=True, readonly=True) + date_start = fields.Datetime( + related="ca_tag_persona.date_start", readonly=True, store=True) + date_end = fields.Datetime( + related="ca_tag_persona.date_end", readonly=True, store=True) + state = fields.Selection([ ('active', 'Active'), ('expired', 'Expired'), ('scheduled', 'Scheduled') ], readonly=True) - date = fields.Date(readonly=True) - date_start = fields.Datetime( - related="ca_tag_persona.date_start", readonly=True, store=True) - date_end = fields.Datetime( - related="ca_tag_persona.date_end", readonly=True, store=True) - active = fields.Boolean(default=True) @api.constrains( @@ -44,35 +43,31 @@ def _check_unique(self): ('ca_tag_persona', '=', record.ca_tag_persona.id), ('date_start', '<=', record.date_start), ('date_end', '>=', record.date_end), - ('state', '=', 'active') + ('state', 'not in', ['expired']) ]) if punto_accesso_persona_id: raise UserError( _('Puo’ esistere solo una configurazione per tag lettore, tag persona, data, in stato attivo')) + @api.onchange('date_start', 'date_end') + def _compute_expired(self): + for record in self: + record.check_update_state() + def elabora_persone(self, lettore_id): vals = [] ca_tag_lettore_ids = self.env['ca.tag_lettore'].search([ - ('ca_lettore_id', '=', lettore_id.id), ('expired', '=', False), + ('ca_lettore_id', '=', lettore_id.id), ('state', 'not in', ['expired']), ]) if ca_tag_lettore_ids: for tag_lettore in ca_tag_lettore_ids: - tag_lettore._compute_expired() - tag_lettore._compute_scheduled() - if not tag_lettore.expired and not tag_lettore.scheduled: + tag_lettore.check_update_state() + if tag_lettore.state == 'active': now = fields.Datetime.now() tag_persona_id = self.env['ca.tag_persona'].get_current_by_tag( tag_lettore.ca_tag_id) if tag_persona_id: - old_lettore_persona_id = self.env[ - 'ca.lettore_persona' - ].search([ - ('ca_tag_lettore_id', '=', tag_lettore.id), - ('ca_tag_persona', '=', tag_persona_id.id), - ('date_end', '<', now), - ('state', '=', 'active') - ]) lettore_persona_id = self.env[ 'ca.lettore_persona' ].search([ @@ -80,19 +75,16 @@ def elabora_persone(self, lettore_id): ('ca_tag_persona', '=', tag_persona_id.id), ('date_start', '<=', now), ('date_end', '>=', now), - ('state', '=', 'active') + ('state', 'not in', ['expired']) ]) - if old_lettore_persona_id: - old_lettore_persona_id.state = 'expired' if not lettore_persona_id: new_lettore_persona_id = self.env[ 'ca.lettore_persona' ].create({ 'ca_tag_lettore_id': tag_lettore.id, - 'ca_tag_persona': tag_persona_id.id, - 'date': fields.date.today(), - 'state': 'active' + 'ca_tag_persona': tag_persona_id.id }) + new_lettore_persona_id.check_update_state() vals.append(new_lettore_persona_id) return vals @@ -104,3 +96,21 @@ def elabora_persone_lettore(self, nome_lettore): return self.elabora_persone(lettore_id) else: return None + + def check_update_state(self): + now = fields.Datetime.now() + self.ensure_one() + if self.date_start <= now <= self.date_end: + self.state = 'active' + elif self.date_start > now: + self.state = 'scheduled' + elif self.date_end <= now: + self.state = 'expired' + + def check_update_by_date_valididty(self): + for person_reader in self.env['ca.lettore_persona'].search([]): + if person_reader: + person_reader.check_update_state() + + def _cron_check_validity_winfo(self): + self.check_update_by_date_valididty() diff --git a/inrim_controllo_accessi/models/ca_punto_accesso.py b/inrim_controllo_accessi/models/ca_punto_accesso.py index 96e59f7..fc12437 100644 --- a/inrim_controllo_accessi/models/ca_punto_accesso.py +++ b/inrim_controllo_accessi/models/ca_punto_accesso.py @@ -272,16 +272,18 @@ def stamping_attach(self): tag_lettore = self.env['ca.tag_lettore'].search( [ ('ca_tag_id', '=', tag.id), - ('ca_lettore_id', "=", self.ca_lettore_id.id) + ('ca_lettore_id', "=", self.ca_lettore_id.id), + ('state', '=', 'active') ], limit=1) if not tag_lettore: - self.env['ca.tag_lettore'].create({ + tag_lettore = self.env['ca.tag_lettore'].create({ 'ca_lettore_id': self.ca_lettore_id.id, 'ca_tag_id': tag.id, 'date_start': self.date_start, 'date_end': self.date_end, 'ca_punto_accesso_id': self.id }) + tag_lettore.check_update_state() self.env['ca.lettore_persona'].elabora_persone(self.ca_lettore_id) diff --git a/inrim_controllo_accessi/models/ca_tag_lettore.py b/inrim_controllo_accessi/models/ca_tag_lettore.py index 513a9a4..68d7074 100644 --- a/inrim_controllo_accessi/models/ca_tag_lettore.py +++ b/inrim_controllo_accessi/models/ca_tag_lettore.py @@ -14,12 +14,15 @@ class CaTagLettore(models.Model): date_start = fields.Date(required=True) date_end = fields.Date(required=True) temp = fields.Boolean(related='ca_tag_id.temp') - expired = fields.Boolean(compute="_compute_expired", store=True) - scheduled = fields.Boolean(compute="_compute_scheduled", store=True) - active = fields.Boolean(default=True) + state = fields.Selection([ + ('active', 'Active'), + ('expired', 'Expired'), + ('scheduled', 'Scheduled') + ], readonly=True) ca_punto_accesso_id = fields.Many2one('ca.punto_accesso') - access_point_typology = fields.Selection(related="ca_punto_accesso_id.typology", - store=True) + access_point_typology = fields.Selection( + related="ca_punto_accesso_id.typology", store=True) + active = fields.Boolean(default=True) def rest_boby_hint(self): return { @@ -83,7 +86,7 @@ def detach(self): self.ensure_one() if self.ca_punto_accesso_id: self.ca_punto_accesso_id.remote_update = True - self.expired = True + self.state = 'expired' self.active = False @api.onchange('ca_lettore_id') @@ -108,19 +111,28 @@ def _onchange_ca_tag_id(self): record.date_start = tag_persona_id.date_start record.date_end = tag_persona_id.date_end - @api.onchange('date_end') - def _compute_expired(self): - for record in self: - record.expired = False - if record.date_end and fields.date.today() > record.date_end: - record.expired = True - - @api.onchange('date_start', 'active') + @api.onchange('date_start', 'date_end') def _compute_scheduled(self): for record in self: - record.scheduled = False - if record.date_start > fields.date.today(): - record.scheduled = True + record.check_update_state() + + def check_update_state(self): + now = fields.Date.today() + self.ensure_one() + if self.date_start <= now <= self.date_end: + self.state = 'active' + elif self.date_start > now: + self.state = 'scheduled' + elif self.date_end <= now: + self.state = 'expired' + + def check_update_by_date_valididty(self): + for tag_reader in self.env['ca.tag_lettore'].search([]): + if tag_reader: + tag_reader.check_update_state() + + def _cron_check_validity_winfo(self): + self.check_update_by_date_valididty() @api.depends('ca_lettore_id', 'ca_tag_id') def _compute_name(self): @@ -136,7 +148,7 @@ def _check_unique(self): ('id', '!=', record.id), ('ca_lettore_id', '=', record.ca_lettore_id.id), ('ca_tag_id', '=', record.ca_tag_id.id), - ('expired', '=', False), + ('state', 'not in', ['expired']), ('active', '=', True) ]) if tag_lettore_id: diff --git a/inrim_controllo_accessi/tests/test_inrim.py b/inrim_controllo_accessi/tests/test_inrim.py index 28107ac..ca7981c 100644 --- a/inrim_controllo_accessi/tests/test_inrim.py +++ b/inrim_controllo_accessi/tests/test_inrim.py @@ -155,6 +155,8 @@ def test_7(self): ('ca_tag_id', "=", self.tag_8.id), ]) + self.assertEqual(ca_tag_lettore.state, 'active') + self.assertTrue(self.punto_accesso_2.enable_sync) # 5 tag_persona_id = self.env['ca.tag_persona'].with_user( diff --git a/inrim_controllo_accessi/views/ca_punto_accesso_persona_views.xml b/inrim_controllo_accessi/views/ca_lettore_persona_views.xml similarity index 84% rename from inrim_controllo_accessi/views/ca_punto_accesso_persona_views.xml rename to inrim_controllo_accessi/views/ca_lettore_persona_views.xml index fbeb217..eca16dc 100644 --- a/inrim_controllo_accessi/views/ca_punto_accesso_persona_views.xml +++ b/inrim_controllo_accessi/views/ca_lettore_persona_views.xml @@ -7,8 +7,9 @@ + + - @@ -19,17 +20,18 @@
+ - + - - - + + diff --git a/inrim_controllo_accessi/views/ca_punto_accesso_views.xml b/inrim_controllo_accessi/views/ca_punto_accesso_views.xml index 9131f1f..97d0b3c 100644 --- a/inrim_controllo_accessi/views/ca_punto_accesso_views.xml +++ b/inrim_controllo_accessi/views/ca_punto_accesso_views.xml @@ -103,7 +103,8 @@ options="{'no_create': True}" readonly="enable_sync"/> - + @@ -133,9 +134,13 @@ domain="[('type_ids', 'in', type_ids)]"/> - - - + + + + + + + @@ -146,6 +151,7 @@ + + + @@ -161,7 +171,7 @@ - + diff --git a/inrim_controllo_accessi/views/ca_tag_lettore_views.xml b/inrim_controllo_accessi/views/ca_tag_lettore_views.xml index 8d8643d..a158270 100644 --- a/inrim_controllo_accessi/views/ca_tag_lettore_views.xml +++ b/inrim_controllo_accessi/views/ca_tag_lettore_views.xml @@ -11,8 +11,7 @@ - - + @@ -23,17 +22,21 @@
+ - - + + @@ -41,7 +44,6 @@ - @@ -58,28 +60,38 @@
-
+ +
- Reader:
+ Reader: + +
- Tag:
+ Tag: + +
- Tag In Use:
+ Tag In Use: + +
- Date Start:
+ Date Start: + +
- Date End:
+ Date End: + +
- Temp:
-
- - Expired:
+ Temp: + +
diff --git a/inrim_controllo_accessi/views/menus.xml b/inrim_controllo_accessi/views/menus.xml index a4d6b0f..e5506a3 100644 --- a/inrim_controllo_accessi/views/menus.xml +++ b/inrim_controllo_accessi/views/menus.xml @@ -14,7 +14,7 @@ action="ca_punto_accesso_category_action" groups="controllo_accessi.ca_ca" parent="ca_punto_accesso_menu" - sequence="1" + sequence="2" /> diff --git a/inrim_controllo_accessi/wizard/ca_registra_ospite.py b/inrim_controllo_accessi/wizard/ca_registra_ospite.py index 5da64df..ac5ea60 100644 --- a/inrim_controllo_accessi/wizard/ca_registra_ospite.py +++ b/inrim_controllo_accessi/wizard/ca_registra_ospite.py @@ -32,7 +32,7 @@ class CaRegistraOspite(models.TransientModel): available_tags_ids = fields.Many2many('ca.tag', compute="_compute_available_tags") ente_interno = fields.Boolean(string="Interno") work_id_number = fields.Char( - string="A.C. ID Numeber", groups="controllo_accessi.ca_gdpr") + string="ID Number", groups="controllo_accessi.ca_gdpr") def ente_azienda_domain(self): return [ diff --git a/inrim_controllo_accessi_rfidglobal/models/ca_punto_accesso.py b/inrim_controllo_accessi_rfidglobal/models/ca_punto_accesso.py index cedb334..13c94b6 100644 --- a/inrim_controllo_accessi_rfidglobal/models/ca_punto_accesso.py +++ b/inrim_controllo_accessi_rfidglobal/models/ca_punto_accesso.py @@ -206,7 +206,7 @@ def decode_data(self, code, file_path): if tag: tag_persona = self.env['ca.tag_persona'].search([ ('ca_tag_id.id', '=', tag.id), - ('tag_in_use', '=', True)]) + ('state', '=', 'to_give_back')]) if tag_persona: riga_accesso_model.aggiungi_riga_accesso( self, tag_persona, @@ -218,7 +218,7 @@ def decode_data(self, code, file_path): return True else: logger.error( - f"tag {record.idd} not associated with no one ") + f"tag {record.idd} associated with no one ") return False else: logger.error(