您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

128 行
2.8 KiB

  1. "use server";
  2. import {
  3. serverFetchJson,
  4. serverFetchString,
  5. serverFetchWithNoContent,
  6. } from "@/app/utils/fetchUtil";
  7. import { BASE_API_URL } from "@/config/api";
  8. import { Task, TaskGroup } from "../tasks";
  9. import { Customer } from "../customer";
  10. import { revalidatePath, revalidateTag } from "next/cache";
  11. export interface CreateProjectInputs {
  12. // Project
  13. projectId: number | null;
  14. projectDeleted: boolean | null;
  15. projectCode: string;
  16. projectName: string;
  17. projectCategoryId: number;
  18. projectDescription: string;
  19. projectLeadId: number;
  20. projectActualStart: string;
  21. projectActualEnd: string;
  22. projectStatus: string;
  23. isClpProject: boolean;
  24. mainProjectId?: number | null;
  25. // Project info
  26. serviceTypeId: number;
  27. fundingTypeId: number;
  28. contractTypeId: number;
  29. locationId: number;
  30. buildingTypeIds: number[];
  31. workNatureIds: number[];
  32. taskTemplateId?: number | "All";
  33. // Client details
  34. clientId: Customer["id"];
  35. clientContactId?: number;
  36. clientSubsidiaryId?: number | null;
  37. subsidiaryContactId?: number;
  38. isSubsidiaryContact?: boolean;
  39. // Allocation
  40. totalManhour: number;
  41. manhourPercentageByGrade: ManhourAllocation;
  42. taskGroups: {
  43. [taskGroup: TaskGroup["id"]]: {
  44. taskIds: Task["id"][];
  45. percentAllocation: number;
  46. };
  47. };
  48. allocatedStaffIds: number[];
  49. // Milestones
  50. milestones: {
  51. [taskGroupId: TaskGroup["id"]]: {
  52. startDate: string;
  53. endDate: string;
  54. payments: PaymentInputs[];
  55. };
  56. };
  57. // Miscellaneous
  58. expectedProjectFee: number;
  59. subContractFee?: number;
  60. }
  61. export interface ManhourAllocation {
  62. [gradeId: number]: number;
  63. }
  64. export interface PaymentInputs {
  65. id: number;
  66. description: string;
  67. date: string;
  68. amount: number;
  69. }
  70. export interface CreateProjectResponse {
  71. id: number;
  72. name: string;
  73. code: string;
  74. category: string;
  75. team: string;
  76. client: string;
  77. }
  78. export const saveProject = async (data: CreateProjectInputs) => {
  79. const newProject = await serverFetchJson<CreateProjectResponse>(
  80. `${BASE_API_URL}/projects/new`,
  81. {
  82. method: "POST",
  83. body: JSON.stringify(data),
  84. headers: { "Content-Type": "application/json" },
  85. },
  86. );
  87. revalidateTag("projects");
  88. return newProject;
  89. };
  90. export const deleteProject = async (id: number) => {
  91. const project = await serverFetchWithNoContent(
  92. `${BASE_API_URL}/projects/${id}`,
  93. {
  94. method: "DELETE",
  95. headers: { "Content-Type": "application/json" },
  96. },
  97. );
  98. revalidateTag("projects");
  99. revalidatePath("/(main)/home");
  100. return project;
  101. };
  102. export const importProjects = async (data: FormData) => {
  103. const importProjects = await serverFetchString<String>(
  104. `${BASE_API_URL}/projects/import`,
  105. {
  106. method: "POST",
  107. body: data,
  108. },
  109. );
  110. return importProjects;
  111. };