Skip to content

Commit

Permalink
Merge pull request #301 from VineetBala-AOT/develop
Browse files Browse the repository at this point in the history
Changes to accept update for update request
  • Loading branch information
VineetBala-AOT authored Feb 20, 2025
2 parents 6d084ab + 161a0ba commit 4ab135f
Show file tree
Hide file tree
Showing 12 changed files with 204 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""add_accepted_status_to_updaterequeststatus
Revision ID: f9cdde365d29
Revises: 2a8e579da45c
Create Date: 2025-02-19 16:58:23.507357
"""
from alembic import op

# revision identifiers, used by Alembic.
revision = 'f9cdde365d29'
down_revision = '2a8e579da45c'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.execute("ALTER TYPE updaterequeststatus ADD VALUE 'ACCEPTED'")

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass

# ### end Alembic commands ###
1 change: 1 addition & 0 deletions submit-api/src/submit_api/models/update_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class UpdateRequestStatus(enum.Enum):
OPEN = 'OPEN'
PENDING_REVIEW = 'PENDING_REVIEW'
CLOSED = 'CLOSED'
ACCEPTED = 'ACCEPTED'


class UpdateRequest(BaseModel):
Expand Down
19 changes: 17 additions & 2 deletions submit-api/src/submit_api/resources/staff/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,10 @@ def get(original_package_id):
return PackageVersionSchema(many=True).dump(package_versions), HTTPStatus.OK


@cors_preflight("POST, OPTIONS")
@cors_preflight("POST, PATCH, OPTIONS")
@API.route(
"/<int:package_id>/update-request",
methods=["POST", "OPTIONS"],
methods=["POST", "PATCH", "OPTIONS"],
)
class PackageUpdateRequest(Resource):
"""Resource for managing a package's update request."""
Expand All @@ -115,6 +115,21 @@ def post(package_id):
package_id, create_update_request_data)
return StaffPackageSchema().dump(package_with_created_update_request), HTTPStatus.CREATED

@staticmethod
@ApiHelper.swagger_decorators(API, endpoint_description="Accept a update request for a package")
@API.expect(create_update_request_model)
@API.response(
code=HTTPStatus.OK, model=package_model, description="Update Request"
)
@API.response(HTTPStatus.BAD_REQUEST, "Bad Request")
@API.response(HTTPStatus.NOT_FOUND, "Not Found")
@auth.has_one_of_roles([EpicSubmitRole.EAO_CREATE.value])
@cors.crossdomain(origin="*")
def patch(package_id):
"""Accept an update request."""
accept_update_request = PackageService.accept_update_request(package_id)
return StaffPackageSchema().dump(accept_update_request), HTTPStatus.OK


@cors_preflight("POST, OPTIONS")
@API.route(
Expand Down
19 changes: 18 additions & 1 deletion submit-api/src/submit_api/services/package.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ def _resubmit_package(cls, package, session):
"""Submit the package by updating its status and items."""
current_app.logger.info(f"Resubmitting package {package.id}")
open_update_requests = [request for request in package.update_requests
if request.status == UpdateRequestStatus.OPEN.value]
if request.status != UpdateRequestStatus.ACCEPTED.value]
if not open_update_requests:
raise BadRequestError("Cannot resubmit a package that has no open update requests")
cls._update_package_submission_details(package, session)
Expand All @@ -342,6 +342,23 @@ def _resubmit_package(cls, package, session):
cls._log_activity_submission(package, ActivityActionType.UPDATED_SUBMISSION.value, session)
return package

@classmethod
def accept_update_request(cls, package_id):
"""Submit the package by updating its status and items."""
with session_scope() as session:
package = cls._get_and_validate_complete_package(package_id)

current_app.logger.info(f"Accepting update reuqest for package {package.id}")
pending_requests = [
request for request in package.update_requests
if request.status == UpdateRequestStatus.PENDING_REVIEW.value
]
if not pending_requests:
raise BadRequestError("Cannot accept an update request that is not pending")
cls._update_update_requests(
session, package, status=UpdateRequestStatus.ACCEPTED.value, active=False)
return package

