Example #1
0
    def put(self, application_guid):
        # save history
        temp_application = Application.find_by_guid(application_guid)
        history = temp_application.save_application_history()

        application = None
        is_json_updated = None
        is_application_updated = None
        try:
            # map only specific fields
            application = Application.find_by_guid(application_guid)

            is_note_updated = application.edit_note != request.json.get(
                "edit_note")

            if is_note_updated:
                application.edit_note = request.json.get("edit_note")

            json = request.json.get("json")

            is_json_updated = DeepDiff(
                json, application.json, ignore_order=True) != {}

            if is_json_updated:
                application.json["company_contact"] = json["company_contact"]
                application.process_well_sites_work_items(
                    json["well_sites"],
                    application.iterate_application_work_items_action)

            is_application_updated = is_note_updated or is_json_updated

        except MarshmallowError as e:
            history.delete()
            raise BadRequest(e)

        try:
            if is_application_updated:
                if is_json_updated:
                    flag_modified(application, "json")

                application.save()
            else:
                history.delete()
        except:
            history.delete()
            raise

        return application
Example #2
0
    def post(self, application_guid):
        application = Application.find_by_guid(application_guid)
        if not application:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        # Documents can only be uploaded for application's in the correct status or if its being done by an admin
        if application.application_status_code == 'WAIT_FOR_DOCS' or jwt.validate_roles(
            [ADMIN]):
            docs = request.json.get('documents', [])

            for doc in docs:
                new_doc = ApplicationDocument(
                    document_name=doc['document_name'],
                    object_store_path=doc['object_store_path'],
                    application_document_code='SUPPORTING_DOC')
                application.documents.append(new_doc)
                application.save()

            if request.json.get('confirm_final_documents'):
                app_status_change = ApplicationStatusChange(
                    application=application,
                    application_status_code='DOC_SUBMITTED',
                    note='Thank you for uploading the required documents.')
                app_status_change.save()

            return '', 204
        raise Unauthorized(
            'Not currently accepting documents on this application')
Example #3
0
    def get(self):
        wa_number = request.args.get('well_auth_number', type=int)
        operator_id = request.args.get('operator_id', None)
        application_guid = request.args.get('application_guid', None)

        wells = []

        if operator_id:
            wells = NominatedWellSite.find_by_operator_id(operator_id)

        if wa_number:
            wells = [NominatedWellSite.find_by_wa_number(wa_number)]

        if application_guid:

            application = Application.find_by_guid(application_guid)
            application_wells = [
                int(x['details']['well_authorization_number'])
                for x in application.json['well_sites']
            ]

            wells = NominatedWellSite.query.filter(
                NominatedWellSite.wa_number.in_(application_wells)).all()

        return wells
    def get(self, application_guid):
        application = Application.find_by_guid(application_guid)
        if application is None:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        return application.contracted_work('APPROVED', True)
Example #5
0
    def get(self, application_guid):
        application = Application.find_by_guid(application_guid)
        if application is None:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        return application
