diff --git a/jobs/furnishings/src/furnishings/stage_processors/post_processor.py b/jobs/furnishings/src/furnishings/stage_processors/post_processor.py index aac46a168..952bb734a 100644 --- a/jobs/furnishings/src/furnishings/stage_processors/post_processor.py +++ b/jobs/furnishings/src/furnishings/stage_processors/post_processor.py @@ -77,7 +77,10 @@ def _update_furnishings_status(self, furnishing_group_id): furnishing.save() def process(self): - """Postprocess to generate and upload file to external resources(BC Laws).""" + """Postprocess to generate and upload file to external resources (BC Laws).""" + if not self._furnishings_dict: + return + self._format_furnishings() self._app.logger.debug('Formatted furnishing details presented in XML file') self._set_meta_info() @@ -108,6 +111,16 @@ class XmlMeta: 'be dissolved under section 422 of the Business Corporations Act.' ) }, + Furnishing.FurnishingName.CORP_DISSOLVED: { + 'title': 'Dissolutions (B.C.)', + 'category': 'DISSOLUTIONS', + 'subcategory': 'B.C.', + 'corp_class': 'BC Company(s)', + 'description': ( + 'The Registrar of Companies hereby gives notice the following companies were dissolved under ' + 'section 317, 422 or 423 of the Business Corporations Act.' + ) + }, } @staticmethod diff --git a/jobs/furnishings/src/furnishings/stage_processors/stage_three.py b/jobs/furnishings/src/furnishings/stage_processors/stage_three.py index f5d176729..ffee4e4d5 100644 --- a/jobs/furnishings/src/furnishings/stage_processors/stage_three.py +++ b/jobs/furnishings/src/furnishings/stage_processors/stage_three.py @@ -19,10 +19,18 @@ from sqlalchemy import exists, not_ -def process(app: Flask): +def process(app: Flask, xml_furnishings: dict): """Run process to manage and track notifications for dissolution stage three process.""" try: - furnishing_subquery = exists().where( + has_stage_2_furnishing = exists().where( + Furnishing.batch_id == BatchProcessing.batch_id, + Furnishing.business_id == BatchProcessing.business_id, + Furnishing.furnishing_name.in_([ + Furnishing.FurnishingName.INTENT_TO_DISSOLVE, + Furnishing.FurnishingName.INTENT_TO_DISSOLVE_XPRO + ]) + ) + has_stage_3_furnishing = exists().where( Furnishing.batch_id == BatchProcessing.batch_id, Furnishing.business_id == BatchProcessing.business_id, Furnishing.furnishing_name.in_([ @@ -32,15 +40,15 @@ def process(app: Flask): ) batch_processings = ( db.session.query(BatchProcessing) - .filter(BatchProcessing.status == BatchProcessing.BatchProcessingStatus.PROCESSING) + .filter(BatchProcessing.status == BatchProcessing.BatchProcessingStatus.COMPLETED) .filter(BatchProcessing.step == BatchProcessing.BatchProcessingStep.DISSOLUTION) .filter(Batch.id == BatchProcessing.batch_id) .filter(Batch.batch_type == Batch.BatchType.INVOLUNTARY_DISSOLUTION) - .filter(Batch.status == Batch.BatchStatus.PROCESSING) - .filter(not_(furnishing_subquery)) + .filter(has_stage_2_furnishing) + .filter(not_(has_stage_3_furnishing)) ).all() - furnishing_group_id = Furnishing.get_next_furnishing_group_id() + bc_furnishings = [] for batch_processing in batch_processings: business = batch_processing.business @@ -58,13 +66,16 @@ def process(app: Flask): created_date=datetime.utcnow(), last_modified=datetime.utcnow(), status=Furnishing.FurnishingStatus.QUEUED, - furnishing_group_id=furnishing_group_id, business_name=business.legal_name ) new_furnishing.save() app.logger.debug(f'Created corp dissolved furnishing entry with ID: {new_furnishing.id}') - # TODO: create data files and SFTPing to BC Laws - # TODO: mark furnishings entry processed + + if business != Business.LegalTypes.EXTRA_PRO_A.value: + bc_furnishings.append(new_furnishing) + + if bc_furnishings: + xml_furnishings[Furnishing.FurnishingName.CORP_DISSOLVED] = bc_furnishings except Exception as err: app.logger.error(err) diff --git a/jobs/furnishings/src/furnishings/stage_processors/stage_two.py b/jobs/furnishings/src/furnishings/stage_processors/stage_two.py index a7b8756f7..fd8b7a7cd 100644 --- a/jobs/furnishings/src/furnishings/stage_processors/stage_two.py +++ b/jobs/furnishings/src/furnishings/stage_processors/stage_two.py @@ -66,7 +66,8 @@ def process(app: Flask, xml_furnishings: dict): if business != Business.LegalTypes.EXTRA_PRO_A.value: bc_furnishings.append(new_furnishing) - xml_furnishings[Furnishing.FurnishingName.INTENT_TO_DISSOLVE] = bc_furnishings + if bc_furnishings: + xml_furnishings[Furnishing.FurnishingName.INTENT_TO_DISSOLVE] = bc_furnishings except Exception as err: app.logger.error(err) diff --git a/jobs/furnishings/src/furnishings/worker.py b/jobs/furnishings/src/furnishings/worker.py index 7b58c5204..dba526a98 100644 --- a/jobs/furnishings/src/furnishings/worker.py +++ b/jobs/furnishings/src/furnishings/worker.py @@ -126,7 +126,7 @@ async def run(application: Flask, qsm: QueueService): # pylint: disable=redefin application.logger.debug('Exiting stage 2 of furnishings job.') if stage_3_valid: application.logger.debug('Entering stage 3 of furnishings job.') - stage_three.process(application) + stage_three.process(application, xml_furnishings_dict) application.logger.debug('Exiting stage 3 of furnishings job.') post_processor.process(application, xml_furnishings_dict) diff --git a/jobs/furnishings/tests/unit/stage_processors/test_post_processor.py b/jobs/furnishings/tests/unit/stage_processors/test_post_processor.py index 8bfded5e8..05533e042 100644 --- a/jobs/furnishings/tests/unit/stage_processors/test_post_processor.py +++ b/jobs/furnishings/tests/unit/stage_processors/test_post_processor.py @@ -11,6 +11,8 @@ # 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. +import pytest + from legal_api.models import BatchProcessing, Furnishing, FurnishingGroup, XmlPayload from furnishings.stage_processors.post_processor import PostProcessor, process @@ -18,7 +20,7 @@ from .. import factory_batch, factory_batch_processing, factory_business, factory_furnishing -def helper_create_furnishings(identifiers: list): +def helper_create_furnishings(identifiers: list, furnishing_name, step): """Test helper to create furnishings for post processing.""" furnishings = [] for identifier in identifiers: @@ -28,25 +30,38 @@ def helper_create_furnishings(identifiers: list): batch_id=batch.id, business_id=business.id, identifier=business.identifier, - step=BatchProcessing.BatchProcessingStep.WARNING_LEVEL_2 + step=step ) furnishing = factory_furnishing( batch_id=batch.id, business_id=business.id, identifier=business.identifier, - furnishing_name=Furnishing.FurnishingName.INTENT_TO_DISSOLVE, + furnishing_name=furnishing_name, furnishing_type=Furnishing.FurnishingType.GAZETTE, business_name=business.legal_name ) furnishings.append(furnishing) return furnishings - -def test_process(app, session): +@pytest.mark.parametrize( + 'test_name, furnishing_name, step', [ + ( + 'STAGE_2_BC', + Furnishing.FurnishingName.INTENT_TO_DISSOLVE, + BatchProcessing.BatchProcessingStep.WARNING_LEVEL_2 + ), + ( + 'STAGE_3_BC', + Furnishing.FurnishingName.CORP_DISSOLVED, + BatchProcessing.BatchProcessingStep.DISSOLUTION + ), + ] +) +def test_process(app, session, test_name, furnishing_name, step): """Assert that FurnishingGroup and XmlPayload entry are created correctly.""" - furnishings = helper_create_furnishings(['BC1234567']) + furnishings = helper_create_furnishings(['BC1234567'], furnishing_name, step) furnishing_dict = { - Furnishing.FurnishingName.INTENT_TO_DISSOLVE: furnishings + furnishing_name: furnishings } process(app, furnishing_dict) @@ -65,19 +80,79 @@ def test_process(app, session): assert xml_payload.payload -def test_processor_format_furnishings(app, session): +def test_process_combined_xml(app, session): + """Assert that FurnishingGroup and XmlPayload entry are created correctly for both stages at once.""" + furnishing_name_stage_2 = Furnishing.FurnishingName.INTENT_TO_DISSOLVE + furnishings_stage_2 = helper_create_furnishings( + ['BC2222222'], + furnishing_name_stage_2, + BatchProcessing.BatchProcessingStep.WARNING_LEVEL_2 + ) + + furnishing_name_stage_3 = Furnishing.FurnishingName.CORP_DISSOLVED + furnishings_stage_3 = helper_create_furnishings( + ['BC3333333'], + furnishing_name_stage_3, + BatchProcessing.BatchProcessingStep.DISSOLUTION + ) + + furnishing_dict = { + furnishing_name_stage_2: furnishings_stage_2, + furnishing_name_stage_3: furnishings_stage_3 + } + process(app, furnishing_dict) + + furnishing_stage_2 = furnishings_stage_2[0] + assert furnishing_stage_2.status == Furnishing.FurnishingStatus.PROCESSED + + furnishing_stage_3 = furnishings_stage_3[0] + assert furnishing_stage_3.status == Furnishing.FurnishingStatus.PROCESSED + + furnishing_group_id = furnishing_stage_2.furnishing_group_id + assert furnishing_group_id + assert furnishing_group_id == furnishing_stage_3.furnishing_group_id + furnishing_group = FurnishingGroup.find_by_id(furnishing_group_id) + assert furnishing_group + + xml_payload_id = furnishing_group.xml_payload_id + assert xml_payload_id + xml_payload = XmlPayload.find_by_id(xml_payload_id) + assert xml_payload + assert xml_payload.payload + + +@pytest.mark.parametrize( + 'test_name, furnishing_name, step', [ + ( + 'STAGE_2_BC', + Furnishing.FurnishingName.INTENT_TO_DISSOLVE, + BatchProcessing.BatchProcessingStep.WARNING_LEVEL_2 + ), + ( + 'STAGE_3_BC', + Furnishing.FurnishingName.CORP_DISSOLVED, + BatchProcessing.BatchProcessingStep.DISSOLUTION + ), + ] +) +def test_processor_format_furnishings(app, session, test_name, furnishing_name, step): """Assert that furnishing details are formated/sorted correctly.""" - furnishings = helper_create_furnishings(['BC7654321', 'BC1234567']) - name = Furnishing.FurnishingName.INTENT_TO_DISSOLVE + furnishings = helper_create_furnishings( + ['BC7654321', 'BC1234567'], + furnishing_name, + step + ) + furnishing_dict = { - name: furnishings + furnishing_name: furnishings, } processor = PostProcessor(app, furnishing_dict) processor._format_furnishings() assert processor._xml_data - assert processor._xml_data['furnishings'][name]['items'] - furnishing_items = processor._xml_data['furnishings'][name]['items'] + assert processor._xml_data['furnishings'][furnishing_name]['items'] + + furnishing_items = processor._xml_data['furnishings'][furnishing_name]['items'] assert furnishing_items[0] == furnishings[1] assert furnishing_items[1] == furnishings[0] diff --git a/jobs/furnishings/tests/unit/stage_processors/test_stage_three.py b/jobs/furnishings/tests/unit/stage_processors/test_stage_three.py index 8550a9816..d6c67123a 100644 --- a/jobs/furnishings/tests/unit/stage_processors/test_stage_three.py +++ b/jobs/furnishings/tests/unit/stage_processors/test_stage_three.py @@ -63,7 +63,20 @@ def test_process_create_furnishings(app, session, test_name, entity_type, step, batch_id=batch.id, business_id=business.id, identifier=business.identifier, - step=step + step=step, + status=BatchProcessing.BatchProcessingStatus.COMPLETED + ) + + #stage 2 furnishing + factory_furnishing( + batch_id=batch.id, + business_id=business.id, + identifier=business.identifier, + furnishing_name=Furnishing.FurnishingName.INTENT_TO_DISSOLVE, + furnishing_type=Furnishing.FurnishingType.GAZETTE, + created_date=datetime.utcnow()+datedelta(years=1), + last_modified=datetime.utcnow()+datedelta(years=1), + business_name=business.legal_name ) if test_name == 'STAGE_3_ALREADY_RUN': @@ -78,12 +91,12 @@ def test_process_create_furnishings(app, session, test_name, entity_type, step, business_name=business.legal_name ) - process(app) + process(app, {}) furnishings = Furnishing.find_by(business_id=business.id) if new_entry: - assert len(furnishings) == 1 - furnishing = furnishings[0] + assert len(furnishings) == 2 + furnishing = furnishings[1] assert furnishing.furnishing_type == Furnishing.FurnishingType.GAZETTE assert furnishing.business_name == business.legal_name if entity_type == Business.LegalTypes.EXTRA_PRO_A.value: @@ -92,8 +105,8 @@ def test_process_create_furnishings(app, session, test_name, entity_type, step, assert furnishing.furnishing_name == Furnishing.FurnishingName.CORP_DISSOLVED else: if test_name == 'STAGE_3_ALREADY_RUN': - assert len(furnishings) == 1 - furnishing = furnishings[0] + assert len(furnishings) == 2 + furnishing = furnishings[1] assert furnishing == existing_furnishing else: - assert len(furnishings) == 0 + assert len(furnishings) == 1