FPSMS-frontend
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.
 
 

267 rindas
8.9 KiB

  1. "use client";
  2. import { InventoryLotLineResult, InventoryResult } from "@/app/api/inventory";
  3. import { useTranslation } from "react-i18next";
  4. import SearchBox, { Criterion } from "../SearchBox";
  5. import { useCallback, useEffect, useMemo, useState } from "react";
  6. import { isEqual, orderBy, uniq, uniqBy } from "lodash";
  7. import SearchResults, { Column } from "../SearchResults";
  8. import { CheckCircleOutline, DoDisturb } from "@mui/icons-material";
  9. import InventoryTable from "./InventoryTable";
  10. import { defaultPagingController } from "../SearchResults/SearchResults";
  11. import InventoryLotLineTable from "./InventoryLotLineTable";
  12. import { SearchInventory, SearchInventoryLotLine, fetchInventories, fetchInventoryLotLines } from "@/app/api/inventory/actions";
  13. import { PrinterCombo } from "@/app/api/settings/printer";
  14. interface Props {
  15. inventories: InventoryResult[];
  16. printerCombo?: PrinterCombo[];
  17. }
  18. type SearchQuery = Partial<
  19. Omit<
  20. InventoryResult,
  21. | "id"
  22. | "qty"
  23. | "uomCode"
  24. | "uomUdfudesc"
  25. | "germPerSmallestUnit"
  26. | "qtyPerSmallestUnit"
  27. | "itemSmallestUnit"
  28. | "price"
  29. | "description"
  30. | "category"
  31. >
  32. >;
  33. type SearchParamNames = keyof SearchQuery;
  34. const InventorySearch: React.FC<Props> = ({ inventories, printerCombo }) => {
  35. const { t } = useTranslation(["inventory", "common"]);
  36. // Inventory
  37. const [filteredInventories, setFilteredInventories] = useState<InventoryResult[]>([]);
  38. const [inventoriesPagingController, setInventoriesPagingController] = useState(defaultPagingController)
  39. const [inventoriesTotalCount, setInventoriesTotalCount] = useState(0)
  40. const [selectedInventory, setSelectedInventory] = useState<InventoryResult | null>(null)
  41. // Inventory Lot Line
  42. const [filteredInventoryLotLines, setFilteredInventoryLotLines] = useState<InventoryLotLineResult[]>([]);
  43. const [inventoryLotLinesPagingController, setInventoryLotLinesPagingController] = useState(defaultPagingController)
  44. const [inventoryLotLinesTotalCount, setInventoryLotLinesTotalCount] = useState(0)
  45. const defaultInputs = useMemo(() => ({
  46. itemId: "",
  47. itemCode: "",
  48. itemName: "",
  49. itemType: "",
  50. onHandQty: "",
  51. onHoldQty: "",
  52. unavailableQty: "",
  53. availableQty: "",
  54. currencyName: "",
  55. status: "",
  56. baseUom: "",
  57. uomShortDesc: "",
  58. }), [])
  59. const [inputs, setInputs] = useState<Record<SearchParamNames, string>>(defaultInputs);
  60. const searchCriteria: Criterion<SearchParamNames>[] = useMemo(
  61. () => [
  62. { label: t("Code"), paramName: "itemCode", type: "text" },
  63. { label: t("Name"), paramName: "itemName", type: "text" },
  64. {
  65. label: t("Type"),
  66. paramName: "itemType",
  67. type: "select",
  68. options: uniq(inventories.map((i) => i.itemType)),
  69. },
  70. // {
  71. // label: t("Status"),
  72. // paramName: "status",
  73. // type: "select",
  74. // options: uniq(inventories.map((i) => i.status)),
  75. // },
  76. ],
  77. [t],
  78. );
  79. // Inventory
  80. const refetchInventoryData = useCallback(async (
  81. query: Record<SearchParamNames, string>,
  82. actionType: "reset" | "search" | "paging" | "init",
  83. pagingController: typeof defaultPagingController,
  84. ) => {
  85. console.log("%c Action Type 1.", "color:red", actionType)
  86. // Avoid loading data again
  87. if (actionType === "paging" && pagingController === defaultPagingController) {
  88. return
  89. }
  90. console.log("%c Action Type 2.", "color:blue", actionType)
  91. const params: SearchInventory = {
  92. code: query?.itemCode ?? '',
  93. name: query?.itemName ?? '',
  94. type: query?.itemType.toLowerCase() === "all" ? '' : query?.itemType ?? '',
  95. pageNum: pagingController.pageNum - 1,
  96. pageSize: pagingController.pageSize
  97. }
  98. const response = await fetchInventories(params)
  99. if (response) {
  100. setInventoriesTotalCount(response.total);
  101. switch (actionType) {
  102. case "init":
  103. case "reset":
  104. case "search":
  105. setFilteredInventories(() => response.records);
  106. break;
  107. case "paging":
  108. setFilteredInventories((fi) =>
  109. // orderBy(
  110. uniqBy([...fi, ...response.records], "id")
  111. // , ["id"], ["desc"])
  112. );
  113. }
  114. }
  115. }, [])
  116. useEffect(() => {
  117. refetchInventoryData(defaultInputs, "init", defaultPagingController)
  118. }, [])
  119. useEffect(() => {
  120. // if (!isEqual(inventoriesPagingController, defaultPagingController)) {
  121. refetchInventoryData(inputs, "paging", inventoriesPagingController)
  122. // }
  123. }, [inventoriesPagingController])
  124. // Inventory Lot Line
  125. const refetchInventoryLotLineData = useCallback(async (
  126. itemId: number | null,
  127. actionType: "reset" | "search" | "paging",
  128. pagingController: typeof defaultPagingController,
  129. ) => {
  130. if (!itemId) {
  131. setSelectedInventory(null)
  132. setInventoryLotLinesTotalCount(0);
  133. setFilteredInventoryLotLines([])
  134. return
  135. }
  136. // Avoid loading data again
  137. if (actionType === "paging" && pagingController === defaultPagingController) {
  138. return
  139. }
  140. const params: SearchInventoryLotLine = {
  141. itemId: itemId,
  142. pageNum: pagingController.pageNum - 1,
  143. pageSize: pagingController.pageSize
  144. }
  145. const response = await fetchInventoryLotLines(params)
  146. if (response) {
  147. setInventoryLotLinesTotalCount(response.total);
  148. switch (actionType) {
  149. case "reset":
  150. case "search":
  151. setFilteredInventoryLotLines(() => response.records);
  152. break;
  153. case "paging":
  154. setFilteredInventoryLotLines((fi) =>
  155. // orderBy(
  156. uniqBy([...fi, ...response.records], "id"),
  157. // ["id"], ["desc"])
  158. );
  159. }
  160. }
  161. }, [])
  162. useEffect(() => {
  163. // if (!isEqual(inventoryLotLinesPagingController, defaultPagingController)) {
  164. refetchInventoryLotLineData(selectedInventory?.itemId ?? null, "paging", inventoryLotLinesPagingController)
  165. // }
  166. }, [inventoryLotLinesPagingController])
  167. // Reset
  168. const onReset = useCallback(() => {
  169. refetchInventoryData(defaultInputs, "reset", defaultPagingController);
  170. refetchInventoryLotLineData(null, "reset", defaultPagingController);
  171. // setFilteredInventories(inventories);
  172. setInputs(() => defaultInputs)
  173. setInventoriesPagingController(() => defaultPagingController)
  174. setInventoryLotLinesPagingController(() => defaultPagingController)
  175. }, []);
  176. // Click Row
  177. const onInventoryRowClick = useCallback((item: InventoryResult) => {
  178. refetchInventoryLotLineData(item.itemId, "search", defaultPagingController)
  179. setSelectedInventory(item)
  180. setInventoryLotLinesPagingController(() => defaultPagingController)
  181. }, [])
  182. // On Search
  183. const onSearch = useCallback((query: Record<SearchParamNames, string>) => {
  184. refetchInventoryData(query, "search", defaultPagingController)
  185. refetchInventoryLotLineData(null, "search", defaultPagingController);
  186. setInputs(() => query)
  187. setInventoriesPagingController(() => defaultPagingController)
  188. setInventoryLotLinesPagingController(() => defaultPagingController)
  189. }, [refetchInventoryData])
  190. console.log("", "color: #666", inventoriesPagingController)
  191. return (
  192. <>
  193. <SearchBox
  194. criteria={searchCriteria}
  195. onSearch={(query) => {
  196. onSearch(query)
  197. // console.log(query)
  198. // console.log(inventories)
  199. // setInputs(() => query)
  200. // refetchInventoryData(query, "search", defaultPagingController)
  201. // setFilteredInventories(
  202. // inventories.filter(
  203. // (i) =>
  204. // i.itemCode.toLowerCase().includes(query.itemCode.toLowerCase()) &&
  205. // i.itemName.toLowerCase().includes(query.itemName.toLowerCase()) &&
  206. // (query.itemType == "All" ||
  207. // i.itemType.toLowerCase().includes(query.itemType.toLowerCase())) &&
  208. // (query.status == "All" ||
  209. // i.status.toLowerCase().includes(query.status.toLowerCase())),
  210. // ),
  211. // );
  212. }}
  213. onReset={onReset}
  214. />
  215. <InventoryTable
  216. inventories={filteredInventories}
  217. pagingController={inventoriesPagingController}
  218. setPagingController={setInventoriesPagingController}
  219. totalCount={inventoriesTotalCount}
  220. onRowClick={onInventoryRowClick}
  221. />
  222. <InventoryLotLineTable
  223. inventoryLotLines={filteredInventoryLotLines}
  224. pagingController={inventoryLotLinesPagingController}
  225. setPagingController={setInventoryLotLinesPagingController}
  226. totalCount={inventoryLotLinesTotalCount}
  227. inventory={selectedInventory}
  228. printerCombo={printerCombo ?? []}
  229. onStockTransferSuccess={() =>
  230. refetchInventoryLotLineData(selectedInventory?.itemId ?? null, "search", inventoryLotLinesPagingController)
  231. }
  232. onStockAdjustmentSuccess={() =>
  233. refetchInventoryLotLineData(selectedInventory?.itemId ?? null, "search", inventoryLotLinesPagingController)
  234. }
  235. />
  236. </>
  237. );
  238. };
  239. export default InventorySearch;