Example #6
0
    def post(self):
        data = AuthorizationResource.parser.parse_args()
        application_guid = data.get('application_guid')
        application = Application.find_by_guid(application_guid)
        otl_guid = uuid.uuid4()

        if application is None:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        html_content = f"""
        <table width="100%" style="font-size:12.0pt; color:#595959 " >
            <tr>
                <td>
                    You have requested access to the Dormant Sites Reclamation Program site to view information about an application (see Reference Number above).
                    <br/>
                    <br/>
                    Use the button below to access your application information and submit payment requests.
                    <br/>
                    This button can only be used once and access expires after four hours. If you need to access the application again, request another link on the website.
                </td> 
            </tr>   
            <tr>
                <td>
                <br/>
                    <table style="margin-left: auto; margin-right: auto;">
                        <tr>
                            <td style="border-radius: 2px;" bgcolor="#003366" >
                                <a href="{ONE_TIME_LINK_FRONTEND_URL(otl_guid)}" target="_blank" style="padding: 8px 12px; border: 1px solid #003366;border-radius: 2px;font-size: 14px; color: #ffffff;text-decoration: none;font-weight:bold;display: inline-block;">
                                    View Application             
                                </a>
                            </td>
                        </tr>
                    </table>
                <br/>
                </td>
            </tr>
		</table>"""

        with EmailService() as es:
            es.send_email_to_applicant(
                application,
                f"Dormant Site Reclamation Program – Access Request",
                html_content)

        current_app.logger.debug(f"This is a OTL: {otl_guid}")
        cache.set(
            str(otl_guid),
            application_guid,
            timeout=AuthorizationResource.ONE_TIME_PASSWORD_TIMEOUT_SECONDS)

        return "OK", 200
    def post(self, application_guid):
        application = Application.find_by_guid(application_guid)
        if not application:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        app_status_change = ApplicationStatusChange(
            application=application,
            application_status_code=request.json['application_status_code'],
            note=request.json['note'])
        app_status_change.save()

        return '', 204
Example #8
0
    def put(self, application_guid):
        application = Application.find_by_guid(application_guid)
        if application is None:
            raise NotFound(
                'No application was found matching the provided reference number'
            )

        try:
            review_json = request.json['review_json']
        except Exception as e:
            raise BadRequest(e)

        application.review_json = review_json
        application.save()

        return application
Example #9
0
    def get(self):
        liabilities = OGCDataService.getLiabilityPerWellDataFrame()

        application_guid = request.args.get('application_guid', None)

        if application_guid is not None:
            application = Application.find_by_guid(application_guid)
            application_wells = [
                int(x['details']['well_authorization_number'])
                for x in application.json['well_sites']
            ]

            liabilities = liabilities[
                liabilities['well_auth_number'].copy().isin(application_wells)]

        return liabilities.to_dict('records')
Example #10
0
    def get(self):
        token_guid = request.args.get('token', '')
        attachment = request.args.get('as_attachment', None)
        token_data = cache.get(DOWNLOAD_TOKEN(token_guid))
        cache.delete(DOWNLOAD_TOKEN(token_guid))
        current_app.logger.debug('redis_data' + str(token_data))

        if not token_data:
            raise BadRequest('Valid token required for download')

        # Generation token
        file_resp = None
        if token_data.get('generation', False):
            application = Application.find_by_guid(
                token_data['application_guid'])
            template_path = token_data['template_path']
            docgen_resp = DocumentGeneratorService.generate_document_and_stream_response(
                template_path, application.shared_cost_agreement_template_json,
                'pdf')
            headers = dict(docgen_resp.headers)
            headers[
                'Content-Disposition'] = f'attachment; filename=shared_cost_agreement_{application.company_name}.pdf'
            file_resp = Response(stream_with_context(
                docgen_resp.iter_content(chunk_size=2048)),
                                 headers=headers)

        # Download token
        else:
            document_guid = token_data['document_guid']
            app_doc = ApplicationDocument.query.filter_by(
                application_document_guid=document_guid).one_or_none()
            if not app_doc:
                raise NotFound(
                    'No document was found with the corresponding download token'
                )
            if attachment is not None:
                attach_style = True if attachment == 'true' else False
            else:
                attach_style = '.pdf' not in app_doc.document_name.lower()

            file_resp = ObjectStoreStorageService().download_file(
                path=app_doc.object_store_path,
                display_name=quote(app_doc.document_name),
                as_attachment=attach_style)

        return file_resp
Example #11
0
    def put(self, application_guid, work_id):
        # Ensure that this work item exists on this application.
        application = Application.find_by_guid(application_guid)
        validate_application_contracted_work(application, work_id)

        # Get the contracted work payment.
        payment = ContractedWorkPayment.find_by_work_id(work_id)
        if not payment:
            raise BadRequest(
                'Only contracted work items that have had information submitted can have their Interim Progress Report updated'
            )

        # Set the contracted work payment interim report.
        interim_report_data = request.json
        interim_report = interim_report_data['interim_report']
        payment.interim_report = interim_report

        payment.save()
        return '', 200
