Skip to content

Commit

Permalink
21737 - Create alembic script & model for furnishings table (#2761)
Browse files Browse the repository at this point in the history
* 21737 - create alembic script & model for furnishings table

Signed-off-by: Hongjing Chen <[email protected]>

* revert changes for address model

Signed-off-by: Hongjing Chen <[email protected]>

* add sequence for grouping_identifier

Signed-off-by: Hongjing Chen <[email protected]>

---------

Signed-off-by: Hongjing Chen <[email protected]>
  • Loading branch information
chenhongjing authored Jun 18, 2024
1 parent 0118c86 commit bca5088
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 1 deletion.
66 changes: 66 additions & 0 deletions legal-api/migrations/versions/01b28a2bb730_furnishings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"""furnishings
Revision ID: 01b28a2bb730
Revises: 3083d361616e
Create Date: 2024-06-12 20:10:44.723041
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import postgresql


# revision identifiers, used by Alembic.
revision = '01b28a2bb730'
down_revision = '3083d361616e'
branch_labels = None
depends_on = None


def upgrade():
op.create_table('furnishings',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('furnishing_type', sa.Enum('EMAIL', 'MAIL', 'GAZETTE', name='furnishing_type'), nullable=False),
sa.Column('furnishing_name', sa.Enum(
'DISSOLUTION_COMMENCEMENT_NO_AR',
'DISSOLUTION_COMMENCEMENT_NO_TR',
'DISSOLUTION_COMMENCEMENT_NO_AR_XPRO',
'DISSOLUTION_COMMENCEMENT_NO_TR_XPRO',
'INTENT_TO_DISSOLVE',
'INTENT_TO_DISSOLVE_XPRO',
'CORP_DISSOLVED',
'CORP_DISSOLVED_XPRO',
name='furnishing_name'
),
nullable=False
),
sa.Column('batch_id', sa.Integer(), nullable=False),
sa.Column('grouping_identifier', sa.Integer(), nullable=True),
sa.Column('business_id', sa.Integer(), nullable=False),
sa.Column('business_identifier', sa.VARCHAR(10), nullable=False),
sa.Column('processed_date', sa.TIMESTAMP(timezone=True), nullable=True),
sa.Column('status', sa.Enum('QUEUED', 'PROCESSED', 'FAILED', name='furnishing_status'), nullable=False),
sa.Column('notes', sa.VARCHAR(length=150), nullable=True),
sa.Column('meta_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
sa.Column('created_date', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('last_modified', sa.TIMESTAMP(timezone=True), nullable=False),
sa.Column('email', sa.VARCHAR(length=254), nullable=True),
sa.Column('last_name', sa.VARCHAR(length=30), nullable=True),
sa.Column('first_name', sa.VARCHAR(length=30), nullable=True),
sa.Column('middle_name', sa.VARCHAR(length=30), nullable=True),
sa.Column('address_id', sa.Integer(), nullable=True),
sa.ForeignKeyConstraint(['address_id'], ['addresses.id']),
sa.ForeignKeyConstraint(['batch_id'], ['batches.id']),
sa.ForeignKeyConstraint(['business_id'], ['businesses.id']),
sa.PrimaryKeyConstraint('id')
)

op.execute("CREATE SEQUENCE grouping_identifier START 1;")


def downgrade():
op.drop_table('furnishings')
op.execute("DROP TYPE furnishing_type;")
op.execute("DROP TYPE furnishing_name;")
op.execute("DROP TYPE furnishing_status;")
op.execute("DROP SEQUENCE grouping_identifier;")
2 changes: 2 additions & 0 deletions legal-api/src/legal_api/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from .dc_revocation_reason import DCRevocationReason
from .document import Document, DocumentType
from .filing import Filing
from .furnishing import Furnishing
from .jurisdiction import Jurisdiction
from .naics_element import NaicsElement
from .naics_structure import NaicsStructure
Expand Down Expand Up @@ -68,6 +69,7 @@
'Document',
'DocumentType',
'Filing',
'Furnishing',
'Jurisdiction',
'NaicsElement',
'NaicsStructure',
Expand Down
5 changes: 4 additions & 1 deletion legal-api/src/legal_api/models/batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module holds data for batch."""
from __future__ import annotations

from enum import auto
from typing import List

from legal_api.utils.base import BaseEnum
from legal_api.utils.datetime import datetime
Expand Down Expand Up @@ -63,7 +66,7 @@ def find_by_id(cls, batch_id: int):
@classmethod
def find_by(cls, # pylint: disable=too-many-arguments
batch_type: BatchType = None,
status: BatchStatus = None) -> dict:
status: BatchStatus = None) -> List[Batch]:
"""Return the batch matching."""
query = db.session.query(Batch)
batches = []
Expand Down
123 changes: 123 additions & 0 deletions legal-api/src/legal_api/models/furnishing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module holds data for furnishings."""
from __future__ import annotations

from enum import auto
from typing import List

from sqlalchemy.dialects.postgresql import JSONB

from legal_api.utils.base import BaseEnum
from legal_api.utils.datetime import datetime

from .db import db


class Furnishing(db.Model):
"""This class manages the furnishings."""

class FurnishingType(BaseEnum):
"""Render an Enum for the furnishing type."""

EMAIL = auto()
MAIL = auto()
GAZETTE = auto()

class FurnishingName(BaseEnum):
"""Render an Enum for the furnishing name."""

DISSOLUTION_COMMENCEMENT_NO_AR = auto()
DISSOLUTION_COMMENCEMENT_NO_TR = auto()
DISSOLUTION_COMMENCEMENT_NO_AR_XPRO = auto()
DISSOLUTION_COMMENCEMENT_NO_TR_XPRO = auto()
INTENT_TO_DISSOLVE = auto()
INTENT_TO_DISSOLVE_XPRO = auto()
CORP_DISSOLVED = auto()
CORP_DISSOLVED_XPRO = auto()

class FurnishingStatus(BaseEnum):
"""Render an Enum for the furnishing status."""

QUEUED = auto()
PROCESSED = auto()
FAILED = auto()

__tablename__ = 'furnishings'

id = db.Column(db.Integer, primary_key=True)
furnishing_type = db.Column('furnishing_type', db.Enum(FurnishingType), nullable=False)
furnishing_name = db.Column('furnishing_name', db.Enum(FurnishingName), nullable=False)
grouping_identifier = db.Column(db.Integer, nullable=True)
business_identifier = db.Column('business_identifier', db.String(10), default='', nullable=False)
processed_date = db.Column('processed_date', db.DateTime(timezone=True), nullable=True)
status = db.Column('status', db.Enum(FurnishingStatus), nullable=False)
notes = db.Column('notes', db.String(150), default='', nullable=True)
meta_data = db.Column('meta_data', JSONB, nullable=True)
created_date = db.Column('created_date', db.DateTime(timezone=True), default=datetime.utcnow)
last_modified = db.Column('last_modified', db.DateTime(timezone=True), default=datetime.utcnow)
email = db.Column('email', db.String(254), default='', nullable=True)
last_name = db.Column('last_name', db.String(30), default='', nullable=True)
first_name = db.Column('first_name', db.String(30), default='', nullable=True)
middle_name = db.Column('middle_name', db.String(30), default='', nullable=True)

# parent keys
batch_id = db.Column('batch_id', db.Integer, db.ForeignKey('batches.id'), index=True, nullable=False)
business_id = db.Column('business_id', db.Integer, db.ForeignKey('businesses.id'), index=True, nullable=False)
address_id = db.Column('address_id', db.Integer, db.ForeignKey('addresses.id'), index=True, nullable=True)

def save(self):
"""Save the object to the database immediately."""
db.session.add(self)
db.session.commit()

@classmethod
def find_by_id(cls, furnishing_id: int):
"""Return a Furnishing entry by the id."""
furnishing = None
if furnishing_id:
furnishing = cls.query.filter_by(id=furnishing_id).one_or_none()
return furnishing

@classmethod
def find_by(cls, # pylint: disable=too-many-arguments
batch_id: int = None,
business_id: int = None,
furnishing_name: str = None,
furnishing_type: str = None,
status: str = None,
grouping_identifier: int = None
) -> List[Furnishing]:
"""Return the Furnishing entries matching the filter."""
query = db.session.query(Furnishing)

if batch_id:
query = query.filter(Furnishing.batch_id == batch_id)

if business_id:
query = query.filter(Furnishing.business_id == business_id)

if furnishing_name:
query = query.filter(Furnishing.furnishing_name == furnishing_name)

if furnishing_type:
query = query.filter(Furnishing.furnishing_type == furnishing_type)

if status:
query = query.filter(Furnishing.status == status)

if grouping_identifier:
query = query.filter(Furnishing.grouping_identifier == grouping_identifier)

return query.all()
126 changes: 126 additions & 0 deletions legal-api/tests/unit/models/test_furnishing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Copyright © 2024 Province of British Columbia
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Tests to assure the Furnishing Model.
Test-Suite to ensure that the Furnishing Model is working as expected.
"""
import pytest
from legal_api.models import Furnishing
from tests.unit.models import factory_business, factory_batch

