diff --git a/src/components/DistributionTable.tsx b/src/components/DistributionTable.tsx
index 3119dad2..25796c48 100644
--- a/src/components/DistributionTable.tsx
+++ b/src/components/DistributionTable.tsx
@@ -7,7 +7,7 @@ import { useCallback, useRef, useState } from "react";
import { useApiClient } from "@/hooks/useApiClient";
import Portal from "./baseTable/Portal";
import toast from "react-hot-toast";
-import { CheckCircle, DotsThree } from "@phosphor-icons/react";
+import { CheckCircle, DotsThree, XCircle } from "@phosphor-icons/react";
import DistributionsGeneralItemChipGroup from "./chips/DistributionsGeneralItemChipGroup";
import { TableDistribution } from "@/types/api/distribution.types";
import { useUser } from "@/components/context/UserContext";
@@ -168,10 +168,35 @@ function OptionsButton({
error: "Failed to approve distribution.",
});
- await promise;
+ try {
+ await promise;
+ fetchTableData();
+ } finally {
+ setIsDropdownOpen(false);
+ }
- setIsDropdownOpen(false);
- fetchTableData();
+ }
+
+ async function unapproveDistribution() {
+ const formData = new FormData();
+ formData.append("pending", "true");
+
+ const promise = apiClient.patch(`/api/distributions/${distribution.id}`, {
+ body: formData,
+ });
+
+ toast.promise(promise, {
+ loading: "Unapproving distribution...",
+ success: "Distribution unapproved!",
+ error: "Failed to unapprove distribution.",
+ });
+
+ try {
+ await promise;
+ fetchTableData();
+ } finally {
+ setIsDropdownOpen(false);
+ }
}
return (
@@ -190,13 +215,24 @@ function OptionsButton({
position="bottom-right"
className="w-48 rounded-md bg-white shadow-lg ring-1 ring-black/5 py-1"
>
-
+ {distribution.pending ? (
+
+ ) : (
+
+
+ )}
);
diff --git a/src/services/allocationService.ts b/src/services/allocationService.ts
index 00830a3f..47e3bfb0 100644
--- a/src/services/allocationService.ts
+++ b/src/services/allocationService.ts
@@ -317,6 +317,11 @@ export default class AllocationService {
"Cannot transfer items from an approved distribution. Approved distributions are locked."
);
}
+ if (allocation.signOffId !== null) {
+ throw new ArgumentError(
+ "Cannot transfer items that have been signed off."
+ );
+ }
}
if (update.distributionId) {
diff --git a/src/services/distributionService.ts b/src/services/distributionService.ts
index cc2136f2..f10044b0 100644
--- a/src/services/distributionService.ts
+++ b/src/services/distributionService.ts
@@ -667,6 +667,18 @@ export default class DistributionService {
throw new NotFoundError("Distribution not found");
}
+ if (data.pending === true && currentDistribution.pending === false) {
+ const signedOffCount = await db.allocation.count({
+ where: {distributionId, signOffId: { not: null} },
+ });
+
+ if (signedOffCount > 0) {
+ throw new ArgumentError(
+ "Cannot unapprove a distribution that has signed-off allocations."
+ );
+ }
+ }
+
const updatedDistribution = await db.distribution.update({
where: { id: distributionId },
data,