Example #12
0
    def put(self, application_guid, work_id):
        # Validate this contracted work item.
        application = Application.find_by_guid(application_guid)
        validate_application_contracted_work(application, work_id)

        # Get the contracted work payment.
        payment = ContractedWorkPayment.find_by_work_id(work_id)
        if not payment:
            raise BadRequest(
                'The applicant must submit payment information for this work item before its audit status can be changed'
            )

        # Update the contracted work payment's audit data.
        audit_data = request.json
        payment.audit_ind = audit_data['audit_ind']
        payment.audit_user = User().get_user_username()
        payment.audit_timestamp = datetime.utcnow()
        payment.save()

        return '', 200
    def post(self, application_guid):
        application = Application.find_by_guid(application_guid)
        work_ids = request.json['work_ids']
        validate_application_contracted_work(application, work_ids)

        payment_document_code = request.json['payment_document_code']
        if payment_document_code == 'FIRST_PRF':
            raise BadRequest(
                'First PRFs are created when an application\'s status is set to approved.'
            )

        try:
            doc = PaymentDocument(application=application,
                                  payment_document_code=payment_document_code,
                                  work_ids=work_ids)
            doc.save()

        except Exception as e:
            raise BadRequest(f'Failed to create the PRF: {e}')

        return doc, 201