def test_valid_furnishing_save(session):
"""Assert that a valid furnishing can be saved."""
identifier = 'BC1234567'
business = factory_business(identifier)
batch = factory_batch()
furnishing = Furnishing(
furnishing_type = Furnishing.FurnishingType.EMAIL,
furnishing_name = Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
batch_id = batch.id,
business_id = business.id,
business_identifier = business.identifier,
status = Furnishing.FurnishingStatus.QUEUED
)

furnishing.save()
assert furnishing.id


def test_find_furnishing_by_id(session):
"""Assert that the method returns correct value."""
identifier = 'BC1234567'
business = factory_business(identifier)
batch = factory_batch()
furnishing = Furnishing(
furnishing_type = Furnishing.FurnishingType.EMAIL,
furnishing_name = Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
batch_id = batch.id,
business_id = business.id,
business_identifier = business.identifier,
status = Furnishing.FurnishingStatus.QUEUED
)

furnishing.save()

res = Furnishing.find_by_id(furnishing_id=furnishing.id)

assert res


@pytest.mark.parametrize(
'params', [
{
'batch_id': None,
'business_id': None,
'furnishing_name': None,
'furnishing_type': None,
'status': None,
'grouping_identifier': None
},
{
'batch_id': None,
'business_id': None,
'furnishing_name': Furnishing.FurnishingType.EMAIL,
'furnishing_type': None,
'status': None,
'grouping_identifier': None
},
{
'batch_id': None,
'business_id': None,
'furnishing_name': Furnishing.FurnishingType.EMAIL,
'furnishing_type': Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
'status': None,
'grouping_identifier': None
},
{
'batch_id': None,
'business_id': None,
'furnishing_name': Furnishing.FurnishingType.EMAIL,
'furnishing_type': Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
'status': Furnishing.FurnishingStatus.QUEUED,
'grouping_identifier': None
},
{
'batch_id': None,
'business_id': None,
'furnishing_name': Furnishing.FurnishingType.EMAIL,
'furnishing_type': Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
'status': Furnishing.FurnishingStatus.QUEUED,
'grouping_identifier': 2
},
]
)
def test_find_furnishing_by(session, params):
"""Assert that the method returns correct values."""
identifier = 'BC1234567'
business = factory_business(identifier)
batch = factory_batch()
furnishing = Furnishing(
furnishing_type = Furnishing.FurnishingType.EMAIL,
furnishing_name = Furnishing.FurnishingName.DISSOLUTION_COMMENCEMENT_NO_AR,
batch_id = batch.id,
business_id = business.id,
business_identifier = business.identifier,
status = Furnishing.FurnishingStatus.QUEUED,
grouping_identifier = 2
)

furnishing.save()

res = Furnishing.find_by(**params)

assert len(res) == 1
assert res[0].id == furnishing.id

0 comments on commit bca5088

Please sign in to comment.