@staticmethod
def _log_activity_submission(package, action, session):
"""Log activity for package submission."""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export default function ProponentSubmissionItemTableRow({
submissionPackage?.submitted_on &&
submissionPackage.update_requests.filter(
(updateRequest) =>
updateRequest.status === UPDATE_REQUEST_STATUS.OPEN.value,
updateRequest.status !== UPDATE_REQUEST_STATUS.ACCEPTED.value,
).length === 0
}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { Box, Typography } from "@mui/material";
import { BCDesignTokens } from "epic.theme";
import dateUtils from "@/utils/dateUtils";
import { UPDATE_REQUEST_TYPE, UpdateRequest } from "@/models/UpdateRequest";
import { UPDATE_REQUEST_STATUS, UPDATE_REQUEST_TYPE, UpdateRequest } from "@/models/UpdateRequest";
import { useAcceptUpdateRequest } from "@/hooks/api/usePackages";
import { Case, Switch, When } from "react-if";
import { AddRequestNoteSection } from "./AddRequestNoteSection";
import { SubmissionPackage } from "@/models/Package";
import { useAccount } from "@/store/accountStore";
import { USER_TYPE } from "@/models/User";
import { LoadingButton } from "@/components/Shared/LoadingButton";
import { UpdateRequestStatusChip } from "../../UpdateRequestStatusChip";
import PermissionsGate from "@/components/Shared/PermissionGate";
import { EPIC_SUBMIT_ROLE } from "@/models/Role";

type UpdateRequestProps = Readonly<{
updateRequest: UpdateRequest;
Expand All @@ -24,6 +29,7 @@ export default function RequestSection({
note,
type,
submission_item_types,
status
} = updateRequest;
const createdDate = dateUtils.formatDate(created_date);

Expand All @@ -32,6 +38,12 @@ export default function RequestSection({
const submissionItems = submissionPackage.items.filter((item) =>
submission_item_types.includes(item.type_id),
);

const { mutate: acceptUpdateRequest, isPending: isUpdating } =
useAcceptUpdateRequest({
packageId: updateRequest.submission_package_id,
});

return (
<Box sx={{ my: BCDesignTokens.layoutMarginLarge }}>
<Box
Expand Down Expand Up @@ -64,9 +76,37 @@ export default function RequestSection({
</Switch>
</Typography>

<Typography variant="body1" sx={{ mb: 1 }}>
{reason}
</Typography>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
mb: 1,
}}
>
<Typography variant="body1" sx={{ mb: 1 }}>
{reason}
</Typography>
<PermissionsGate scopes={[EPIC_SUBMIT_ROLE.eao_create]}>
{status === UPDATE_REQUEST_STATUS.ACCEPTED.value ? (
<UpdateRequestStatusChip status={UPDATE_REQUEST_STATUS.ACCEPTED.value} />
) : (
<LoadingButton
variant="contained"
color="secondary"
disabled={status !== UPDATE_REQUEST_STATUS.PENDING_REVIEW.value}
onClick={() =>
acceptUpdateRequest({
packageId: updateRequest.submission_package_id,
})
}
loading={isUpdating}
>
Accept Update
</LoadingButton>
)}
</PermissionsGate>
</Box>

<When condition={Boolean(note)}>
<Typography
Expand Down
42 changes: 42 additions & 0 deletions submit-web/src/components/UpdateRequestStatusChip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Chip } from "@mui/material";
import { BCDesignTokens } from "epic.theme";

type StyleProps = {
sx: Record<string, string | number>;
label: string;
};

const statusStyles: Record<string, StyleProps> = {
ACCEPTED: {
label: "Accepted",
sx: {
borderRadius: 1,
border: `1px solid ${BCDesignTokens.supportBorderColorSuccess}`,
background: BCDesignTokens.supportSurfaceColorSuccess,
height: "24px",
width: "83px",
},
},
};

type UpdateRequestStatusChipProps = Readonly<{
status?: string;
}>;
export function UpdateRequestStatusChip({
status = "",
}: UpdateRequestStatusChipProps) {
const style = statusStyles[status];

if (!style) {
return null;
}

return (
<Chip
sx={{
...style.sx,
}}
label={style.label}
/>
);
}
35 changes: 35 additions & 0 deletions submit-web/src/hooks/api/usePackages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ const createPackageUpdateRequest = ({
});
};

const acceptUpdateRequest = ({
packageId,
}: {
packageId: number;
}) => {
return submitRequest<SubmissionPackage>({
url: `/staff/packages/${packageId}/update-request`,
method: "patch",
});
};

type UseCreatePackageUpdateRequestParams = {
packageId: number;
accountProjectId: number;
Expand Down Expand Up @@ -258,6 +269,30 @@ const createPackageUpdateRequesNote = ({
});
};

type UseAcceptUpdateRequestParams = {
packageId: number;
options?: Options;
};
export const useAcceptUpdateRequest = ({
packageId,
options = {},
}: UseAcceptUpdateRequestParams) => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: acceptUpdateRequest,
...options,
onSuccess: () => {
if (options?.onSuccess) {
options.onSuccess();
}

queryClient.invalidateQueries({
queryKey: [QUERY_KEY.SUBMISSION_PACKAGE, packageId],
});
},
});
};

type UseCreatePackageUpdateRequestNoteParams = {
packageId: number;
options?: Options;
Expand Down
16 changes: 15 additions & 1 deletion submit-web/src/models/UpdateRequest.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
// NonCanonicalSubmissionStatus are just for display purpose, they are not canonical business statuses
export type NonCanonicalSubmissionStatus =
| "ACCEPTED"

export const NON_CANONICAL_UPDATE_REQUEST_STATUS = Object.freeze<
Record<NonCanonicalSubmissionStatus, NonCanonicalSubmissionStatus>
>({
ACCEPTED: "ACCEPTED",
});

export type UpdateRequestType = "UPDATE" | "REVIEW";

export const UPDATE_REQUEST_TYPE = Object.freeze<
Expand All @@ -13,7 +23,7 @@ export const UPDATE_REQUEST_TYPE = Object.freeze<
},
});