Example #14
0
    def post(self):
        applications_disabled = DSRPSettings.find_by_setting(
            DISABLE_APP_SUBMIT_SETTING).setting_value
        if applications_disabled:
            raise BadRequest(
                "Application Submissions are disabled at this time.")

        try:
            application_json = request.json['application']
            application_json[
                'application_phase_code'] = CURRENT_APPLICATION_PHASE_CODE
            application = Application._schema().load(application_json)
            application.submitter_ip = request.headers.getlist(
                'X-Forwarded-For')[0] if request.headers.getlist(
                    'X-Forwarded-For') else request.remote_addr
            application.save()
        except MarshmallowError as e:
            raise BadRequest(e)

        application.send_confirmation_email()

        return application, 201
    def get(self):
        operator_id = request.args.get('operator_id', None)
        well_auth_number = request.args.get('well_auth_number', None)
        application_guid = request.args.get('application_guid', None)

        wells = OGCDataService.getDormantWellsDataFrame()

        if operator_id:
            wells = wells[wells['operator_id'] == int(operator_id)]

        if well_auth_number:
            wells = wells[wells['well_auth_number'] == int(well_auth_number)]

        if application_guid:
            application = Application.find_by_guid(application_guid)
            application_wells = [
                int(x['details']['well_authorization_number'])
                for x in application.json['well_sites']
            ]

            wells = wells[wells['well_auth_number'].copy().isin(
                application_wells)]

        return wells.to_dict('records')
    def get(self):
        # Get all approved contracted work items on all approved applications
        application_id = request.args.get('application_id', type=int)
        application_guid = request.args.get('application_guid', type=str)
        company_name = request.args.get('company_name', type=str)
        all_approved_contracted_work = Application.all_approved_contracted_work(
            application_id, application_guid, company_name)

        # Get pagination/sorting query params
        page_number = request.args.get('page', DEFAULT_PAGE_NUMBER, type=int)
        page_size = request.args.get('per_page', DEFAULT_PAGE_SIZE, type=int)
        sort_field = request.args.get('sort_field',
                                      'review_deadlines',
                                      type=str)
        sort_dir = request.args.get('sort_dir', 'asc', type=str)

        # Get filtering query params
        work_id = request.args.get('work_id', type=str)
        well_authorization_number = request.args.get(
            'well_authorization_number', type=str)
        contracted_work_type = request.args.getlist('contracted_work_type',
                                                    type=str)
        interim_payment_status_code = request.args.getlist(
            'interim_payment_status_code', type=str)
        final_payment_status_code = request.args.getlist(
            'final_payment_status_code', type=str)
        application_phase_code = request.args.getlist('application_phase_code',
                                                      type=str)

        # Apply filtering
        records = all_approved_contracted_work
        if (work_id or well_authorization_number or contracted_work_type
                or interim_payment_status_code or final_payment_status_code
                or application_phase_code):
            records = []
            for approved_work in all_approved_contracted_work:

                if work_id:
                    if approved_work['work_id'] == work_id:
                        records.append(approved_work)
                        break
                    continue

                if well_authorization_number and approved_work[
                        'well_authorization_number'] != well_authorization_number:
                    continue

                if contracted_work_type and approved_work[
                        'contracted_work_type'] not in contracted_work_type:
                    continue

                contracted_work_payment = approved_work.get(
                    'contracted_work_payment', None)

                interim_status = 'INFORMATION_REQUIRED' if not contracted_work_payment else contracted_work_payment[
                    'interim_payment_status_code']
                final_status = 'INFORMATION_REQUIRED' if not contracted_work_payment else contracted_work_payment[
                    'final_payment_status_code']

                if interim_payment_status_code and final_payment_status_code:
                    if interim_status not in interim_payment_status_code and final_status not in final_payment_status_code:
                        continue
                else:
                    if interim_payment_status_code and interim_status not in interim_payment_status_code:
                        continue
                    if final_payment_status_code and final_status not in final_payment_status_code:
                        continue

                if application_phase_code and approved_work[
                        'application_phase_code'] not in application_phase_code:
                    continue

                records.append(approved_work)

        # Apply sorting
        reverse = sort_dir == 'desc'
        if sort_field == 'well_authorization_number':
            records.sort(key=lambda x: int(x[sort_field]), reverse=reverse)
        elif sort_field == 'work_id':
            records.sort(
                key=lambda x:
                (x['application_id'], int(x[sort_field].split('.')[1])),
                reverse=reverse)
        elif sort_field in ('application_id', 'work_id',
                            'contracted_work_type', 'company_name',
                            'application_phase_code'):
            records.sort(key=lambda x: x[sort_field], reverse=reverse)
        elif sort_field in ('review_deadlines'):
            records.sort(
                key=lambda x:
                (x.get('contracted_work_payment') and
                 (x['contracted_work_payment'][sort_field] and (
                     (x['contracted_work_payment'][sort_field]['interim'], x[
                         'contracted_work_payment'][sort_field]['final'])
                     if x['contracted_work_payment'][sort_field]['interim'] <=
                     x['contracted_work_payment'][sort_field]['final'] else
                     (x['contracted_work_payment'][sort_field]['final'],
                      x['contracted_work_payment'][sort_field]['interim']))) or
                 (REVIEW_DEADLINE_NOT_APPLICABLE,
                  REVIEW_DEADLINE_NOT_APPLICABLE)),
                reverse=reverse)
        elif sort_field in ('interim_payment_status_code',
                            'final_payment_status_code'):
            records.sort(key=lambda x: (x.get('contracted_work_payment') and x[
                'contracted_work_payment'][sort_field]) or
                         'INFORMATION_REQUIRED',
                         reverse=reverse)

        # Return records with pagination applied
        return apply_pagination_to_records(records, page_number, page_size)
