FPSMS-frontend
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

204 lines
5.8 KiB

  1. import dayjs, { ConfigType, Dayjs } from "dayjs";
  2. import { Uom } from "../api/settings/uom";
  3. import {
  4. ListIterateeCustom,
  5. every,
  6. isArray,
  7. isNaN,
  8. isNull,
  9. isUndefined,
  10. take,
  11. } from "lodash";
  12. import { Box, BoxProps } from "@mui/material";
  13. export const manhourFormatter = new Intl.NumberFormat("en-HK", {
  14. minimumFractionDigits: 2,
  15. maximumFractionDigits: 2,
  16. });
  17. export const moneyFormatter = new Intl.NumberFormat("en-HK", {
  18. style: "currency",
  19. currency: "HKD",
  20. });
  21. export const decimalFormatter = new Intl.NumberFormat("en-HK", {
  22. minimumFractionDigits: 2,
  23. maximumFractionDigits: 5,
  24. });
  25. /** Use for prices (e.g. market unit price): 2 decimal places only */
  26. export const priceFormatter = new Intl.NumberFormat("en-HK", {
  27. minimumFractionDigits: 2,
  28. maximumFractionDigits: 2,
  29. });
  30. export const integerFormatter = new Intl.NumberFormat("en-HK", {});
  31. export const INPUT_DATE_FORMAT = "YYYY-MM-DD";
  32. export const OUTPUT_DATE_FORMAT = "YYYY-MM-DD";
  33. /** Date and time for display, e.g. "YYYY-MM-DD HH:mm" */
  34. export const OUTPUT_DATETIME_FORMAT = "YYYY-MM-DD HH:mm";
  35. export const INPUT_TIME_FORMAT = "HH:mm:ss";
  36. export const OUTPUT_TIME_FORMAT = "HH:mm:ss";
  37. export const arrayToDayjs = (arr: ConfigType | (number | undefined)[], showTime: boolean = false) => {
  38. const isValidNumber = (
  39. item: ListIterateeCustom<number | undefined, boolean>,
  40. ): boolean => typeof item === "number" && !isNaN(item) && isFinite(item);
  41. let tempArr = arr;
  42. if (isArray(arr) && every(arr, isValidNumber) && arr.length >= 3) {
  43. // [year, month, day]
  44. // tempArr = take(arr, 3);
  45. tempArr = `${arr[0]?.toString().padStart(4, "0")}-${arr[1]?.toString().padStart(2, "0")}-${arr[2]?.toString().padStart(2, "0")}`;
  46. if (showTime) {
  47. // [year, month, day, hour, minute, second]
  48. tempArr += ` ${
  49. arr[3]?.toString().padStart(2, "0")}:${
  50. arr[4]?.toString().padStart(2, "0")}:${
  51. (arr[5] ?? 0)?.toString().padStart(2, "0")}`;
  52. }
  53. }
  54. return dayjs(tempArr as ConfigType);
  55. };
  56. export const arrayToDateString = (arr: ConfigType | (number | undefined)[], format: "input"|"output" = "output") => {
  57. if (format == "output") {
  58. return arrayToDayjs(arr).format(OUTPUT_DATE_FORMAT);
  59. }
  60. else {
  61. return arrayToDayjs(arr).format(INPUT_DATE_FORMAT);
  62. }
  63. };
  64. export const arrayToDateTimeString = (arr: ConfigType | (number | undefined)[]) => {
  65. return arrayToDayjs(arr, true).format(`${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`);
  66. };
  67. export const dateStringToDayjs = (date: string) => {
  68. // Format: YYYY/MM/DD
  69. return dayjs(date, OUTPUT_DATE_FORMAT);
  70. };
  71. export const dateTimeStringToDayjs = (dateTime: string) => {
  72. // Format: YYYY/MM/DD HH:mm:ss
  73. return dayjs(dateTime, `${OUTPUT_DATE_FORMAT} ${OUTPUT_TIME_FORMAT}`);
  74. };
  75. export const dayjsToDateString = (date: Dayjs, format: "input"|"output" = "output") => {
  76. if (format == "output") {
  77. return date.format(OUTPUT_DATE_FORMAT);
  78. } else {
  79. return date.format(INPUT_DATE_FORMAT);
  80. }
  81. };
  82. export const dayjsToDateTimeString = (date: Dayjs, format: "input"|"output" = "input") => {
  83. if (format == "input") {
  84. return date.format(`${INPUT_DATE_FORMAT}T${INPUT_TIME_FORMAT}`);
  85. }
  86. else {
  87. return date.format(`${OUTPUT_DATE_FORMAT}T${OUTPUT_TIME_FORMAT}`);
  88. }
  89. };
  90. export const dayjsToArray = (date: Dayjs) => {
  91. return [
  92. date.year(),
  93. date.month() + 1, // Months are 0-based in Day.js, so add 1
  94. date.date(),
  95. date.hour(), // (24-hour format)
  96. date.minute(),
  97. date.second(),
  98. ];
  99. };
  100. export const outputDateStringToInputDateString = (date: string) => {
  101. return dayjsToDateTimeString(dateStringToDayjs(date))
  102. }
  103. export const stockInLineStatusMap: { [status: string]: number } = {
  104. draft: 0,
  105. pending: 1,
  106. qc: 2,
  107. determine1: 3,
  108. determine2: 4,
  109. determine3: 5,
  110. receiving: 6,
  111. received: 7,
  112. completed: 8,
  113. rejected: 9,
  114. };
  115. export const stockOutLineStatusMap: { [status: string]: number } = {
  116. draft: 0,
  117. pending: 1, // waiting for qc
  118. determine1: 2, // waiting for qc
  119. "lot-change": 3, // waiting for qc
  120. // after qc = completed
  121. completed: 4,
  122. rejected: 5,
  123. };
  124. export const pickOrderStatusMap: { [status: string]: number } = {
  125. pending: 1,
  126. consolidated: 2,
  127. released: 3,
  128. completed: 4,
  129. };
  130. export const calculateWeight = (qty: number, uom: Uom) => {
  131. return qty * (uom.unit2Qty || 1) * (uom.unit3Qty || 1) * (uom.unit4Qty || 1);
  132. };
  133. export const returnWeightUnit = (uom: Uom) => {
  134. return uom.unit4 || uom.unit3 || uom.unit2 || uom.unit1;
  135. };
  136. /**
  137. * Formats departure time to HH:mm format
  138. * Handles array format [hours, minutes] from API and string formats
  139. */
  140. export const formatDepartureTime = (time: string | number[] | String | Number | null | undefined): string => {
  141. if (!time) return "-";
  142. // Handle array format [hours, minutes] from API
  143. if (Array.isArray(time) && time.length >= 2) {
  144. const hours = time[0];
  145. const minutes = time[1];
  146. if (typeof hours === 'number' && typeof minutes === 'number' &&
  147. hours >= 0 && hours <= 23 && minutes >= 0 && minutes <= 59) {
  148. return `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
  149. }
  150. }
  151. const timeStr = String(time).trim();
  152. if (!timeStr || timeStr === "-") return "-";
  153. // If already in HH:mm format, return as is
  154. if (/^\d{1,2}:\d{2}$/.test(timeStr)) {
  155. const [hours, minutes] = timeStr.split(":");
  156. return `${hours.padStart(2, "0")}:${minutes.padStart(2, "0")}`;
  157. }
  158. return timeStr;
  159. };
  160. /**
  161. * Normalizes store ID to display format (2F or 4F)
  162. */
  163. export const normalizeStoreId = (storeId: string | number | String | Number | null | undefined): string => {
  164. if (!storeId) return "-";
  165. const storeIdStr = typeof storeId === 'string' || storeId instanceof String
  166. ? String(storeId)
  167. : String(storeId);
  168. if (storeIdStr === "2" || storeIdStr === "2F") return "2F";
  169. if (storeIdStr === "4" || storeIdStr === "4F") return "4F";
  170. return storeIdStr;
  171. };