diff --git a/submit-api/migrations/versions/67a4a5ef2087_.py b/submit-api/migrations/versions/67a4a5ef2087_.py
new file mode 100644
index 00000000..876a86d9
--- /dev/null
+++ b/submit-api/migrations/versions/67a4a5ef2087_.py
@@ -0,0 +1,58 @@
+from alembic import op
+import sqlalchemy as sa
+
+# Revision identifiers, used by Alembic
+revision = '67a4a5ef2087'
+down_revision = '9655618a231b'
+branch_labels = None
+depends_on = None
+
+# Define the enums
+itemstatus = sa.Enum('NEW_SUBMISSION', 'PARTIALLY_COMPLETED', 'COMPLETED', name='itemstatus')
+temp_itemstatus = sa.Enum('PENDING', 'NEW_SUBMISSION', 'PARTIALLY_COMPLETED', 'COMPLETED', name='temp_itemstatus')
+old_itemstatus = sa.Enum('PENDING', 'COMPLETED', name='itemstatus')
+
+def upgrade():
+ # Step 1: Create the temporary enum type with 'PENDING' included
+ temp_itemstatus.create(op.get_bind(), checkfirst=False)
+
+ # Step 2: Alter the column to use the temporary enum type, allowing both 'PENDING' and 'NEW_SUBMISSION'
+ op.alter_column('items', 'status', type_=temp_itemstatus, postgresql_using='status::text::temp_itemstatus')
+
+ # Step 3: Update all instances of 'PENDING' to 'NEW_SUBMISSION' in the items table
+ op.execute("UPDATE items SET status = 'NEW_SUBMISSION' WHERE status = 'PENDING'")
+
+ # Step 4: Drop the old enum type
+ itemstatus.drop(op.get_bind(), checkfirst=False)
+
+ # Step 5: Recreate the original enum with the new values (excluding 'PENDING')
+ itemstatus.create(op.get_bind(), checkfirst=False)
+
+ # Step 6: Alter the column to use the new version of the original enum
+ op.alter_column('items', 'status', type_=itemstatus, postgresql_using='status::text::itemstatus')
+
+ # Step 7: Drop the temporary enum type after migration
+ temp_itemstatus.drop(op.get_bind(), checkfirst=False)
+
+
+def downgrade():
+ # Step 1: Create the temporary enum type with the values needed for conversion, including 'PENDING'
+ temp_itemstatus.create(op.get_bind(), checkfirst=False)
+
+ # Step 2: Alter the column to use the temporary enum type (with 'PENDING') to allow conversion
+ op.alter_column('items', 'status', type_=temp_itemstatus, postgresql_using='status::text::temp_itemstatus')
+
+ # Step 3: Update any instances of 'NEW_SUBMISSION' back to 'PENDING' after confirming the column type allows it
+ op.execute("UPDATE items SET status = 'PENDING' WHERE status = 'NEW_SUBMISSION'")
+ op.execute("UPDATE items SET status = 'PENDING' WHERE status = 'PARTIALLY_COMPLETED'")
+ # Step 4: Drop the current itemstatus enum
+ itemstatus.drop(op.get_bind(), checkfirst=False)
+
+ # Step 5: Recreate the old enum type (including 'PENDING' and 'COMPLETED')
+ old_itemstatus.create(op.get_bind(), checkfirst=False)
+
+ # Step 6: Alter the column to use the old enum type
+ op.alter_column('items', 'status', type_=old_itemstatus, postgresql_using='status::text::itemstatus')
+
+ # Step 7: Drop the temporary enum type after conversion
+ temp_itemstatus.drop(op.get_bind(), checkfirst=False)
\ No newline at end of file
diff --git a/submit-api/src/submit_api/models/item.py b/submit-api/src/submit_api/models/item.py
index 35708d24..7750791f 100644
--- a/submit-api/src/submit_api/models/item.py
+++ b/submit-api/src/submit_api/models/item.py
@@ -15,7 +15,8 @@
class ItemStatus(enum.Enum):
"""Enum for item statuses."""
- PENDING = 'PENDING'
+ NEW_SUBMISSION = 'NEW_SUBMISSION'
+ PARTIALLY_COMPLETED = 'PARTIALLY_COMPLETED'
COMPLETED = 'COMPLETED'
@@ -30,7 +31,7 @@ class Item(BaseModel):
sort_order = Column(db.Integer, nullable=True, default=0)
type = db.relationship('ItemType', foreign_keys=[type_id], lazy='joined')
status = Column(Enum(ItemStatus), nullable=False,
- default=ItemStatus.PENDING)
+ default=ItemStatus.NEW_SUBMISSION)
submitted_on = Column(db.DateTime, nullable=True)
submitted_by = Column(db.String(255), nullable=True)
version = Column(db.Integer, nullable=False, default=1)
diff --git a/submit-api/src/submit_api/resources/submission.py b/submit-api/src/submit_api/resources/submission.py
index 49e685d1..47b801ce 100644
--- a/submit-api/src/submit_api/resources/submission.py
+++ b/submit-api/src/submit_api/resources/submission.py
@@ -20,7 +20,6 @@
from submit_api.schemas.submission import CreateSubmissionRequestSchema, SubmissionSchema
from submit_api.services.submission import SubmissionService
from submit_api.utils.util import cors_preflight
-
from ..auth import auth
from .apihelper import Api as ApiHelper
@@ -55,6 +54,10 @@ def post(submission_item_id):
"""Create a submission."""
create_submission_data = CreateSubmissionRequestSchema().load(API.payload)
created_submission = SubmissionService.create_submission(submission_item_id, create_submission_data)
+ item_id = create_submission_data.get("item_id")
+ status = create_submission_data.get("status")
+ if status:
+ SubmissionService.update_submission_item_status(item_id, status)
return SubmissionSchema().dump(created_submission), HTTPStatus.CREATED
@@ -76,4 +79,8 @@ def patch(submission_id):
"""Edit a submission."""
edit_submission_data = CreateSubmissionRequestSchema().load(API.payload)
edited_submission = SubmissionService.edit_submission_form(submission_id, edit_submission_data)
+ item_id = edit_submission_data.get("item_id")
+ status = edit_submission_data.get("status")
+ if status:
+ SubmissionService.update_submission_item_status(item_id, status)
return SubmissionSchema().dump(edited_submission), HTTPStatus.OK
diff --git a/submit-api/src/submit_api/schemas/submission.py b/submit-api/src/submit_api/schemas/submission.py
index ec659652..209de387 100644
--- a/submit-api/src/submit_api/schemas/submission.py
+++ b/submit-api/src/submit_api/schemas/submission.py
@@ -67,4 +67,6 @@ class Meta: # pylint: disable=too-few-public-methods
unknown = EXCLUDE
type = fields.Str(data_key="type")
+ status = fields.Str(data_key="status")
data = fields.Dict(data_key="data")
+ item_id = fields.Int(data_key="item_id")
diff --git a/submit-api/src/submit_api/services/item.py b/submit-api/src/submit_api/services/item.py
index 2e1c0ee2..a00e731d 100644
--- a/submit-api/src/submit_api/services/item.py
+++ b/submit-api/src/submit_api/services/item.py
@@ -11,3 +11,16 @@ def get_item_by_id(cls, item_id):
"""Get item by id."""
item = ItemModel.find_by_id(item_id)
return item
+
+ @classmethod
+ def update_submission_item(cls, item_id, update_data):
+ """Update submission item by id."""
+ submission_item = cls.get_item_by_id(item_id)
+ if not submission_item:
+ raise ValueError(f"Item with id {item_id} not found.")
+
+ for key, value in update_data.items():
+ setattr(submission_item, key, value)
+
+ submission_item.save()
+ return submission_item
diff --git a/submit-api/src/submit_api/services/submission/__init__.py b/submit-api/src/submit_api/services/submission/__init__.py
index b0691ccd..fe4a9b8f 100644
--- a/submit-api/src/submit_api/services/submission/__init__.py
+++ b/submit-api/src/submit_api/services/submission/__init__.py
@@ -4,6 +4,7 @@
from submit_api.models.submission import SubmissionTypeStatus
from submit_api.services.submission.submission_creator_factory import (
DocumentSubmissionCreator, FormSubmissionCreator, SubmissionCreatorFactory)
+from submit_api.services.item import ItemService
class SubmissionService:
@@ -36,10 +37,10 @@ def create_submission(cls, item_id, request_data):
submission_type = request_data.get("type")
if not submission_type:
raise ValueError("Submission type is required.")
-
submission_creator = cls.make_submission_creator(submission_type)
submission_data = request_data.get("data")
- return submission_creator.create(item_id, submission_data)
+ submission = submission_creator.create(item_id, submission_data)
+ return submission
@classmethod
def get_submission_by_id_and_validate_edit(cls, submission_id):
@@ -61,3 +62,11 @@ def edit_submission_form(cls, submission_id, request):
submission.submitted_form.submission_json = request.get('data')
submission.submitted_form.save()
return submission
+
+ @classmethod
+ def update_submission_item_status(cls, item_id, status):
+ """Update the status of the submission item."""
+ if status is None:
+ raise ValueError("Status is required.")
+ update_data = {"status": status}
+ ItemService.update_submission_item(item_id, update_data)
diff --git a/submit-web/src/components/Submission/SubmissionItemTableRow.tsx b/submit-web/src/components/Submission/SubmissionItemTableRow.tsx
index 6cc68946..0b851b03 100644
--- a/submit-web/src/components/Submission/SubmissionItemTableRow.tsx
+++ b/submit-web/src/components/Submission/SubmissionItemTableRow.tsx
@@ -116,9 +116,7 @@ export default function SubmissionItemTableRow({
-
+
diff --git a/submit-web/src/components/Submission/SubmissionStatusChip.tsx b/submit-web/src/components/Submission/SubmissionStatusChip.tsx
index a052ea7f..c3b10c54 100644
--- a/submit-web/src/components/Submission/SubmissionStatusChip.tsx
+++ b/submit-web/src/components/Submission/SubmissionStatusChip.tsx
@@ -7,12 +7,14 @@ type StyleProps = {
sx: Record;
label: string;
};
+
const statusStyles: Record = {
NEW_SUBMISSION: {
sx: {
borderRadius: 1,
border: `2px solid ${EAOColors.DecisionDark}`,
background: EAOColors.DecisionLight,
+ height: "24px",
},
label: "New Submission",
},
@@ -21,15 +23,17 @@ const statusStyles: Record = {
borderRadius: 1,
border: `2px solid ${BCDesignTokens.supportBorderColorSuccess}`,
background: BCDesignTokens.supportSurfaceColorSuccess,
+ height: "24px",
},
label: "Completed",
},
- PARTIALLY_COMPLETE: {
- label: "Partially Complete",
+ PARTIALLY_COMPLETED: {
+ label: "Partially Completed",
sx: {
borderRadius: 1,
border: `2px solid ${BCDesignTokens.supportBorderColorWarning}`,
background: BCDesignTokens.supportSurfaceColorWarning,
+ height: "24px",
},
},
SUBMITTED: {
@@ -38,6 +42,7 @@ const statusStyles: Record = {
borderRadius: 1,
border: `2px solid ${BCDesignTokens.themeBlue100}`,
background: BCDesignTokens.themeBlue20,
+ height: "24px",
},
},
};
@@ -47,7 +52,7 @@ export default function SubmissionStatusChip({
}: {
status: SubmissionStatus;
}) {
- const style = statusStyles[status];
+ const style = statusStyles[status] || statusStyles.NEW_SUBMISSION;
return (
{
});
const formSubmission = submissionItem?.submissions?.find(
- (submission) => submission.type === SUBMISSION_TYPE.FORM,
+ (submission) => submission.type === SUBMISSION_TYPE.FORM
);
const defaultFormValues = useMemo(() => {
if (!formSubmission?.submitted_form?.submission_json) return {};
@@ -89,31 +93,31 @@ export const ConsultationRecord = () => {
return {
...formSubmission.submitted_form.submission_json,
allPartiesConsulted: booleanToString(
- formSubmission.submitted_form.submission_json.allPartiesConsulted,
+ formSubmission.submitted_form.submission_json.allPartiesConsulted
),
planWasReviewed: booleanToString(
- formSubmission.submitted_form.submission_json.planWasReviewed,
+ formSubmission.submitted_form.submission_json.planWasReviewed
),
writtenExplanationsProvidedToParties: booleanToString(
formSubmission.submitted_form.submission_json
- .writtenExplanationsProvidedToParties,
+ .writtenExplanationsProvidedToParties
),
writtenExplanationsProvidedToCommenters: booleanToString(
formSubmission.submitted_form.submission_json
- .writtenExplanationsProvidedToCommenters,
+ .writtenExplanationsProvidedToCommenters
),
};
}, [formSubmission]);
const documentSubmissions = submissionItem?.submissions?.filter(
- (submission) => submission.type === SUBMISSION_TYPE.DOCUMENT,
+ (submission) => submission.type === SUBMISSION_TYPE.DOCUMENT
);
const defaultDocumentValues = useMemo(() => {
if (!documentSubmissions) return {};
return {
consultationRecords: documentSubmissions.map(
- (submission) => submission.submitted_document.url,
+ (submission) => submission.submitted_document.url
),
};
}, [documentSubmissions]);
@@ -162,7 +166,14 @@ export const ConsultationRecord = () => {
formState: { errors, dirtyFields },
} = methods;
- const saveSubmission = async (formData: ConsultationRecordForm) => {
+ const handleCompleteForm = (formData: ConsultationRecordForm) => {
+ saveSubmission(formData, SUBMISSION_STATUS.COMPLETED.value); // Add default status here
+ };
+
+ const saveSubmission = async (
+ formData: ConsultationRecordForm,
+ status: SubmissionStatus
+ ) => {
const {
consultedParties,
allPartiesConsulted,
@@ -173,15 +184,17 @@ export const ConsultationRecord = () => {
callSaveSubmission({
data: {
type: SUBMISSION_TYPE.FORM,
+ status,
+ item_id: submissionItemId,
data: {
consultedParties,
allPartiesConsulted: stringToBoolean(allPartiesConsulted),
planWasReviewed: stringToBoolean(planWasReviewed),
writtenExplanationsProvidedToParties: stringToBoolean(
- writtenExplanationsProvidedToParties,
+ writtenExplanationsProvidedToParties
),
writtenExplanationsProvidedToCommenters: stringToBoolean(
- writtenExplanationsProvidedToCommenters,
+ writtenExplanationsProvidedToCommenters
),
},
},
@@ -199,7 +212,7 @@ export const ConsultationRecord = () => {
...methods.getValues(),
};
- saveSubmission(formData);
+ saveSubmission(formData, SUBMISSION_STATUS.PARTIALLY_COMPLETED.value);
};
useEffect(() => {
@@ -243,7 +256,7 @@ export const ConsultationRecord = () => {
title={accountProject.project.name + " Management Plan"}
/>
-