Example #17
0
    def post(self, application_guid, work_id):
        # Validate this contracted work item.
        application = Application.find_by_guid(application_guid)
        validate_application_contracted_work(application, work_id)

        # Get the payment status change data.
        payment_status_data = request.json

        # Validate the contracted work payment code.
        contracted_work_payment_code = payment_status_data[
            'contracted_work_payment_code']
        prefix = contracted_work_payment_code.lower()
        if not ContractedWorkPaymentType.find_by_code(
                contracted_work_payment_code):
            raise BadRequest('Unknown contracted work payment code received!')

        # Validate the contracted work payment status code.
        contracted_work_payment_status_code = payment_status_data[
            f'{prefix}_payment_status_code']
        if not ContractedWorkPaymentStatus.find_by_code(
                contracted_work_payment_status_code):
            raise BadRequest(
                'Unknown contracted work payment status code received!')

        # Get the contracted work payment.
        payment = ContractedWorkPayment.find_by_work_id(work_id)
        if not payment:
            raise BadRequest(
                'The applicant must submit payment information for this work item before its status can be changed'
            )

        # Validate the request to change the final payment status to approved.
        if contracted_work_payment_code == 'FINAL' and contracted_work_payment_status_code == 'APPROVED':
            if payment.interim_payment_status_code != 'APPROVED':
                raise BadRequest('The interim payment must first be approved!')
            if not payment.interim_paid_amount:
                raise BadRequest(
                    'The interim payment must have an approved amount set!')
            if not payment.interim_report:
                raise BadRequest(
                    'The interim progress report must be provided!')

        note = payment_status_data.get(f'{prefix}_note', None)
        if contracted_work_payment_status_code == 'APPROVED':
            approved_amount = payment_status_data[f'{prefix}_approved_amount']
            if not approved_amount:
                raise BadRequest('The amount to approve must be provided!')

            if contracted_work_payment_code == 'INTERIM':
                payment.interim_paid_amount = approved_amount
            else:
                payment.final_paid_amount = approved_amount

        elif contracted_work_payment_status_code == 'READY_FOR_REVIEW':
            pass
        elif contracted_work_payment_status_code == 'INFORMATION_REQUIRED':
            if not note:
                BadRequest('A note is mandatory for this status!')
        else:
            raise BadRequest(
                'Unknown contracted work payment status code received!')

        status_change = ContractedWorkPaymentStatusChange(
            contracted_work_payment=payment,
            application=application,
            contracted_work_payment_status_code=
            contracted_work_payment_status_code,
            contracted_work_payment_code=contracted_work_payment_code,
            note=note)
        payment.status_changes.append(status_change)

        payment.save()
        return '', 201
Example #18
0
    def put(self, application_guid, work_id):
        response_code = 200

        # Ensure that this work item exists on this application.
        application = Application.find_by_guid(application_guid)
        validate_application_contracted_work(application, work_id)

        # Get the contracted work payment or create it if it doesn't exist.
        payment = ContractedWorkPayment.find_by_work_id(work_id)
        if not payment:
            payment = ContractedWorkPayment(
                application=application,
                application_guid=application_guid,
                work_id=work_id,
                contracted_work_payment_status_code='READY_FOR_REVIEW',
                contracted_work_payment_code='INTERIM')
            response_code = 201
        else:
            # Applicants can only update existing contracted work payments that are in the Information Required status.
            if payment.interim_payment_status_code != 'INFORMATION_REQUIRED':
                raise BadRequest(
                    'Only contracted work payments with the status Information Required can be modified'
                )
            status_change = ContractedWorkPaymentStatusChange(
                contracted_work_payment=payment,
                application=application,
                contracted_work_payment_status_code='READY_FOR_REVIEW',
                contracted_work_payment_code='INTERIM')
            payment.status_changes.append(status_change)

        # Update the required data points.
        interim_payment_data = request.json
        payment.interim_total_hours_worked_to_date = interim_payment_data[
            'interim_total_hours_worked_to_date']
        payment.interim_number_of_workers = interim_payment_data[
            'interim_number_of_workers']
        payment.interim_actual_cost = interim_payment_data[
            'interim_actual_cost']
        payment.interim_submitter_name = interim_payment_data[
            'interim_submitter_name']

        # The interim report is optional at this step.
        interim_report = interim_payment_data.get('interim_report')
        if interim_report:
            payment.interim_report = interim_report

        # The EoC is only required if it hasn't been provided yet.
        interim_eoc_data = interim_payment_data.get('interim_eoc', [None])[0]
        if not interim_eoc_data and not payment.interim_eoc_document:
            raise BadRequest('Evidence of Cost is required!')

        # Create the EoC document and soft-delete the existing one (if it exists).
        if interim_eoc_data:
            if payment.interim_eoc_document:
                payment.interim_eoc_document.active_ind = False
            filename = ApplicationDocument.create_filename(
                application, payment.work_id, 'INTERIM_EOC', 'pdf')
            interim_eoc = ApplicationDocument(
                document_name=filename,
                object_store_path=interim_eoc_data['key'],
                application_document_code='INTERIM_EOC')
            application.documents.append(interim_eoc)
            application.save()
            payment.interim_eoc_application_document_guid = interim_eoc.application_document_guid

        payment.save()
        return '', response_code
