Skip to content
This repository has been archived by the owner on Apr 30, 2024. It is now read-only.

Commit

Permalink
Merge pull request #274 from OpenSPP/273-unique-id-on-area-and-servic…
Browse files Browse the repository at this point in the history
…e-point

[UPD] add unique_id to service point and area
  • Loading branch information
gonzalesedwin1123 authored Dec 8, 2023
2 parents 48ad71a + 28bcbe1 commit ddbc42e
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 109 deletions.
4 changes: 2 additions & 2 deletions spp_idpass/views/id_pass_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@
<field name="act_window_id" ref="action_spp_idpass" />
</record>

<menuitem
<!-- <menuitem
id="menu_spp_idpass"
name="ID PASS"
action="action_spp_idpass"
parent="spp_idpass.id_pass_configuration_menu_root"
sequence="10"
groups="g2p_registry_base.group_g2p_admin"
/>
/> -->
</odoo>
4 changes: 1 addition & 3 deletions spp_registrant_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
def post_init_hook(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
contact_model = env.ref("base.model_res_partner")
registrant_id_field = env.ref(
"spp_registrant_import.field_res_partner__registrant_id"
)
registrant_id_field = env.ref("spp_registrant_import.field_res_partner__spp_id")
contact_import_match = env["spp.import.match"].search(
[("model_id", "=", contact_model.id)]
)
Expand Down
7 changes: 3 additions & 4 deletions spp_registrant_import/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,13 @@
"development_status": "Alpha",
"maintainers": ["jeremi", "gonzalesedwin1123", "nhatnm0612"],
"depends": [
"base",
"g2p_registry_base",
"g2p_registry_individual",
"g2p_registry_group",
"spp_base",
"spp_import_match",
],
"data": [
"views/res_partner_views.xml",
"views/spp_area_views.xml",
"views/spp_service_point_views.xml",
],
"application": False,
"installable": True,
Expand Down
2 changes: 2 additions & 0 deletions spp_registrant_import/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from . import res_partner
from . import spp_area
from . import spp_service_point
85 changes: 18 additions & 67 deletions spp_registrant_import/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,79 +1,16 @@
import random
import re
import string

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo import api, models, fields


class Registrant(models.Model):
_inherit = "res.partner"
_name = "res.partner"
_inherit = ["res.partner", "spp.unique.id"]

name = fields.Char(
compute="_compute_name",
inverse="_inverse_name",
store=True,
)
registrant_id = fields.Char(
string="Registrant ID",
compute="_compute_registrant_id",
store=True,
readonly=False,
index=True,
)

_sql_constraints = [
(
"registrant_id_uniq",
"UNIQUE(registrant_id)",
"registrant_id is an unique identifier!",
)
]

@api.constrains("registrant_id")
def _check_registrant_id(self):
match_pattern = r"^(IND|GRP)_[0-9A-Z]{8}$"
not_correct_format = _("Registrant ID is not following correct format!")
for rec in self:
if not rec.is_registrant:
continue
if not re.match(match_pattern, rec.registrant_id):
raise ValidationError(not_correct_format)
if rec.is_group and rec.registrant_id.startswith("IND_"):
raise ValidationError(not_correct_format)
if not rec.is_group and rec.registrant_id.startswith("GRP_"):
raise ValidationError(not_correct_format)
if any(
[
char in rec.registrant_id.split("_")[-1]
for char in ("0", "O", "1", "I")
]
):
raise ValidationError(not_correct_format)

@api.depends("is_registrant", "is_group")
def _compute_registrant_id(self):
for rec in self:
if not rec.is_registrant:
rec.registrant_id = None
continue
prefix = "GRP" if rec.is_group else "IND"
unique_id = self._generate_unique_id()
rec.registrant_id = "_".join([prefix, unique_id])

def _generate_unique_id(self):
# Adjust the desired length of the unique identifier
length = 8
# Define the characters allowed in the unique identifier
characters = string.digits + string.ascii_uppercase
# Exclude characters that can be confused
excluded_characters = ["0", "O", "1", "I"]
# Filter the characters to exclude
allowed_characters = [c for c in characters if c not in excluded_characters]
# Generate the unique identifier by randomly selecting characters
unique_id = "".join(random.choice(allowed_characters) for _ in range(length))

return unique_id
spp_id = fields.Char(readonly=False)

@api.onchange("is_group", "family_name", "given_name", "addl_name")
def name_change(self):
Expand Down Expand Up @@ -113,3 +50,17 @@ def _inverse_name(self):
rec.family_name = name[0]
rec.given_name = name[1]
rec.addl_name = name[2]

def _get_spp_id_prefix(self):
if not self.is_registrant:
return ""
if self.is_group:
return "GRP"
return "IND"

def _get_match_spp_id_pattern(self):
if not self.is_registrant:
return ""
if self.is_group:
return r"^GRP_[0-9A-Z]{8}$"
return r"^IND_[0-9A-Z]{8}$"
12 changes: 12 additions & 0 deletions spp_registrant_import/models/spp_area.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import models


class SppArea(models.Model):
_name = "spp.area"
_inherit = ["spp.area", "spp.unique.id"]

def _get_spp_id_prefix(self):
return "LOC"

def _get_match_spp_id_pattern(self):
return r"^LOC_[0-9A-Z]{8}$"
12 changes: 12 additions & 0 deletions spp_registrant_import/models/spp_service_point.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from odoo import models


class SppServicePoint(models.Model):
_name = "spp.service.point"
_inherit = ["spp.service.point", "spp.unique.id"]

def _get_spp_id_prefix(self):
return "SVP"

def _get_match_spp_id_pattern(self):
return r"^SVP_[0-9A-Z]{8}$"
2 changes: 2 additions & 0 deletions spp_registrant_import/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from . import test_area
from . import test_registrant
from . import test_service_point
58 changes: 58 additions & 0 deletions spp_registrant_import/tests/test_area.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from psycopg2.errors import UniqueViolation

from odoo.exceptions import ValidationError
from odoo.tests import TransactionCase
from odoo.tools import mute_logger

EXCLUDED_CHARACTERS = ["0", "O", "1", "I"]


class TestArea(TransactionCase):
def setUp(self):
super().setUp()
self.area_1, self.area_2 = self.env["spp.area"].create(
[
{"draft_name": "Area 1"},
{"draft_name": "Area 2"},
]
)

def test_01_compute_spp_id_uniq(self):
self.assertNotEqual(self.area_1.spp_id, self.area_2.spp_id)

def test_02_compute_spp_id(self):
for area in [self.area_1, self.area_2]:
self.assertRegex(
area.spp_id,
r"^LOC_[a-zA-Z0-9]{8}$",
"Area should have unique id start with "
"`LOC_` and following by 8 characters.",
)
for char in EXCLUDED_CHARACTERS:
self.assertNotIn(
char,
area.spp_id.split("_")[-1],
"Excluded characters should not be exist in spp_id",
)

@mute_logger("odoo.sql_db")
def test_03_spp_id_unique_violation(self):
with self.assertRaises(UniqueViolation):
self.area_1.write(
{
"spp_id": self.area_2.spp_id,
}
)

@mute_logger("py.warnings")
def test_04_check_spp_id(self):
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# 7 characters spp_id
self.area_1.write({"spp_id": "LOC_AaAaAa2"})
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# '1' in spp_id
self.area_2.write({"spp_id": "LOC_AaAaAa21"})
54 changes: 27 additions & 27 deletions spp_registrant_import/tests/test_registrant.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ def setUp(self):
"is_group": True,
}
)
self._test_individuals = [
self.create_registrant({"name": "TEST, INDIVIDUAL, 1"}),
self.create_registrant({"name": "TEST, INDIVIDUAL, 2"}),
]
self._test_individuals = (
self.create_registrant({"name": "TEST, INDIVIDUAL, 1"}) |
self.create_registrant({"name": "TEST, INDIVIDUAL, 2"})
)
self._partner = self.env["res.partner"].create(
{
"name": "Partner 1",
Expand Down Expand Up @@ -48,73 +48,73 @@ def create_registrant(self, vals):
virtual_rec._compute_name()
return model.create(virtual_rec._convert_to_write(virtual_rec._cache))

def test_01_compute_registrant_id_normal_partner(self):
def test_01_compute_spp_id_normal_partner(self):
self.assertFalse(
bool(self._partner.registrant_id),
"Normal Odoo contact should not have registrant_id",
bool(self._partner.spp_id),
"Normal Odoo contact should not have spp_id",
)

def test_02_compute_registrant_id_household(self):
def test_02_compute_spp_id_household(self):
self.assertRegex(
self._test_household.registrant_id,
self._test_household.spp_id,
r"^GRP_[a-zA-Z0-9]{8}$",
"Household should have unique registrant id start with "
"`GRP_` and following by 8 characters.",
)
for char in EXCLUDED_CHARACTERS:
self.assertNotIn(
char,
self._test_household.registrant_id.split("_")[-1],
"Excluded characters should not be exist in unique registrant_id",
self._test_household.spp_id.split("_")[-1],
"Excluded characters should not be exist in unique spp_id",
)

def test_03_compute_registrant_id_individual(self):
def test_03_compute_spp_id_individual(self):
for individual in self._test_individuals:
self.assertRegex(
individual.registrant_id,
individual.spp_id,
r"^IND_[a-zA-Z0-9]{8}$",
"Individual should have unique registrant id start with "
"`IND_` and following by 8 characters.",
)
for char in EXCLUDED_CHARACTERS:
self.assertNotIn(
char,
individual.registrant_id.split("_")[-1],
"Excluded characters should not be exist in unique registrant_id",
individual.spp_id.split("_")[-1],
"Excluded characters should not be exist in unique spp_id",
)

@mute_logger("odoo.sql_db")
def test_04_compute_registrant_id_unique_violation(self):
def test_04_compute_spp_id_unique_violation(self):
with (self.env.cr.savepoint(), self.assertRaises(UniqueViolation)):
self._test_individuals[0].write(
{
"registrant_id": self._test_individuals[1].registrant_id,
"spp_id": self._test_individuals[1].spp_id,
}
)

@mute_logger("py.warnings")
def test_05_check_registrant_id(self):
def test_05_check_spp_id(self):
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# 7 characters registrant_id
self._test_household.write({"registrant_id": "GRP_AAAAAA2"})
# 7 characters spp_id
self._test_household.write({"spp_id": "GRP_AAAAAA2"})
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# '1' in registrant_id
self._test_individuals[0].write({"registrant_id": "IND_AAAAAA21"})
# '1' in spp_id
self._test_individuals[0].write({"spp_id": "IND_AAAAAA21"})
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# individual with registrant_id starts with GRP_
self._test_individuals[0].write({"registrant_id": "GRP_AAAAAA22"})
# individual with spp_id starts with GRP_
self._test_individuals[0].write({"spp_id": "GRP_AAAAAA22"})
with self.assertRaisesRegex(
ValidationError, "^.*not following correct format.{1}$"
):
# group with registrant_id starts with IND_
self._test_household.write({"registrant_id": "IND_AAAAAA22"})
self._partner.write({"registrant_id": "IND_AAAAAA21"})
# group with spp_id starts with IND_
self._test_household.write({"spp_id": "IND_AAAAAA22"})
self._partner.write({"spp_id": "IND_AAAAAA21"})

def test_06__inverse_name(self):
registrant_1 = self._test_individuals[0]
Expand Down
Loading

0 comments on commit ddbc42e

Please sign in to comment.