diff --git a/strr-api/migrations/versions/20250204_1137_7e9fccbeb3ed_.py b/strr-api/migrations/versions/20250204_1137_7e9fccbeb3ed_.py new file mode 100644 index 00000000..004380b8 --- /dev/null +++ b/strr-api/migrations/versions/20250204_1137_7e9fccbeb3ed_.py @@ -0,0 +1,38 @@ +"""empty message + +Revision ID: 7e9fccbeb3ed +Revises: 842bb132abc7 +Create Date: 2025-02-04 11:37:53.005700 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '7e9fccbeb3ed' +down_revision = '842bb132abc7' +branch_labels = None +depends_on = None + +stratahotelcategory = postgresql.ENUM('FULL_SERVICE', 'MULTI_UNIT_NON_PR', 'POST_DECEMBER_2023', name='stratahotelcategory') +stratahotelcategory.create(op.get_bind(), checkfirst=True) + +def upgrade(): + with op.batch_alter_table('rental_properties', schema=None) as batch_op: + batch_op.add_column(sa.Column('strata_hotel_category', stratahotelcategory, nullable=True)) + batch_op.create_index(batch_op.f('ix_rental_properties_strata_hotel_category'), ['strata_hotel_category'], unique=False) + + with op.batch_alter_table('rental_properties_history', schema=None) as batch_op: + batch_op.add_column(sa.Column('strata_hotel_category', stratahotelcategory, autoincrement=False, nullable=True)) + batch_op.create_index(batch_op.f('ix_rental_properties_history_strata_hotel_category'), ['strata_hotel_category'], unique=False) + + +def downgrade(): + with op.batch_alter_table('rental_properties', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_rental_properties_strata_hotel_category')) + batch_op.drop_column('strata_hotel_category') + + with op.batch_alter_table('rental_properties_history', schema=None) as batch_op: + batch_op.drop_index(batch_op.f('ix_rental_properties_history_strata_hotel_category')) + batch_op.drop_column('strata_hotel_category') diff --git a/strr-api/src/strr_api/enums/enum.py b/strr-api/src/strr_api/enums/enum.py index deb91999..d7d3a1e2 100644 --- a/strr-api/src/strr_api/enums/enum.py +++ b/strr-api/src/strr_api/enums/enum.py @@ -15,6 +15,8 @@ from enum import Enum +from strr_api.common.enum import BaseEnum, auto + class AuthHeaderType(Enum): """Authorization header types.""" @@ -163,3 +165,11 @@ class ApplicationRole(Enum): """STRR Application Roles.""" HOST = "HOST" + + +class StrataHotelCategory(BaseEnum): + """Enum of the strata hotel category.""" + + FULL_SERVICE = auto() # pylint: disable=invalid-name + MULTI_UNIT_NON_PR = auto() # pylint: disable=invalid-name + POST_DECEMBER_2023 = auto() # pylint: disable=invalid-name diff --git a/strr-api/src/strr_api/models/rental.py b/strr-api/src/strr_api/models/rental.py index 63cf929e..7409df29 100644 --- a/strr-api/src/strr_api/models/rental.py +++ b/strr-api/src/strr_api/models/rental.py @@ -10,7 +10,7 @@ from sqlalchemy.orm import relationship from strr_api.common.enum import BaseEnum, auto -from strr_api.enums.enum import PropertyType, RegistrationStatus +from strr_api.enums.enum import PropertyType, RegistrationStatus, StrataHotelCategory from strr_api.models.base_model import BaseModel from .db import db @@ -91,6 +91,7 @@ class OwnershipType(BaseEnum): is_unit_on_principal_residence_property = db.Column(db.Boolean, nullable=False) number_of_rooms_for_rent = db.Column(db.Integer, nullable=False) strata_hotel_registration_number = db.Column(db.String, nullable=True) + strata_hotel_category = db.Column(Enum(StrataHotelCategory), nullable=True, index=True) address_id = db.Column(db.Integer, db.ForeignKey("addresses.id"), nullable=False) registration_id = db.Column(db.Integer, db.ForeignKey("registrations.id"), nullable=False) diff --git a/strr-api/src/strr_api/models/strata_hotels.py b/strr-api/src/strr_api/models/strata_hotels.py index 1193b714..4ea1cf31 100644 --- a/strr-api/src/strr_api/models/strata_hotels.py +++ b/strr-api/src/strr_api/models/strata_hotels.py @@ -7,7 +7,7 @@ from sqlalchemy import Enum from sqlalchemy.orm import relationship -from strr_api.common.enum import BaseEnum, auto +from strr_api.enums.enum import StrataHotelCategory from strr_api.models.base_model import BaseModel from .db import db @@ -16,13 +16,6 @@ class StrataHotel(Versioned, BaseModel): """Strata Hotel""" - class StrataHotelCategory(BaseEnum): - """Enum of the strata hotel category.""" - - FULL_SERVICE = auto() # pylint: disable=invalid-name - MULTI_UNIT_NON_PR = auto() # pylint: disable=invalid-name - POST_DECEMBER_2023 = auto() # pylint: disable=invalid-name - __tablename__ = "strata_hotels" id = db.Column(db.Integer, primary_key=True, autoincrement=True) diff --git a/strr-api/src/strr_api/requests/RegistrationRequest.py b/strr-api/src/strr_api/requests/RegistrationRequest.py index f5c5975e..eb40ff29 100644 --- a/strr-api/src/strr_api/requests/RegistrationRequest.py +++ b/strr-api/src/strr_api/requests/RegistrationRequest.py @@ -124,6 +124,7 @@ def __init__( blExemptReason=None, strataHotelRegistrationNumber=None, prExemptReason=None, + strataHotelCategory=None, ): self.propertyType = propertyType self.ownershipType = ownershipType @@ -137,6 +138,7 @@ def __init__( self.blExemptReason = blExemptReason self.strataHotelRegistrationNumber = strataHotelRegistrationNumber self.prExemptReason = prExemptReason + self.strataHotelCategory = strataHotelCategory class MailingAddress: diff --git a/strr-api/src/strr_api/responses/RegistrationSerializer.py b/strr-api/src/strr_api/responses/RegistrationSerializer.py index 8969a5d8..b2de3cf8 100644 --- a/strr-api/src/strr_api/responses/RegistrationSerializer.py +++ b/strr-api/src/strr_api/responses/RegistrationSerializer.py @@ -276,6 +276,7 @@ def populate_host_registration_details(cls, registration_data: dict, registratio "numberOfRoomsForRent": registration.rental_property.number_of_rooms_for_rent, "strataHotelRegistrationNumber": registration.rental_property.strata_hotel_registration_number, "prExemptReason": registration.rental_property.pr_exempt_reason, + "strataHotelCategory": registration.rental_property.strata_hotel_category, } registration_data["listingDetails"] = [ diff --git a/strr-api/src/strr_api/schemas/schemas/host-registration.json b/strr-api/src/strr_api/schemas/schemas/host-registration.json index 2652ea66..3c7192b5 100644 --- a/strr-api/src/strr_api/schemas/schemas/host-registration.json +++ b/strr-api/src/strr_api/schemas/schemas/host-registration.json @@ -184,6 +184,14 @@ "FARM_LAND", "FRACTIONAL_OWNERSHIP" ] + }, + "strataHotelCategory": { + "type": "string", + "enum": [ + "FULL_SERVICE", + "MULTI_UNIT_NON_PR", + "POST_DECEMBER_2023" + ] } }, "required": [ diff --git a/strr-api/src/strr_api/services/registration_service.py b/strr-api/src/strr_api/services/registration_service.py index b9cb1df3..22882167 100644 --- a/strr-api/src/strr_api/services/registration_service.py +++ b/strr-api/src/strr_api/services/registration_service.py @@ -299,6 +299,7 @@ def _create_host_registration(cls, registration_request: dict) -> RentalProperty pr_exempt_reason=registration_request.unitDetails.prExemptReason, property_listings=[PropertyListing(url=listing.url) for listing in registration_request.listingDetails], strata_hotel_registration_number=registration_request.unitDetails.strataHotelRegistrationNumber, + strata_hotel_category=registration_request.unitDetails.strataHotelCategory, ) if property_manager_info := registration_request.propertyManager: diff --git a/strr-api/tests/mocks/json/host_registration.json b/strr-api/tests/mocks/json/host_registration.json index f75200c9..0e9e299b 100644 --- a/strr-api/tests/mocks/json/host_registration.json +++ b/strr-api/tests/mocks/json/host_registration.json @@ -73,7 +73,8 @@ "isUnitOnPrincipalResidenceProperty": true, "numberOfRoomsForRent": 1, "prExemptReason": "FRACTIONAL_OWNERSHIP", - "blExemptReason": "This short-term rental does not offer bookings of under 30 days" + "blExemptReason": "This short-term rental does not offer bookings of under 30 days", + "strataHotelCategory": "MULTI_UNIT_NON_PR" }, "listingDetails": [ { diff --git a/strr-api/tests/postman/strr-api.postman_collection.json b/strr-api/tests/postman/strr-api.postman_collection.json index 19d635d1..f1b305b7 100644 --- a/strr-api/tests/postman/strr-api.postman_collection.json +++ b/strr-api/tests/postman/strr-api.postman_collection.json @@ -51,7 +51,7 @@ ], "body": { "mode": "raw", - "raw": "{\n \"header\": {\n \"paymentMethod\": \"DIRECT_PAY\"\n },\n \"registration\": {\n \"registrationType\": \"HOST\",\n \"primaryContact\": {\n \"firstName\": \"The\",\n \"middleName\": \"First\",\n \"lastName\": \"Guy\",\n \"dateOfBirth\": \"1986-10-23\",\n \"preferredName\": \"Mickey\",\n \"phoneCountryCode\": \"001\",\n \"phoneNumber\": \"604-999-9999\",\n \"extension\": \"x64\",\n \"faxNumber\": \"604-777-7777\",\n \"emailAddress\": \"test@test.test\",\n \"socialInsuranceNumber\":\"123 222 333\",\n \"mailingAddress\": {\n \"country\": \"CA\",\n \"address\": \"12766 227st\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 6K6\"\n }\n },\n \"secondaryContact\": {\n \"firstName\": \"The\",\n \"middleName\": \"Other\",\n \"lastName\": \"Guy\",\n \"dateOfBirth\": \"1986-10-23\",\n \"preferredName\": \"Mouse\",\n \"phoneCountryCode\": \"001\",\n \"phoneNumber\": \"604-888-8888\",\n \"extension\": \"\",\n \"faxNumber\": \"\",\n \"emailAddress\": \"test2@test.test\",\n \"mailingAddress\": {\n \"country\": \"CA\",\n \"address\": \"12766 227st\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 6K6\"\n }\n },\n \"unitAddress\": {\n \"nickname\": \"My Rental Property\",\n \"country\": \"CA\",\n \"unitNumber\": \"\",\n \"streetNumber\": \"12166\",\n \"streetName\": \"GREENWELL ST MAPLE RIDGE\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 7N1\"\n },\n \"strRequirements\": {\n \"isBusinessLicenceRequired\": false,\n \"isPrincipalResidenceRequired\": true,\n \"isStrProhibited\": false,\n \"isStraaExempt\": null,\n \"organizationNm\": \"City of Maple Ridge\"\n },\n \"unitDetails\": {\n \"parcelIdentifier\": \"000-460-991\",\n \"businessLicense\": \"7777777\",\n \"businessLicenseExpiryDate\": \"2025-01-01\",\n \"propertyType\": \"SINGLE_FAMILY_HOME\",\n \"ownershipType\": \"OWN\",\n \"rentalUnitSpaceType\": \"ENTIRE_HOME\",\n \"hostResidence\": \"SAME_UNIT\",\n \"isUnitOnPrincipalResidenceProperty\": true,\n \"numberOfRoomsForRent\": 1,\n \"blExemptReason\": \"This short-term rental does not offer bookings of under 30 days\",\n \"prExemptReason\": \"FRACTIONAL_OWNERSHIP\"\n },\n \"listingDetails\": [\n {\n \"url\": \"https://www.airbnb.ca/rooms/26359027\"\n }\n ],\n \"documents\": [\n {\n \"fileName\": \"Drivers License\",\n \"fileType\": \"pdf\",\n \"fileKey\": \"a1234\",\n \"documentType\": \"BC_DRIVERS_LICENSE\"\n }\n ]\n }\n}", + "raw": "{\n \"header\": {\n \"paymentMethod\": \"DIRECT_PAY\"\n },\n \"registration\": {\n \"registrationType\": \"HOST\",\n \"primaryContact\": {\n \"firstName\": \"The\",\n \"middleName\": \"First\",\n \"lastName\": \"Guy\",\n \"dateOfBirth\": \"1986-10-23\",\n \"preferredName\": \"Mickey\",\n \"phoneCountryCode\": \"001\",\n \"phoneNumber\": \"604-999-9999\",\n \"extension\": \"x64\",\n \"faxNumber\": \"604-777-7777\",\n \"emailAddress\": \"test@test.test\",\n \"socialInsuranceNumber\":\"123 222 333\",\n \"mailingAddress\": {\n \"country\": \"CA\",\n \"address\": \"12766 227st\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 6K6\"\n }\n },\n \"secondaryContact\": {\n \"firstName\": \"The\",\n \"middleName\": \"Other\",\n \"lastName\": \"Guy\",\n \"dateOfBirth\": \"1986-10-23\",\n \"preferredName\": \"Mouse\",\n \"phoneCountryCode\": \"001\",\n \"phoneNumber\": \"604-888-8888\",\n \"extension\": \"\",\n \"faxNumber\": \"\",\n \"emailAddress\": \"test2@test.test\",\n \"mailingAddress\": {\n \"country\": \"CA\",\n \"address\": \"12766 227st\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 6K6\"\n }\n },\n \"unitAddress\": {\n \"nickname\": \"My Rental Property\",\n \"country\": \"CA\",\n \"unitNumber\": \"\",\n \"streetNumber\": \"12166\",\n \"streetName\": \"GREENWELL ST MAPLE RIDGE\",\n \"addressLineTwo\": \"\",\n \"city\": \"MAPLE RIDGE\",\n \"province\": \"BC\",\n \"postalCode\": \"V2X 7N1\"\n },\n \"strRequirements\": {\n \"isBusinessLicenceRequired\": false,\n \"isPrincipalResidenceRequired\": true,\n \"isStrProhibited\": false,\n \"isStraaExempt\": null,\n \"organizationNm\": \"City of Maple Ridge\"\n },\n \"unitDetails\": {\n \"parcelIdentifier\": \"000-460-991\",\n \"businessLicense\": \"7777777\",\n \"businessLicenseExpiryDate\": \"2025-01-01\",\n \"propertyType\": \"SINGLE_FAMILY_HOME\",\n \"ownershipType\": \"OWN\",\n \"rentalUnitSpaceType\": \"ENTIRE_HOME\",\n \"hostResidence\": \"SAME_UNIT\",\n \"isUnitOnPrincipalResidenceProperty\": true,\n \"numberOfRoomsForRent\": 1,\n \"strataHotelCategory\": \"MULTI_UNIT_NON_PR\",\n \"blExemptReason\": \"This short-term rental does not offer bookings of under 30 days\",\n \"prExemptReason\": \"FRACTIONAL_OWNERSHIP\"\n },\n \"listingDetails\": [\n {\n \"url\": \"https://www.airbnb.ca/rooms/26359027\"\n }\n ],\n \"documents\": [\n {\n \"fileName\": \"Drivers License\",\n \"fileType\": \"pdf\",\n \"fileKey\": \"a1234\",\n \"documentType\": \"BC_DRIVERS_LICENSE\"\n }\n ]\n }\n}", "options": { "raw": { "language": "json"