Example #19
0
    def put(self, application_guid, work_id):
        response_code = 200

        # Ensure that this work item exists on this application.
        application = Application.find_by_guid(application_guid)
        validate_application_contracted_work(application, work_id)

        # Get the contracted work payment or create it if it doesn't exist.
        payment = ContractedWorkPayment.find_by_work_id(work_id)
        if not payment:
            payment = ContractedWorkPayment(
                application=application,
                application_guid=application_guid,
                work_id=work_id,
                contracted_work_payment_status_code='READY_FOR_REVIEW',
                contracted_work_payment_code='FINAL')
            response_code = 201
        else:
            # Applicants can only update existing contracted work payments that are in the Information Required status.
            if payment.final_payment_status_code != 'INFORMATION_REQUIRED':
                raise BadRequest(
                    'Only contracted work payments with the status Information Required can be modified'
                )
            status_change = ContractedWorkPaymentStatusChange(
                contracted_work_payment=payment,
                application=application,
                contracted_work_payment_status_code='READY_FOR_REVIEW',
                contracted_work_payment_code='FINAL')
            payment.status_changes.append(status_change)

        # Update the required data points.
        final_payment_data = request.json
        payment.final_total_hours_worked_to_date = final_payment_data[
            'final_total_hours_worked_to_date']
        payment.final_number_of_workers = final_payment_data[
            'final_number_of_workers']
        payment.final_actual_cost = final_payment_data['final_actual_cost']
        payment.work_completion_date = final_payment_data[
            'work_completion_date']
        payment.final_submitter_name = final_payment_data[
            'final_submitter_name']

        # Update the general reporting data point "surface landowner".
        surface_landowner = final_payment_data['surface_landowner']
        if surface_landowner not in ('Crown', 'Freehold', 'Both'):
            raise BadRequest('Unknown "surface landowner" value received!')
        payment.surface_landowner = surface_landowner

        # Update the work-type specific reporting data points.
        contracted_work_type = application.find_contracted_work_type_by_work_id(
            payment.work_id)

        def parseBool(value):
            if isinstance(value, bool):
                return value
            if value not in ('true', 'false'):
                raise BadRequest(f'{value} is not a valid boolean value')
            return value == 'true'

        # Update the general reporting data point "reclamation was achieved".
        payment.reclamation_was_achieved = parseBool(
            final_payment_data['reclamation_was_achieved'])

        # Abandonment reporting
        if contracted_work_type == 'abandonment':
            payment.abandonment_cut_and_capped_completed = parseBool(
                final_payment_data['abandonment_cut_and_capped_completed'])

            payment.abandonment_notice_of_operations_submitted = parseBool(
                final_payment_data[
                    'abandonment_notice_of_operations_submitted'])

            abandonment_was_pipeline_abandoned = parseBool(
                final_payment_data['abandonment_was_pipeline_abandoned'])
            payment.abandonment_was_pipeline_abandoned = abandonment_was_pipeline_abandoned
            if abandonment_was_pipeline_abandoned:
                payment.abandonment_metres_of_pipeline_abandoned = int(
                    final_payment_data[
                        'abandonment_metres_of_pipeline_abandoned'])

        # Reclamation reporting
        elif contracted_work_type == 'reclamation':
            payment.reclamation_reclaimed_to_meet_cor_p2_requirements = parseBool(
                final_payment_data[
                    'reclamation_reclaimed_to_meet_cor_p2_requirements'])

            payment.reclamation_surface_reclamation_criteria_met = parseBool(
                final_payment_data[
                    'reclamation_surface_reclamation_criteria_met'])

        # Remediation reporting
        elif contracted_work_type == 'remediation':
            remediation_type_of_document_submitted = final_payment_data[
                'remediation_type_of_document_submitted']
            if remediation_type_of_document_submitted not in ('COR_P1', 'DSAF',
                                                              'NONE'):
                raise BadRequest(
                    'Unknown "remediation type of document submitted" value received!'
                )
            payment.remediation_type_of_document_submitted = remediation_type_of_document_submitted

            payment.remediation_identified_contamination_meets_standards = parseBool(
                final_payment_data[
                    'remediation_identified_contamination_meets_standards'])

            payment.remediation_reclaimed_to_meet_cor_p1_requirements = parseBool(
                final_payment_data[
                    'remediation_reclaimed_to_meet_cor_p1_requirements'])

        # Site investigation reporting
        elif contracted_work_type in ('preliminary_site_investigation',
                                      'detailed_site_investigation'):
            site_investigation_type_of_document_submitted = final_payment_data[
                'site_investigation_type_of_document_submitted']
            if site_investigation_type_of_document_submitted not in ('COR_P1',
                                                                     'DSAF',
                                                                     'NONE'):
                raise BadRequest(
                    'Unknown "site investigation type of document submitted" value received!'
                )
            payment.site_investigation_type_of_document_submitted = site_investigation_type_of_document_submitted

            payment.site_investigation_concerns_identified = parseBool(
                final_payment_data['site_investigation_concerns_identified'])

        # The EoC is only required if it hasn't been provided yet.
        final_eoc_data = final_payment_data.get('final_eoc', [None])[0]
        if not final_payment_data.get('final_eoc',
                                      None) and not payment.final_eoc_document:
            raise BadRequest('Evidence of Cost is required!')

        # Create the EoC document and soft-delete the existing one (if it exists).
        if final_eoc_data:
            if payment.final_eoc_document:
                payment.final_eoc_document.active_ind = False
            filename = ApplicationDocument.create_filename(
                application, payment.work_id, 'FINAL_EOC', 'pdf')
            final_eoc = ApplicationDocument(
                document_name=filename,
                object_store_path=final_eoc_data['key'],
                application_document_code='FINAL_EOC')
            application.documents.append(final_eoc)
            application.save()
            payment.final_eoc_application_document_guid = final_eoc.application_document_guid

        # The Final Report is only required if it hasn't been provided yet.
        final_report_data = final_payment_data.get('final_report', [None])[0]
        if not final_report_data and not payment.final_report_document:
            raise BadRequest('Final Report is required!')

        # Create the Final Report document and soft-delete the existing one (if it exists).
        if final_report_data:
            if payment.final_report_document:
                payment.final_report_document.active_ind = False
            filename = ApplicationDocument.create_filename(
                application, payment.work_id, 'FINAL_REPORT', 'pdf')
            final_report = ApplicationDocument(
                document_name=filename,
                object_store_path=final_report_data['key'],
                application_document_code='FINAL_REPORT')
            application.documents.append(final_report)
            application.save()
            payment.final_report_application_document_guid = final_report.application_document_guid

        payment.save()
        return '', response_code