From e97d3fdf8406a4a93234fbbba975ad05d7392232 Mon Sep 17 00:00:00 2001 From: Chandra Y Date: Thu, 31 Oct 2024 12:54:35 -0500 Subject: [PATCH] WP-720: [APCD][React] Extension form submit hookup (#340) * Submit handling for extension * Add error message ui element * - Suggested styles changes for extension form (#342) * Update apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.tsx Co-authored-by: sophia-massie <96220951+sophia-massie@users.noreply.github.com> * Delete unused templates and css --------- Co-authored-by: sophia-massie <96220951+sophia-massie@users.noreply.github.com> --- .../forms/css/extension_submission_form.css | 47 --- .../extension_err_no_sub_id.html | 30 -- .../extension_form_success.html | 13 - .../extension_submission_error.html | 18 - apcd-cms/src/apps/extension/views.py | 28 +- apcd-cms/src/apps/utils/apcd_database.py | 40 +- .../Extensions/ExtensionFormInfo.module.css | 7 +- .../Extensions/ExtensionFormInfo.tsx | 149 +++---- .../Extensions/ExtensionsForm.module.css | 24 +- .../Submitter/Extensions/ExtensionsForm.tsx | 398 +++++++++++------- 10 files changed, 354 insertions(+), 400 deletions(-) delete mode 100644 apcd-cms/src/apps/extension/static/forms/css/extension_submission_form.css delete mode 100644 apcd-cms/src/apps/extension/templates/extension_submission_form/extension_err_no_sub_id.html delete mode 100644 apcd-cms/src/apps/extension/templates/extension_submission_form/extension_form_success.html delete mode 100644 apcd-cms/src/apps/extension/templates/extension_submission_form/extension_submission_error.html diff --git a/apcd-cms/src/apps/extension/static/forms/css/extension_submission_form.css b/apcd-cms/src/apps/extension/static/forms/css/extension_submission_form.css deleted file mode 100644 index 83b91f6c..00000000 --- a/apcd-cms/src/apps/extension/static/forms/css/extension_submission_form.css +++ /dev/null @@ -1,47 +0,0 @@ -/* Field Widths */ -select { - overflow: hidden; - white-space:pre; - text-overflow: ellipsis; - } - -/* to make submission date inputs the same size*/ -select[name^="applicable-data-period"] { - max-width: 20ch; -} -/* Text alignment */ -/* To make required text line up with helper text for justification text area*/ -#justification-asterisk { - padding-left: 0; - margin-left: 0; - } - - -/* Field Layouts */ -/* To put required for extension dates on another line to avoid cutting off text */ -label[name^="extension-date-asterisk"] { - padding: 0; - margin-left:0; -} -/* To make sure sup values are not cut off when set as a label*/ -label[name^="date-row"] { - margin-top: 1rem; -} -/* To make (radio/check)box sets take up less vertical space */ -#on-behalf-of { - display: flex; - flex-wrap: wrap; - column-gap: 1em; - row-gap: 0.5em; -} - -[id^="extension-block_"] { - - /* Expectations: - - automatically enough columns - - maximum column count of 3 (i.e. minimum column width of 33%) - - equal width columns*/ - display: grid; - grid-template-columns: repeat( auto-fill, var(--max-col-width)); - max-width: calc( var(--global-space--grid-gap) + var(--max-col-width) *3 ); -} diff --git a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_err_no_sub_id.html b/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_err_no_sub_id.html deleted file mode 100644 index cd4995b3..00000000 --- a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_err_no_sub_id.html +++ /dev/null @@ -1,30 +0,0 @@ -{% extends "standard.html" %} -{% load static %} - -{% block content %} - - - -
- {% include "nav_cms_breadcrumbs.html" %} - -
-
-

Request an Extension

-
- -

- This form should be completed and submitted by data submitters to request - an extension to the deadline for submitting either a regular submission or - a corrected resubmission. Please review the - Data Submission Guide for details about completing and submitting this form, especially - regarding the timeliness of the request. -

-
-

- We have not found a submitter code on file for your account. For assistance, please submit a ticket. -

- Go to Dashboard -
- {% endblock %} diff --git a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_form_success.html b/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_form_success.html deleted file mode 100644 index 7394bf76..00000000 --- a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_form_success.html +++ /dev/null @@ -1,13 +0,0 @@ -{% extends "standard.html" %} -{% block content %} -
- {% include "nav_cms_breadcrumbs.html" %} - -

Request to Submit Extension

-
-

- Your extension submission was successful. -

- Go to Dashboard -
-{% endblock %} diff --git a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_submission_error.html b/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_submission_error.html deleted file mode 100644 index 2ff06825..00000000 --- a/apcd-cms/src/apps/extension/templates/extension_submission_form/extension_submission_error.html +++ /dev/null @@ -1,18 +0,0 @@ -{% extends "standard.html" %} -{% block content %} - -{# TUP-175: Move to Core, Remove from Here #} -{% include 'snippets/tup-175-css-alerts-messages-ui-pattern.html' %} - -
- {% include "nav_cms_breadcrumbs.html" %} - -

Request to Submit Extension

-
-

- An error occurred during your extension request submission. For help, submit a ticket. -

- Go Back to Extensions -
- -{% endblock %} diff --git a/apcd-cms/src/apps/extension/views.py b/apcd-cms/src/apps/extension/views.py index a1a39f04..012ec4ba 100644 --- a/apcd-cms/src/apps/extension/views.py +++ b/apcd-cms/src/apps/extension/views.py @@ -5,6 +5,7 @@ from apps.utils.utils import title_case from datetime import datetime import logging +import json logger = logging.getLogger(__name__) @@ -46,30 +47,19 @@ def post(self, request): Handle form submission and return JSON response for success/failure """ if request.user.is_authenticated and has_apcd_group(request.user): - form = request.POST.copy() + form = json.loads(request.body) + extensions = form['extensions'] errors = [] - submitters = request.session.get('submitters') - - max_iterations = 1 - for i in range(2, 6): - # Check if subsequent fields are present to determine the number of iterations - if form.get(f'requested-target-date_{i}'): - max_iterations += 1 - else: - break - - # Process the form for each submitter - for iteration in range(max_iterations): - submitter = next( - submitter for submitter in submitters - if int(submitter[0]) == int(form[f'business-name_{iteration + 1}']) - ) - exten_resp = apcd_database.create_extension(form, iteration + 1, submitter) + submitters = apcd_database.get_submitter_info(request.user.username) + for extension in extensions: + submitter = next(submitter for submitter in submitters if int(submitter[0] == int(extension['businessName']))) + exten_resp = apcd_database.create_extension(form, extension, submitter) if self._err_msg(exten_resp): errors.append(self._err_msg(exten_resp)) # Return success or error as JSON if errors: + logger.error("Extension request failed. Errors: %s", errors) return JsonResponse({'status': 'error', 'errors': errors}, status=400) else: return JsonResponse({'status': 'success'}, status=200) @@ -78,7 +68,7 @@ def post(self, request): def _set_submitter(self, sub): """ - Helper function to structure the submitter info + Helper function to structure the submitter info """ return { "submitter_id": sub[0], diff --git a/apcd-cms/src/apps/utils/apcd_database.py b/apcd-cms/src/apps/utils/apcd_database.py index 68e19836..9bc51331 100644 --- a/apcd-cms/src/apps/utils/apcd_database.py +++ b/apcd-cms/src/apps/utils/apcd_database.py @@ -961,41 +961,25 @@ def get_all_submissions_and_logs(): if conn is not None: conn.close() -def create_extension(form, iteration, sub_data): +def create_extension(form, extension, sub_data): cur = None conn = None values = () try: - if iteration > 1: - values = ( - _clean_value(form['business-name_{}'.format(iteration)]), - _clean_date(form['requested-target-date_{}'.format(iteration)]), - _clean_value(form['extension-type_{}'.format(iteration)]), - int((form['applicable-data-period_{}'.format(iteration)].replace("-", ""))), - _clean_date(form['hidden-current-expected-date_{}'.format(iteration)]), - "pending", - _clean_value(sub_data[1]), - _clean_value(sub_data[2]), - _clean_value(sub_data[3]), - _clean_value(form["requestor-name"]), - _clean_email(form["requestor-email"]), - _clean_value(form["justification"]) - ) - else: - values = ( - _clean_value(form['business-name_{}'.format(iteration)]), - _clean_date(form['requested-target-date_{}'.format(iteration)]), - _clean_value(form['extension-type_{}'.format(iteration)]), - int((form['applicable-data-period_{}'.format(iteration)].replace("-", ""))), - _clean_date(form['hidden-current-expected-date_{}'.format(iteration)]), + values = ( + _clean_value(extension['businessName']), + _clean_value(extension['requestedTargetDate']), + _clean_value(extension['extensionType']), + _clean_value(extension['applicableDataPeriod'].replace("-", "")), + _clean_value(extension['currentExpectedDate']), "pending", _clean_value(sub_data[1]), _clean_value(sub_data[2]), _clean_value(sub_data[3]), - _clean_value(form["requestor-name"]), - _clean_email(form["requestor-email"]), + _clean_value(form["requestorName"]), + _clean_email(form["requestorEmail"]), _clean_value(form["justification"]) - ) + ) operation = """INSERT INTO extensions( submitter_id, @@ -1022,10 +1006,10 @@ def create_extension(form, iteration, sub_data): ) cur = conn.cursor() cur.execute(operation, values) - conn.commit() + conn.commit() except Exception as error: - logger.error(error) + logger.error('DB error related to extension request creation: %s', error) return error finally: diff --git a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.module.css b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.module.css index ec8ed4f2..ff3c2970 100644 --- a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.module.css +++ b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.module.css @@ -1,5 +1,8 @@ -.requiredText { - color: red; +.isInvalid { + width: 100%; /* To match error message styles from*/ + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; } .dateInputField { diff --git a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.tsx b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.tsx index 47c5e017..91ecbdde 100644 --- a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.tsx +++ b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionFormInfo.tsx @@ -1,23 +1,24 @@ import React from 'react'; -import { Field, ErrorMessage, FieldArray } from 'formik'; -import { FormGroup, Label, Row, Col, FormFeedback } from 'reactstrap'; +import { Field, ErrorMessage } from 'formik'; +import { FormGroup, Label } from 'reactstrap'; import styles from './ExtensionsForm.module.css'; import { SubmitterEntityData, Entities } from 'hooks/entities'; import SectionMessage from 'core-components/SectionMessage'; -import { Link, useLocation } from 'react-router-dom'; +import { Link } from 'react-router-dom'; const ExtensionFormInfo: React.FC<{ index: number; submitterData: SubmitterEntityData | undefined; }> = ({ index, submitterData }) => { return ( -
+ <> +

Extension Information {index + 1}

This extension is on behalf of the following organization:

- + {submitterData && ( <> @@ -25,7 +26,6 @@ const ExtensionFormInfo: React.FC<{ as="select" name={`extensions.${index}.businessName`} id={`extensions.${index}.businessName`} - className="form-control" > {submitterData?.submitters?.map((submitter: Entities) => ( @@ -39,7 +39,8 @@ const ExtensionFormInfo: React.FC<{ )} @@ -53,15 +54,14 @@ const ExtensionFormInfo: React.FC<{ )} - + @@ -72,81 +72,72 @@ const ExtensionFormInfo: React.FC<{
Submission Dates
- - - - - - - - - - Enter month and year - - - - - - + + + - - - - - + + + + +
Enter month and year
+ +
- - - - - - - -
+ + + + + -
-
+ + + + + +
+ ); }; diff --git a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.module.css b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.module.css index d166e647..e735f9e3 100644 --- a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.module.css +++ b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.module.css @@ -1,5 +1,8 @@ -.requiredText { - color: red; +.isInvalid { + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; } .dateInputField { @@ -18,3 +21,20 @@ height: 100%; width: 100%; } +.termsCheckbox input { + position: unset; + margin-left: 0; + margin-right: 2px; +} +.fieldRows { + display: flex; + gap: 5rem; + margin-top: 1rem; + margin-bottom: 1rem; +} +.fieldRows input { + font-size: inherit; +} +.justification { + font-size: unset; +} diff --git a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.tsx b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.tsx index 37d0cb15..3314b080 100644 --- a/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.tsx +++ b/apcd-cms/src/client/src/components/Submitter/Extensions/ExtensionsForm.tsx @@ -1,11 +1,14 @@ -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup'; -import { Button, Col, FormGroup, Label, Row, FormFeedback } from 'reactstrap'; +import { FormGroup, Label } from 'reactstrap'; import styles from './ExtensionsForm.module.css'; import ExtensionFormInfo from './ExtensionFormInfo'; import { useEntities } from 'hooks/entities'; +import { fetchUtil } from 'utils/fetchUtil'; import LoadingSpinner from 'core-components/LoadingSpinner'; +import SectionMessage from 'core-components/SectionMessage'; +import Button from 'core-components/Button'; const validationSchema = Yup.object().shape({ extensions: Yup.array().of( @@ -64,8 +67,40 @@ const initialValues: FormValues = { }; export const ExtensionRequestForm: React.FC = () => { - const handleSubmit = (values: FormValues) => { - console.log('Form values:', values); + const [errorMessage, setErrorMessage] = useState(''); + const [isSuccess, setIsSuccess] = useState(false); + + const handleSubmit = async ( + values: FormValues, + { setSubmitting }: { setSubmitting: (isSubmitting: boolean) => void } + ) => { + setErrorMessage(''); + const url = `submissions/extension/api/`; + try { + const response = await fetchUtil({ + url, + method: `POST`, + body: values, + }); + if (response.status == 'success') { + setIsSuccess(true); + } + } catch (error: any) { + console.error('Error saving data:', error); + console.log(url); + if (error.response && error.response.data) { + setErrorMessage( + error.response.data.message || + 'An error occurred while saving the data. Please try again.' + ); + } else { + setErrorMessage( + 'An error occurred while saving the data. Please try again.' + ); + } + } finally { + setSubmitting(false); + } }; const { @@ -84,170 +119,209 @@ export const ExtensionRequestForm: React.FC = () => { return ( <> -

Request an Extension

+

Request Extension


-

- This form should be completed and submitted by data submitters to - request an extension to the deadline for submitting either a regular - submission or a corrected resubmission. Please review the{' '} - - Data Submission Guide - {' '} - for details about completing and submitting this form, especially - regarding the timeliness of the request. -

- {({ values, isSubmitting, setFieldValue }) => ( -
- {values.extensions.map((extension, index) => ( - - ))} - {' '} - -
-

Request and Justification

- - - - - - 2000 character limit - - -
-

Acknowledgment of Terms

- - - - - - - - - - - - - - - - - -
-

- I understand and acknowledge that the Texas Department of - Insurance (TDI) may review the validity of the information - submitted on this form. -

- - - - - -
- -
- - 1Applicable data period - month/year in which claims - data was adjudicated. - -
- - 2Requested target date - requested day/month/year by - which the data should be received (the extension date). - -
- - 3Current expected date - day/month/year in which - applicable data was expected within the submission window. - - - )} + {({ values, isSubmitting, setFieldValue, resetForm }) => { + useEffect(() => { + if (isSuccess) { + resetForm(); + } + }, [isSuccess, resetForm]); + { + return ( + <> +

+ This form should be completed and submitted by data submitters + to request an extension to the deadline for submitting either + a regular submission or a corrected resubmission. Please + review the{' '} + + Data Submission Guide + {' '} + for details about completing and submitting this form, + especially regarding the timeliness of the request. +

+
+ {values.extensions.map((extension, index) => ( + + ))} + {' '} + +
+

Request and Justification

+

+ Provide rationale for the exception request, outlining the + reasons why the organization is unable to comply with the + relevant requirements. Provide as much detail as possible + regarding the exception request, indicating the specific + submission requirements for which relief is being sought. If + applicable, indicate how the organization plans to become + compliant.** +

+ + + +
2000 character limit
+
+
+

Acknowledgment of Terms

+

+ I understand and acknowledge that the Texas Department of + Insurance (TDI) may review the validity of the information + submitted on this form. +

+
+ + + + + + + + + + + + + + + +
+ {isSuccess ? ( + <> + +
+ + Your extension request was successfully sent. + +
+ + ) : ( + + )} + {errorMessage && ( +
+ + {errorMessage} + +
+ )} +
+ + 1 Applicable data period - month/year in which + claims data was adjudicated. + +
+ + 2 Requested target date - requested + day/month/year by which the data should be received (the + extension date). + +
+ + 3 Current expected date - day/month/year in which + applicable data was expected within the submission window. + + + + ); + } + }}
);