export type UpdateRequestStatus = "OPEN" | "PENDING_REVIEW" | "CLOSED";
export type UpdateRequestStatus = "OPEN" | "PENDING_REVIEW" | "CLOSED" | "ACCEPTED";
export const UPDATE_REQUEST_STATUS = Object.freeze<
Record<UpdateRequestStatus, { value: UpdateRequestStatus; label: string }>
>({
Expand All @@ -29,6 +39,10 @@ export const UPDATE_REQUEST_STATUS = Object.freeze<
value: "CLOSED",
label: "Closed",
},
ACCEPTED: {
value: "ACCEPTED",
label: "Accepted",
},
});
export type UpdateRequest = {
id: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default function SubmissionPage() {
isPackageSubmitted &&
submissionPackage.update_requests.filter(
(updateRequest) =>
updateRequest.status === UPDATE_REQUEST_STATUS.OPEN.value &&
updateRequest.status !== UPDATE_REQUEST_STATUS.ACCEPTED.value &&
updateRequest.active,
).length === 0;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export function Submission() {
const hasPackageUpdateRequest =
submissionPackage?.update_requests.filter(
(updateRequest) =>
updateRequest.status === UPDATE_REQUEST_STATUS.OPEN.value &&
updateRequest.status !== UPDATE_REQUEST_STATUS.ACCEPTED.value &&
updateRequest.active,
).length > 0;
const isPackageSubmitted = submissionPackage?.submitted_on;
Expand Down
2 changes: 1 addition & 1 deletion submit-web/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const filterOpenUpdateRequests = (updateRequests: UpdateRequest[]) => {
if (!updateRequests) return [];
return updateRequests.filter(
(updateRequest) =>
updateRequest.status === UPDATE_REQUEST_STATUS.OPEN.value &&
updateRequest.status !== UPDATE_REQUEST_STATUS.ACCEPTED.value &&
updateRequest.type === UPDATE_REQUEST_TYPE.UPDATE.value &&
updateRequest.active,
);
Expand Down

0 comments on commit 4ab135f

Please sign in to comment.