@erpsquad/common 1.8.94 → 1.8.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/_virtual/index/index.esm2.js +4 -2
  2. package/dist/_virtual/index/index.esm2.js.map +1 -1
  3. package/dist/_virtual/index/index.esm5.js +2 -4
  4. package/dist/_virtual/index/index.esm5.js.map +1 -1
  5. package/dist/_virtual/index/index.esm6.js +3 -3
  6. package/dist/_virtual/index/index2.js +1 -1
  7. package/dist/_virtual/index/index5.js +1 -1
  8. package/dist/_virtual/index/index6.js +1 -1
  9. package/dist/api-client/api.hrms/api/index.esm.js +1 -12
  10. package/dist/api-client/api.hrms/api/index.esm.js.map +1 -1
  11. package/dist/api-client/api.hrms/api/index.js +1 -1
  12. package/dist/api-client/api.hrms/api/index.js.map +1 -1
  13. package/dist/api-client/api.rbac/api/index.esm2.js +230 -1
  14. package/dist/api-client/api.rbac/api/index.esm2.js.map +1 -1
  15. package/dist/api-client/api.rbac/api/index2.js +1 -1
  16. package/dist/api-client/api.rbac/api/index2.js.map +1 -1
  17. package/dist/components/action-bar/action-bar/index.esm.js +1 -1
  18. package/dist/components/action-bar/action-bar/index.esm.js.map +1 -1
  19. package/dist/components/action-bar/action-bar/index.js +5 -5
  20. package/dist/components/action-bar/action-bar/index.js.map +1 -1
  21. package/dist/components/filter/filter/index.esm.js +1 -1
  22. package/dist/components/filter/filter/index.esm.js.map +1 -1
  23. package/dist/components/filter/filter/index.js +7 -7
  24. package/dist/components/filter/filter/index.js.map +1 -1
  25. package/dist/components/header/redux/actionCreator/index.esm.js +1 -1
  26. package/dist/components/header/redux/actionCreator/index.esm.js.map +1 -1
  27. package/dist/components/header/redux/actionCreator/index.js +1 -1
  28. package/dist/components/header/redux/actionCreator/index.js.map +1 -1
  29. package/dist/components/inventory-reports-title-bar/redux/actionCreator/index.esm.js +1 -1
  30. package/dist/components/inventory-reports-title-bar/redux/actionCreator/index.esm.js.map +1 -1
  31. package/dist/components/inventory-reports-title-bar/redux/actionCreator/index.js +1 -1
  32. package/dist/components/inventory-reports-title-bar/redux/actionCreator/index.js.map +1 -1
  33. package/dist/components/reports-title-bar/redux/actionCreator/index.esm.js +1 -1
  34. package/dist/components/reports-title-bar/redux/actionCreator/index.esm.js.map +1 -1
  35. package/dist/components/reports-title-bar/redux/actionCreator/index.js +1 -1
  36. package/dist/components/reports-title-bar/redux/actionCreator/index.js.map +1 -1
  37. package/dist/components/share-modal/redux/actionCreator/index.esm.js +1 -1
  38. package/dist/components/share-modal/redux/actionCreator/index.esm.js.map +1 -1
  39. package/dist/components/share-modal/redux/actionCreator/index.js +1 -1
  40. package/dist/components/share-modal/redux/actionCreator/index.js.map +1 -1
  41. package/dist/components/upload/upload/index.esm.js +2 -2
  42. package/dist/components/upload/upload/index.esm.js.map +1 -1
  43. package/dist/components/upload/upload/index.js +11 -11
  44. package/dist/components/upload/upload/index.js.map +1 -1
  45. package/dist/constants/defaultColumns/index.esm.js +1 -1
  46. package/dist/constants/defaultColumns/index.esm.js.map +1 -1
  47. package/dist/constants/defaultColumns/index.js +1 -1
  48. package/dist/constants/defaultColumns/index.js.map +1 -1
  49. package/dist/contexts/AuthContext/index.esm.js +1 -1
  50. package/dist/contexts/AuthContext/index.esm.js.map +1 -1
  51. package/dist/contexts/AuthContext/index.js +1 -1
  52. package/dist/contexts/AuthContext/index.js.map +1 -1
  53. package/dist/contexts/languageContext/index.esm.js +1 -1
  54. package/dist/contexts/languageContext/index.esm.js.map +1 -1
  55. package/dist/contexts/languageContext/index.js +1 -1
  56. package/dist/contexts/languageContext/index.js.map +1 -1
  57. package/dist/node_modules/@asseinfo/react-kanban/dist/index/index.esm.js +1 -1
  58. package/dist/node_modules/@asseinfo/react-kanban/dist/index/index.js +1 -1
  59. package/dist/node_modules/@mui/icons-material/utils/createSvgIcon/index.esm.js +1 -1
  60. package/dist/node_modules/@mui/icons-material/utils/createSvgIcon/index.js +1 -1
  61. package/dist/node_modules/@mui/system/createStyled/index.esm.js +1 -1
  62. package/dist/node_modules/@mui/system/createStyled/index.js +1 -1
  63. package/dist/node_modules/@mui/system/useThemeWithoutDefault/index.esm.js +1 -1
  64. package/dist/node_modules/@mui/system/useThemeWithoutDefault/index.js +1 -1
  65. package/dist/src/utils/api.d.ts +6 -6
  66. package/dist/style.css +68 -68
  67. package/dist/utils/api/index.esm.js +6 -8
  68. package/dist/utils/api/index.esm.js.map +1 -1
  69. package/dist/utils/api/index.js +1 -1
  70. package/dist/utils/api/index.js.map +1 -1
  71. package/dist/utils/api.d.ts +6 -6
  72. package/dist/utils/common/index.esm.js +6 -6
  73. package/dist/utils/common/index.esm.js.map +1 -1
  74. package/dist/utils/common/index.js +1 -1
  75. package/dist/utils/common/index.js.map +1 -1
  76. package/dist/views/form-builder/redux/actionCreator/index.esm.js +1 -1
  77. package/dist/views/form-builder/redux/actionCreator/index.esm.js.map +1 -1
  78. package/dist/views/form-builder/redux/actionCreator/index.js +1 -1
  79. package/dist/views/form-builder/redux/actionCreator/index.js.map +1 -1
  80. package/dist/views/template-editor/components/EditorSidebar/index.esm.js +1 -1
  81. package/dist/views/template-editor/components/EditorSidebar/index.esm.js.map +1 -1
  82. package/dist/views/template-editor/components/EditorSidebar/index.js +1 -1
  83. package/dist/views/template-editor/components/EditorSidebar/index.js.map +1 -1
  84. package/dist/views/template-editor/templates/index.esm.js +1 -1
  85. package/dist/views/template-editor/templates/index.esm.js.map +1 -1
  86. package/dist/views/template-editor/templates/index.js +1 -1
  87. package/dist/views/template-editor/templates/index.js.map +1 -1
  88. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../../src/utils/common.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport { auth } from \"../constants/auth\";\nimport _ from \"lodash\";\nimport { getV1PartiesId, postV1CurrencyInfo, postV1PartiesCheck } from \"../api-client/api.accounting/api\";\nimport { enqueueSnackbar } from \"notistack\";\nimport { fetchApi } from \"./api\";\nimport formatText from \"./format-text\";\nimport { formatDate } from \"./dateFormat\";\nimport { subModuleMappings, specificFilters } from './export-filters'\nimport parsePhoneNumberFromString from \"libphonenumber-js\";\nimport moment from 'moment-timezone'\nimport { getV1CrossHireRfqResponseItems } from \"../api-client/api.rental/api\";\nimport { getV1RfqResponseItems } from \"../api-client/api.purchase/api\";\nimport { getV1AssemblyItemsId, postV1InventoryItemsCheck } from \"../api-client/api.inventory/api\";\nimport { getV1LocationsCountries } from \"../api-client/api.rbac/api\";\nimport { FieldDisableConfig, INVENTORY_ADD_MODE_DISABLED_FIELDS, INVENTORY_ALWAYS_DISABLED_FIELDS, INVENTORY_EDIT_MODE_DISABLED_FIELDS, INVENTORY_FIELDS_TO_BE_DISABLED, INVENTORY_MATERIAL_COSTING_TYPE_ARR, INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS } from \"./constant\";\n\nexport const isJsonParse = (jsonString?: string) => {\n if (!jsonString) return false;\n try {\n return JSON.parse(jsonString);\n } catch (err) {\n return false;\n }\n};\n\nexport const generateRandomId = (concatString: string = \"\") => {\n const uniqueStringId = `${Date.now()}${concatString}${Math.random()}`.replace(\n \".\",\n \"\"\n );\n const uniqueNumberId = Number(uniqueStringId.replace(concatString, \"\"));\n\n return { uniqueStringId, uniqueNumberId };\n};\n\nexport const generateAndFormatStringFromObj = (\n obj: any = {},\n keysInOrder: string[] = []\n) => {\n let string = \"\";\n\n keysInOrder?.forEach((key) => {\n if (obj?.[key]) {\n string = string ? string + ` ${obj?.[key]}` : obj?.[key];\n }\n });\n\n return string;\n};\n\nexport const generateFields = (fieldsConfig: any) => {\n const defaultOperators = [\n { name: \"null\", label: \"is null\" },\n { name: \"notNull\", label: \"is not null\" },\n ];\n\n const textOperators = [\n { name: \"contains\", label: \"contains\" },\n { name: \"beginsWith\", label: \"begins with\" },\n { name: \"endsWith\", label: \"ends with\" },\n { name: \"doesNotContain\", label: \"does not contain\" },\n { name: \"doesNotBeginWith\", label: \"does not begin with\" },\n { name: \"doesNotEndWith\", label: \"does not end with\" },\n ...defaultOperators,\n ];\n\n const numberOperators = [\n { name: \"=\", label: \"equal to\" },\n { name: \"<\", label: \"less than\" },\n { name: \"<=\", label: \"less than or equal to\" },\n { name: \">\", label: \"greater than\" },\n { name: \">=\", label: \"greater than or equal to\" },\n ...defaultOperators,\n ];\n\n const selectOperators = [\n { name: \"in\", label: \"in\" },\n { name: \"notIn\", label: \"not in\" },\n ...defaultOperators,\n ];\n\n const dropdownOperators = [{ name: \"in\", label: \"in\" }];\n\n const dateOperators = [\n { name: \"=\", label: \"on\" },\n { name: \"!=\", label: \"not on\" },\n { name: \"<\", label: \"before\" },\n { name: \"<=\", label: \"on or before\" },\n { name: \">\", label: \"after\" },\n { name: \">=\", label: \"on or after\" },\n ...defaultOperators,\n ];\n\n // const booleanOperators = [{ name: \"=\", label: \"is\" }];\n\n const getFieldConfig = (field: any) => {\n\n let { type, values } = field;\n const { is_aggregate = false, table = null } = field;\n const { key: name, label, fieldType } = field;\n let operators, valueEditorType, inputType, datatype;\n\n if (field?.enum) {\n type = \"select\";\n\n let fieldArr = field.enum;\n\n if (\n fieldArr &&\n !Array.isArray(fieldArr) &&\n typeof fieldArr === \"object\"\n ) {\n fieldArr = Object.values(fieldArr);\n }\n\n values = fieldArr.map((value) => ({ name: value, label: value }));\n }\n\n if (fieldType === \"select\") {\n type = \"select\";\n\n values = field?.options;\n }\n\n if (field?.boolean) {\n type = \"select\";\n\n values = field?.values || [];\n }\n\n if (field?.table) {\n type = \"table\";\n }\n\n switch (type) {\n case \"string\":\n operators = textOperators;\n valueEditorType = \"text\";\n inputType = \"text\";\n break;\n case \"number\":\n operators = numberOperators;\n valueEditorType = \"text\";\n inputType = \"number\";\n break;\n case \"select\":\n operators = selectOperators;\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n case \"table\":\n operators = dropdownOperators;\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n case \"datetime\":\n operators = dateOperators;\n valueEditorType = \"text\";\n inputType = \"date\";\n datatype = \"date\";\n break;\n case \"date\":\n operators = dateOperators;\n valueEditorType = \"text\";\n inputType = \"date\";\n datatype = \"date\";\n break;\n case \"boolean\":\n operators = [...dropdownOperators, ...defaultOperators];\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n default:\n operators = textOperators;\n valueEditorType = \"text\";\n inputType = \"text\";\n }\n\n return {\n name: name.replace(\"__replaceKey\", ''),\n // name,\n label,\n valueEditorType,\n operators,\n inputType,\n datatype,\n comparator: \"datatype\",\n values,\n is_aggregate,\n table,\n };\n };\n\n return fieldsConfig.filter((f: any) => f.isFilterAllowed && f?.type).map(getFieldConfig);\n};\n\nexport const generateQueryString = (rule: any) => {\n const operatorMap = {\n null: \"eq\",\n notNull: \"ne\",\n contains: \"like\",\n beginsWith: \"like\",\n endsWith: \"like\",\n doesNotContain: \"ne\",\n doesNotBeginWith: \"ne\",\n doesNotEndWith: \"ne\",\n \"<\": \"lt\",\n \"<=\": \"lte\",\n \">\": \"gt\",\n \">=\": \"gte\",\n \"=\": \"eq\",\n \"!=\": \"ne\",\n in: \"in\",\n notIn: \"nin\",\n };\n\n const formatValue = (operator: any, value: any) => {\n if ([\"in\", \"notIn\"].includes(operator)) {\n return `[${value}]`;\n } else if ([\"like\", \"ilike\"].includes(operator)) {\n if (operator === \"beginsWith\") return `${value}%`;\n if (operator === \"endsWith\") return `%${value}`;\n return `%${value}%`;\n } else if (operator === \"null\" || operator === \"notNull\") {\n return \"\";\n } else {\n return value;\n }\n };\n\n const processRules = (rules: any) => {\n return rules.map((rule) => {\n let ruleValue = rule.value;\n if (Array.isArray(ruleValue)) {\n ruleValue = ruleValue.map(rv => {\n if (typeof rv === 'object') {\n rv = rv.name\n }\n return rv\n })\n }\n if (rule.rules) {\n\n const combinator = rule.combinator === \"or\" ? \"|\" : \"&\";\n const nestedRules = processRules(rule.rules);\n return `${nestedRules.join(combinator)}`;\n } else {\n let operator = operatorMap[rule.operator];\n\n if (\n (operator === \"in\" || operator === \"notIn\") &&\n typeof ruleValue === \"string\"\n ) {\n operator = \"eq\";\n }\n\n if (rule.operator === \"null\" || rule.operator === \"notNull\") {\n ruleValue = null;\n }\n\n const value = formatValue(operator, ruleValue);\n if (operator === \"eq\" || operator === \"ne\") {\n return `${rule.field}.${operator}=${value}`;\n }\n return `${rule.field}.${operator}=${value}`;\n }\n });\n };\n\n const combinator = rule.combinator === \"or\" ? \"|\" : \"&\";\n const processedRules = processRules(rule.rules);\n return `(${processedRules.join(combinator)})`.replace(/ /g, \"---\");\n};\n\n\n// export const formatAmount = (\n// \tamount: number | string = '',\n// \tformat: string = '',\n// \tposition: 'after' | 'before' = 'after',\n// \tsymbol?: string\n// ) => {\n\n// \tlet isNegative = false;\n// \tamount = amount.toString();\n// \tif (amount.includes('-')) {\n// \t\tamount = amount.replace('-', '');\n// \t\tisNegative = true;\n// \t}\n\n// \tif (format && amount) {\n// \t\t// Split the format into integer and decimal parts\n// \t\tconst [integerFormat, decFormat] = format.split('.');\n// \t\tlet intFormat: string | string[] = integerFormat;\n// \t\t// Convert amount to string and split into integer and decimal parts\n// \t\tconst [integerAmount, decAmount] = Math.abs(Number(amount))\n// \t\t\t.toFixed(decFormat ? decFormat.length : 0)\n// \t\t\t.toString()\n// \t\t\t.trim()\n// \t\t\t.split('.');\n// \t\tlet intAmount: string | string[] = integerAmount;\n// \t\t// let [intAmount, decAmount] = Math.abs(amount).toFixed(decFormat ? decFormat.length : 0).split('.');\n\n// \t\tconst am = intAmount.split('').reverse().join('');\n// \t\tconst formatArr: string[] = intFormat.split(',').reverse();\n\n// \t\tif (intFormat.length !== 1) {\n// \t\t\twhile (formatArr.join('').length < am.length) {\n// \t\t\t\tif (formatArr.length >= 2) {\n// \t\t\t\t\tformatArr.splice(1, 0, formatArr[1]);\n// \t\t\t\t} else {\n// \t\t\t\t\tformatArr.push(formatArr[formatArr.length - 1]);\n// \t\t\t\t}\n// \t\t\t}\n// \t\t} else {\n// \t\t\tconst formatZeroIndex = am?.split('')?.reduce((lv: string) => {\n// \t\t\t\treturn lv + '#';\n// \t\t\t}, '');\n\n// \t\t\tformatArr[0] = formatZeroIndex;\n// \t\t}\n\n// \t\tintFormat = formatArr.join(',').split('');\n\n// \t\t// Reverse the integer amount and format for easier processing from right to left\n// \t\tintAmount = intAmount.split('').reverse();\n\n// \t\tlet formattedInt = '';\n// \t\tlet intIndex = 0;\n// \t\tfor (let i = 0; i < intFormat.length; i++) {\n// \t\t\tif (intFormat[i] === '#') {\n// \t\t\t\tformattedInt +=\n// \t\t\t\t\tintAmount[intIndex] !== undefined ? intAmount[intIndex++] : '';\n// \t\t\t} else if (intFormat[i] === ',') {\n// \t\t\t\tformattedInt += intIndex > 0 ? ',' : '';\n// \t\t\t} else {\n// \t\t\t\tformattedInt += intFormat[i];\n// \t\t\t}\n// \t\t}\n\n// \t\t// Reverse back to the original order\n// \t\tformattedInt = formattedInt.split('').reverse().join('');\n\n// \t\t// Handle the decimal part\n// \t\tlet formattedDec = '';\n// \t\tif (decFormat && decAmount) {\n// \t\t\tfor (let i = 0; i < decFormat.length; i++) {\n// \t\t\t\tformattedDec +=\n// \t\t\t\t\tdecFormat[i] === '#'\n// \t\t\t\t\t\t? decAmount[i] !== undefined\n// \t\t\t\t\t\t\t? decAmount[i]\n// \t\t\t\t\t\t\t: ''\n// \t\t\t\t\t\t: decFormat[i];\n// \t\t\t}\n// \t\t}\n\n// \t\twhile (formattedInt?.startsWith(',')) {\n// \t\t\tformattedInt = formattedInt.replace(',', '');\n// \t\t}\n\n// \t\t// Combine integer and decimal parts\n// \t\tlet formattedAmount = formattedInt;\n// \t\tif (formattedDec) {\n// \t\t\tformattedAmount += '.' + formattedDec;\n// \t\t}\n\n// \t\t// Add negative sign if the amount is negative\n// \t\tif (isNegative) {\n// \t\t\tformattedAmount = '-' + formattedAmount;\n// \t\t}\n\n// \t\t// Add symbol on specific position\n// \t\tif (symbol && position) {\n\n// \t\t\tif (position === 'after') {\n// \t\t\t\tformattedAmount = formattedAmount + ' ' + symbol;\n// \t\t\t} else if (position === 'before') {\n// \t\t\t\tformattedAmount = symbol + ' ' + formattedAmount;\n// \t\t\t}\n// \t\t}\n// \t\treturn formattedAmount;\n// \t}\n\n// \treturn isNegative ? '-' + amount : amount;\n// };\n\n\nexport const getOperatorLabel = (rule: any, filterFields: any[]) => {\n const defaultOperators = [\n { name: 'null', label: 'Is null' },\n { name: 'notNull', label: 'Is not null' }\n ];\n\n const textOperators = [\n { name: 'contains', label: 'Contains' },\n { name: 'beginsWith', label: 'Begins with' },\n { name: 'endsWith', label: 'Ends with' },\n { name: 'doesNotContain', label: 'Does not contain' },\n { name: 'doesNotBeginWith', label: 'Does not begin with' },\n { name: 'doesNotEndWith', label: 'Does not end with' },\n ...defaultOperators\n ];\n\n const numberOperators = [\n { name: '=', label: 'Equal to' },\n { name: '<', label: 'Less than' },\n { name: '<=', label: 'Less than or equal to' },\n { name: '>', label: 'Greater than' },\n { name: '>=', label: 'Greater than or equal to' },\n ...defaultOperators\n ];\n\n const selectOperators = [\n { name: 'in', label: 'In' },\n { name: 'notIn', label: 'Not in' },\n ...defaultOperators\n ];\n\n const dropdownOperators = [{ name: 'in', label: 'In' }];\n\n const dateOperators = [\n { name: '=', label: 'On' },\n { name: '!=', label: 'Not on' },\n { name: '<', label: 'Before' },\n { name: '<=', label: 'On or before' },\n { name: '>', label: 'After' },\n { name: '>=', label: 'On or after' },\n ...defaultOperators\n ];\n\n const booleanOperators = [{ name: '=', label: 'is' }, ...defaultOperators];\n const { field: rField, operator } = rule;\n const field = filterFields?.find(\n (ff) => ff.key.replace('__replaceKey', '') == rField\n );\n let operatorLable = '';\n if (field) {\n let { type } = field || {};\n // const { is_aggregate = false, table = null } = field || {};\n const { fieldType } = field;\n\n if (field?.enum) {\n type = 'select';\n }\n\n if (fieldType === 'select') {\n type = 'select';\n }\n\n if (field?.boolean) {\n type = 'select';\n }\n\n if (field?.table) {\n type = 'table';\n }\n\n switch (type) {\n case 'string':\n operatorLable =\n textOperators.find((to) => to.name == operator)?.label || '';\n break;\n case 'number':\n operatorLable =\n numberOperators.find((no) => no.name == operator)?.label || '';\n break;\n case 'select':\n operatorLable =\n selectOperators.find((so) => so.name == operator)?.label || '';\n break;\n case 'table':\n operatorLable =\n dropdownOperators.find((dwo) => dwo.name == operator)?.label || '';\n break;\n case 'datetime':\n operatorLable =\n dateOperators.find((dto) => dto.name == operator)?.label || '';\n break;\n case 'date':\n operatorLable =\n dateOperators.find((dto) => dto.name == operator)?.label || '';\n break;\n case 'boolean':\n operatorLable =\n booleanOperators.find((bo) => bo.name == operator)?.label || '';\n break;\n }\n }\n\n return operatorLable;\n};\n\nexport const formatAmount = (\n amount: number | string = \"\",\n format: string = \"\",\n position: \"after\" | \"before\" = \"before\",\n symbol?: string\n): string => {\n if (amount === \"\" || amount === null || amount === undefined) {\n amount = 0;\n }\n\n if (typeof amount === \"string\") {\n amount = parseFloat(amount.replace(/[^\\d.-]/g, \"\"));\n if (isNaN(amount)) return \"\";\n }\n\n const num = parseFloat((amount as number).toFixed(2));\n\n let formatter: Intl.NumberFormat;\n\n switch (format) {\n case \"#,###.##\":\n formatter = new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#.###,##\":\n formatter = new Intl.NumberFormat(\"de-DE\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"# ###.##\":\n formatter = new Intl.NumberFormat(\"fr-FR\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"# ###,##\":\n formatter = new Intl.NumberFormat(\"es-ES\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#’ ###. ##\":\n formatter = new Intl.NumberFormat(\"de-CH\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#, ###.##\":\n formatter = new Intl.NumberFormat(\"en-GB\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n default:\n formatter = new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n }\n\n let formattedAmount = formatter.format(num);\n\n // Handle specific spacing for formats\n if (format === \"# ###.##\" || format === \"# ###,##\") {\n formattedAmount = formattedAmount.replace(/\\u00A0/g, \" \");\n }\n if (format === \"#’ ###. ##\") {\n formattedAmount = formattedAmount.replace(/\\u00A0/g, \" \").replace(/'/g, \"’\");\n }\n if (format === \"#, ###.##\") {\n formattedAmount = formattedAmount.replace(/,/g, \", \");\n }\n\n if (symbol) {\n return position === \"after\"\n ? `${formattedAmount} ${symbol}`\n : `${symbol} ${formattedAmount}`;\n }\n\n return formattedAmount;\n};\n\n\nexport const filterCoaByCompanyIdOrNull = (\n allCoa: any[],\n { companyId }: { companyId?: number | string | null | any[] }\n) => {\n if (!allCoa?.length) return [];\n\n return allCoa.filter((coa) => {\n if (companyId) {\n const ic = Array.isArray(companyId)\n ? companyId.map(Number)\n : [Number(companyId)];\n return !coa.company_ids || coa.company_ids.some((c) => ic.includes(c.id));\n }\n return !coa.company_ids;\n });\n};\n\n// type DiscountDueDateBasedOn = \"DAYS_AFTER_INVOICE_DATE\" | \"DAYS_AFTER_INVOICE_MONTH\" | \"MONTHS_AFTER_INVOICE_MONTH\";\n\nexport const validateDiscountValidity = (\n date,\n discountDueDateBasedOn,\n discountValidity\n) => {\n const currentDate = new Date();\n const dateObj = new Date(date);\n let discountEndDate;\n\n switch (discountDueDateBasedOn) {\n case \"DAYS_AFTER_INVOICE_DATE\":\n discountEndDate = new Date(dateObj);\n discountEndDate.setDate(\n discountEndDate.getDate() + parseInt(discountValidity)\n );\n break;\n case \"DAYS_AFTER_INVOICE_MONTH\":\n discountEndDate = new Date(\n dateObj.getFullYear(),\n dateObj.getMonth() + 1,\n parseInt(discountValidity)\n );\n break;\n case \"MONTHS_AFTER_INVOICE_MONTH\":\n discountEndDate = new Date(dateObj);\n discountEndDate.setMonth(\n discountEndDate.getMonth() + parseInt(discountValidity)\n );\n discountEndDate = new Date(\n discountEndDate.getFullYear(),\n discountEndDate.getMonth() + 1,\n 0\n ); // End of the month\n break;\n default:\n throw new Error(\"Invalid discount_due_date_based_on value\");\n }\n\n return currentDate <= discountEndDate;\n};\n\nconst token = localStorage.getItem(auth.storageTokenKeyName) || undefined;\nexport const postImportSheet = async (request: any, moduleName: string) => {\n\n let mainModule = window.location.pathname.split('/')[2]\n const subModuleName = window.location.pathname.split('/')[3]\n console.log(\"mainModule\", mainModule, moduleName)\n let type = ''\n if (mainModule == \"crm\") {\n mainModule = \"sales\"\n }\n if (mainModule == \"procurement\") {\n mainModule = \"purchase\"\n }\n if (mainModule == 'rental' && subModuleName == 'item') {\n mainModule = 'inventory'\n }\n if (mainModule == 'rental' && moduleName == 'quotation') {\n moduleName = 'rental-quotations'\n }\n if (mainModule == 'rental' && moduleName == 'lead') {\n moduleName = 'rental-lead'\n }\n if (mainModule == 'rental' && moduleName == 'rfq') {\n mainModule = 'purchase'\n }\n if (mainModule == 'rental' && moduleName == 'purchase-orders') {\n mainModule = 'purchase'\n }\n if (mainModule == 'rental' && moduleName == 'opportunity') {\n moduleName = 'rental-opportunity'\n }\n\n if (moduleName == 'collection-entries') {\n moduleName = 'payment-entries'\n type = 'receive'\n }\n\n\n\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}/${mainModule}`;\n\n const headers = {};\n\n headers[\"x-token\"] = token;\n // headers['Content-type'] = 'application/json; charset=utf-8';\n\n const response = await fetch(`${baseUrl}/v1/${moduleName}/import${type ? `?type=${type}` : ''}`, {\n method: \"POST\",\n body: request,\n headers,\n });\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response.json();\n};\n\nexport const getExcelTemplateGenerateTemplate = async (request: any) => {\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}/accounting`;\n\n const headers = {};\n\n if (request[\"x-token\"] !== undefined) {\n headers[\"x-token\"] = request[\"x-token\"];\n delete request[\"x-token\"];\n }\n if (request[\"Content-Type\"] !== undefined) {\n headers[\"Content-Type\"] = request[\"Content-Type\"];\n delete request[\"Content-Type\"];\n }\n console.log(\"request\", request.resource)\n const response = await fetch(\n `${baseUrl}/v1/excel-template/generate-template?resource=${request.resource.toString()}`,\n {\n headers,\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response;\n};\n\n\nexport const getExcelExportTemplate = async (request: any) => {\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}`;\n\n const headers = {};\n\n if (request[\"x-token\"] !== undefined) {\n headers[\"x-token\"] = request[\"x-token\"];\n delete request[\"x-token\"];\n }\n if (request[\"Content-Type\"] !== undefined) {\n headers[\"Content-Type\"] = request[\"Content-Type\"];\n delete request[\"Content-Type\"];\n }\n const pathParts = window.location.pathname.split(\"/\");\n const currentPath = pathParts.pop();\n const currentModule = pathParts[3];\n let moduleName = pathParts[2];\n console.log(\"selectedIds\", request)\n console.log(\"moduleName\", moduleName, currentPath, currentModule)\n if (currentPath == \"demand-planning\") {\n moduleName = \"purchase\"\n }\n if (moduleName == \"crm\") {\n moduleName = \"sales\"\n }\n if (moduleName == \"procurement\") {\n moduleName = \"purchase\"\n }\n let combinedFilters = \"\";\n const excelpath = \"generate-excel\";\n if (currentPath && specificFilters[currentPath]) {\n combinedFilters = specificFilters[currentPath];\n }\n if (currentPath === \"items\" || currentPath === 'item') {\n if (request?.title && request?.title == \"Non Inventory\") {\n request.title = \"non-inventory\"\n } else if (request?.title && request?.title == \"Assembly (Finished product)\") {\n request.title = \"assembly\"\n }\n combinedFilters += `&type.eq=${request?.title.toLowerCase()}`\n }\n if (request.filterQueryString) {\n const cleanedFilterQueryString = request.filterQueryString.replace(/[{}()]/g, \"\");\n if (combinedFilters) {\n combinedFilters = `(${combinedFilters}&${cleanedFilterQueryString})`;\n } else {\n combinedFilters = `(${cleanedFilterQueryString})`;\n }\n } else {\n combinedFilters = `(${combinedFilters})`;\n }\n if (combinedFilters.includes(\"is_variant.eq=false|self_variant.eq=true\")) {\n if (moduleName == \"rental\") {\n combinedFilters = combinedFilters.replace(\"is_variant.eq=false|self_variant.eq=true\", \"(is_variant.eq=false|self_variant.eq=true&is_rental.eq=1)\");\n } else {\n combinedFilters = combinedFilters.replace(\"is_variant.eq=false|self_variant.eq=true\", \"(is_variant.eq=false|self_variant.eq=true)\");\n }\n }\n\n\n\n if (currentPath && !specificFilters[currentPath] && !request.filterQueryString) {\n combinedFilters = \"\"\n }\n\n let subModuleName = subModuleMappings[currentPath || \"\"] || currentPath;\n console.log(\"combinedFiltersNEWWWWWWWWWW\", moduleName, subModuleName, combinedFilters)\n if (moduleName == \"sales\" && subModuleName == \"quotation\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == \"sales\" && subModuleName == \"sales-orders\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == \"rental\" && subModuleName == \"rental-lead\") {\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == \"sales\" && subModuleName == \"lead\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n\n if (\n moduleName === \"purchase\" &&\n (subModuleName === \"purchase-requests\" || subModuleName === \"rfq\" || subModuleName === \"purchase-orders\")\n ) {\n combinedFilters = '(is_rental.eq=0)';\n }\n\n if (moduleName == \"rental\" && subModuleName == \"quotation\") {\n console.log(\"rental quotation::::::::::::::::::;\")\n subModuleName = \"rental-quotations\"\n }\n if (moduleName == \"rental\" && subModuleName == \"opportunity\") {\n subModuleName = \"rental-opportunity\"\n }\n if (moduleName == 'rental' && subModuleName == 'item') {\n moduleName = \"inventory\"\n subModuleName = 'inventory-items'\n }\n if (moduleName == 'rental' && subModuleName == 'category') {\n moduleName = \"inventory\"\n subModuleName = 'category-items'\n }\n if (moduleName == 'rental' && subModuleName == 'purchase-requests') {\n subModuleName = 'cross-hire-requests'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'rfq' && currentModule != 'purchase') {\n subModuleName = 'cross-hire-rfq'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'rfq' && currentModule == 'purchase') {\n moduleName = 'purchase'\n combinedFilters = '(is_rental.eq=0)'\n }\n\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title !== 'Rental Orders' && request.title !== 'Replacement Orders') {\n console.log(\"combinedFilters\", combinedFilters);\n subModuleName = 'cross-hire-orders'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && (subModuleName == 'orders' || subModuleName == 'cross-hire-orders') && currentModule == 'purchase') {\n moduleName = 'purchase'\n subModuleName = \"purchase-orders\"\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'rental-quotations' && request.title == \"Quotations\") {\n combinedFilters = '(is_visible.eq=1&is_rental.eq=1&is_replacement.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'rental-quotations' && request.title == \"Replacement Quotations\") {\n combinedFilters = '(is_visible.eq=1&is_rental.eq=1&is_replacement.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title == 'Rental Orders') {\n subModuleName = 'rental-orders'\n combinedFilters = '(is_rental.eq=1&is_replacement.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title == 'Replacement Orders') {\n subModuleName = 'rental-orders'\n combinedFilters = '(is_rental.eq=1&is_replacement.eq=1)'\n }\n console.log(\"moduleName\", moduleName, subModuleName, request.title)\n const queryParams: Record<string, string> = {};\n if (request.selectedIds && combinedFilters) {\n if (request.selectedIds.length > 0) {\n combinedFilters = `(${combinedFilters}&id.in=${request.selectedIds})`;\n }\n } else if (request.selectedIds) {\n if (request.selectedIds.length > 0) {\n combinedFilters = `(id.in=${request.selectedIds})`;\n }\n }\n if (combinedFilters) {\n queryParams.filters = combinedFilters;\n }\n const queryString = new URLSearchParams(queryParams).toString();\n const response = await fetch(\n `${baseUrl}/${moduleName}/v1/${subModuleName}/${excelpath}${queryString ? `?${queryString}` : \"\"\n }`,\n {\n headers,\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response;\n};\n\nexport const removeIdStaticIdsFromMongoObject = (data: any) => {\n const newData = data.map((ele: { _id: string | number }) => {\n if (typeof ele._id === \"number\") {\n return { ...ele, _id: null };\n }\n return ele;\n });\n\n return newData;\n};\n\n/**\n * * FILE UPLOAD\n */\nconst spliceUploadedLocation = (uploadedlocation: string) => {\n const splitLocation = uploadedlocation.split(\"/\");\n if (splitLocation.length) {\n splitLocation.splice(0, splitLocation.length - 2);\n return splitLocation.join(\"/\");\n }\n\n return uploadedlocation;\n};\n\n/**\n * Fetch with retry logic for network resilience\n */\nasync function fetchWithRetry(\n url: string,\n options: RequestInit,\n maxRetries: number,\n retryDelay: number\n): Promise<Response> {\n let lastError: Error;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n\n // If it's a server error (5xx), retry\n if (response.status >= 500 && attempt < maxRetries) {\n throw new Error(`Server error: ${response.status} ${response.statusText}`);\n }\n\n return response;\n } catch (error: any) {\n lastError = error;\n\n // Don't retry for abort signals or client errors (4xx)\n if (error.name === 'AbortError') {\n throw error;\n }\n\n if (attempt < maxRetries) {\n const delay = retryDelay * Math.pow(2, attempt); // Exponential backoff\n console.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms...`, error.message);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError!;\n}\n\n/**\n * Helper function to format file size in human-readable format\n */\nfunction formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n// Interface declarations moved to exported section below\nexport interface UploadOptions {\n onProgress?: (progress: ProgressInfo) => void;\n chunkSize?: number;\n retryAttempts?: number;\n retryDelay?: number;\n}\n\nexport interface ProgressInfo {\n fileName: string;\n progress: number;\n bytesUploaded: number;\n totalBytes: number;\n fileIndex?: number;\n totalFiles?: number;\n}\n\nexport interface FileUploadResponse {\n data: {\n preSignedData: {\n uploadId: string;\n fileName: string;\n preSignedUrls: Array<{\n partNumber: number;\n presignedUrl: string;\n }>;\n location?: string;\n presignedUrl?: string; // For single part uploads\n };\n };\n}\n\nexport interface CompleteUploadResponse {\n data: {\n location: string;\n };\n}\n\nexport interface UploadPart {\n partNumber: number;\n etag: string;\n}\n\nexport const handleRegularUpload = async (\n files: File[],\n controller: AbortController,\n module: string,\n options: UploadOptions = {}\n): Promise<string[]> => {\n const BASE_URL = `${import.meta.env.VITE_BACKEND_BASE_URL}/${module}/v1/file-upload/`;\n const COMPLETE_BASE_URL = `${import.meta.env.VITE_BACKEND_BASE_URL}/${module}/v1/file-upload/mark-complete`;\n const authToken = localStorage.getItem(auth.storageTokenKeyName);\n\n const {\n onProgress,\n chunkSize = 5 * 1024 * 1024, // 5MB default chunk size (S3 minimum for multipart)\n retryAttempts = 3,\n retryDelay = 1000\n } = options;\n\n if (!authToken) {\n throw new Error('Authentication token not found. Please log in again.');\n }\n\n // Validate chunk size for multipart uploads\n // if (chunkSize < 1024 * 1024) {\n // console.warn('Chunk size less than 5MB may cause issues with S3 multipart uploads');\n // }\n\n try {\n const uploaded: string[] = [];\n\n // Process files sequentially to maintain order and avoid overwhelming the server\n for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {\n const file = files[fileIndex];\n\n if (controller.signal.aborted) {\n throw new Error('Upload cancelled by user');\n }\n\n console.log(`🚀 Uploading file ${fileIndex + 1}/${files.length}:`, file.name, `(${formatFileSize(file.size)})`);\n\n try {\n const uploadedLocation = await uploadSingleFile(\n file,\n fileIndex,\n files.length,\n controller,\n BASE_URL,\n COMPLETE_BASE_URL,\n authToken,\n chunkSize,\n retryAttempts,\n retryDelay,\n onProgress\n );\n\n uploaded.push(uploadedLocation);\n console.log(`✅ Successfully uploaded: ${file.name}`);\n\n } catch (fileError: any) {\n console.error(`❌ Failed to upload ${file.name}:`, fileError.message);\n throw new Error(`Failed to upload ${file.name}: ${fileError.message}`);\n }\n }\n\n return uploaded;\n } catch (error: any) {\n console.error('❌ Upload process failed:', error.message);\n throw new Error(error.message || 'Upload failed');\n }\n};\n\nconst uploadSingleFile = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n controller: AbortController,\n baseUrl: string,\n completeUrl: string,\n authToken: string,\n chunkSize: number,\n retryAttempts: number,\n retryDelay: number,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n const isMultipart = file.size > chunkSize;\n const totalParts = isMultipart ? Math.ceil(file.size / chunkSize) : 1;\n\n // Step 1: Get pre-signed URLs\n console.log(`📋 Requesting ${totalParts} pre-signed URLs for ${file.name}`);\n\n const preSignedResponse = await fetchWithRetry(\n `${baseUrl}?key=${encodeURIComponent(file.name)}&partCount=${totalParts}&mimeType=${encodeURIComponent(file.type)}`,\n {\n method: 'GET',\n headers: {\n \"Content-Type\": \"application/json\",\n \"file-size\": file.size.toString(),\n \"x-token\": authToken,\n },\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!preSignedResponse.ok) {\n const errorData = await preSignedResponse.json().catch(() => ({}));\n throw new Error(`Failed to get pre-signed URL: ${errorData.message || preSignedResponse.statusText}`);\n }\n\n const pData: FileUploadResponse = await preSignedResponse.json();\n const preSignedData = pData?.data?.preSignedData;\n\n if (!preSignedData) {\n throw new Error('Invalid pre-signed URL response format');\n }\n\n const { uploadId, preSignedUrls, presignedUrl, location } = preSignedData;\n\n // Step 2: Upload file parts\n if (isMultipart) {\n return await handleMultipartUpload(\n file,\n fileIndex,\n totalFiles,\n uploadId,\n preSignedUrls,\n controller,\n completeUrl,\n authToken,\n chunkSize,\n retryAttempts,\n retryDelay,\n onProgress\n );\n } else {\n return await handleSinglePartUpload(\n file,\n fileIndex,\n totalFiles,\n presignedUrl || preSignedUrls?.[0]?.presignedUrl,\n location,\n controller,\n onProgress\n );\n }\n};\n\nconst handleSinglePartUpload = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n presignedUrl: string,\n location: string | undefined,\n controller: AbortController,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n if (!presignedUrl) {\n throw new Error('No presigned URL provided for single part upload');\n }\n\n console.log(`📤 Uploading single part for ${file.name}`);\n\n const response = await fetch(presignedUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": file.type || \"application/octet-stream\",\n \"Content-Length\": file.size.toString(),\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Single part upload failed: ${response.statusText}`);\n }\n\n // Report completion\n onProgress?.({\n fileName: file.name,\n progress: 100,\n bytesUploaded: file.size,\n totalBytes: file.size,\n fileIndex: fileIndex + 1,\n totalFiles\n });\n\n if (!location) {\n throw new Error('No location provided for single part upload');\n }\n\n return spliceUploadedLocation(location);\n};\n\nconst handleMultipartUpload = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n uploadId: string,\n preSignedUrls: Array<{ partNumber: number; presignedUrl: string }>,\n controller: AbortController,\n completeUrl: string,\n authToken: string,\n chunkSize: number,\n retryAttempts: number,\n retryDelay: number,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n if (!uploadId || !preSignedUrls || preSignedUrls.length === 0) {\n throw new Error('Invalid multipart upload data: missing uploadId or preSignedUrls');\n }\n\n console.log(`📤 Starting multipart upload for ${file.name} (${preSignedUrls.length} parts)`);\n\n const uploadedParts: UploadPart[] = [];\n let totalBytesUploaded = 0;\n\n // Upload each part\n for (let i = 0; i < preSignedUrls.length; i++) {\n if (controller.signal.aborted) {\n throw new Error('Upload cancelled by user');\n }\n\n const { partNumber, presignedUrl } = preSignedUrls[i];\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, file.size);\n const chunk = file.slice(start, end);\n\n console.log(`📦 Uploading part ${partNumber}/${preSignedUrls.length} (${start}-${end})`);\n\n try {\n const partResponse = await fetchWithRetry(\n presignedUrl,\n {\n method: \"PUT\",\n body: chunk,\n headers: {\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": chunk.size.toString(),\n },\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!partResponse.ok) {\n throw new Error(`Part ${partNumber} upload failed: ${partResponse.statusText}`);\n }\n\n // Extract ETag from response headers (required for completion)\n // const etag = partResponse.headers.get('ETag');\n // if (!etag) {\n // throw new Error(`Part ${partNumber} upload succeeded but no ETag received`);\n // }\n\n uploadedParts.push({\n partNumber\n });\n\n totalBytesUploaded += chunk.size;\n\n // Report progress\n const progress = Math.round((totalBytesUploaded / file.size) * 100);\n onProgress?.({\n fileName: file.name,\n progress,\n bytesUploaded: totalBytesUploaded,\n totalBytes: file.size,\n fileIndex: fileIndex + 1,\n totalFiles\n });\n\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('Upload cancelled by user');\n }\n throw new Error(`Failed to upload part ${partNumber}: ${error.message}`);\n }\n }\n\n // Step 3: Complete the multipart upload\n console.log(`🔗 Completing multipart upload for ${file.name}`);\n\n // Sort parts by part number to ensure correct order\n uploadedParts.sort((a, b) => a.partNumber - b.partNumber);\n\n const completeResponse = await fetchWithRetry(\n completeUrl,\n {\n method: 'POST',\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-token\": authToken,\n },\n body: JSON.stringify({\n fileName: file.name,\n uploadId: uploadId,\n //parts: uploadedParts // Include the uploaded parts with ETags\n }),\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!completeResponse.ok) {\n const errorData = await completeResponse.json().catch(() => ({}));\n throw new Error(`Failed to complete multipart upload: ${errorData.message || completeResponse.statusText}`);\n }\n\n const completeData: CompleteUploadResponse = await completeResponse.json();\n\n if (!completeData.data?.location) {\n throw new Error('Invalid completion response format - no location received');\n }\n\n return spliceUploadedLocation(completeData.data.location);\n};\n\n/**\n * Main upload function - handles file validation and orchestrates the upload process\n * @param files - Single file or array of files to upload\n * @param module - Module name for the upload endpoint (default: \"sales\")\n * @param options - Optional upload configuration\n * @returns Promise<string[]> - Array of uploaded file locations\n */\nexport const uploadFiles = async (\n files: any,\n module = \"sales\",\n options: UploadOptions = {}\n): Promise<string[]> => {\n if (Array.isArray(files) && files?.filter(i => i)?.length === 0) return [];\n try {\n let uFiles: string[] = [];\n const bUrl = import.meta.env.VITE_S3_BUCKET_URL;\n const bUrl2 = bUrl?.replace(\"https://\", \"\");\n\n const controller = new AbortController();\n\n // Normalize input to array and filter valid files\n const iFiles = files ? (Array.isArray(files) ? files : [files]) : [];\n\n const existingFiles = iFiles.filter((file) => !(file instanceof File));\n if (iFiles && iFiles.length) {\n // Filter to ensure only File objects are processed\n const validFiles = iFiles.filter((file) => file instanceof File);\n\n if (validFiles && validFiles.length) {\n console.log(`📁 Starting upload of ${validFiles.length} file(s) to module: ${module}`);\n uFiles = await handleRegularUpload(validFiles, controller, module, options);\n console.log(`✅ Successfully uploaded ${uFiles.length} file(s)`);\n } else {\n console.warn('⚠️ No valid File objects found in the provided input');\n }\n }\n\n return [...uFiles, ...existingFiles]?.map(f => f?.split(bUrl)?.join('')?.split(bUrl2)?.join(''))?.filter(Boolean) || [];\n } catch (error) {\n let errorMessage: string = \"Something went wrong during file upload.\";\n\n if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n console.error('❌ Upload failed:', errorMessage);\n throw new Error(errorMessage);\n }\n};\n\nexport const formatDateForPayload = (date: any) =>\n date && dayjs(date).isValid() ? dayjs(date).format(\"YYYY-MM-DD\") : undefined;\n\nexport const formatTimeForPayload = (date: any) =>\n date && dayjs(date).isValid() ? dayjs(date).format(\"HH:mm:ss\") : undefined;\n\nexport const formatDateTimeForPayload = (date: any) =>\n (date && dayjs(date).isValid()) ? dayjs(date).format(\"YYYY-MM-DD HH:mm:ss\") : undefined;\n\nexport function isJSONString(str: string | undefined) {\n if (!str) return false;\n\n try {\n return JSON.parse(str);\n } catch (e) {\n return false;\n }\n}\n\nexport const getErrorMessage = (error?: any) => {\n if (error instanceof Error) return error.message;\n else if (isJSONString(error)?.message) return isJSONString(error)?.message;\n else if (typeof error === 'string') return error;\n else return \"Something went wrong\";\n};\n\nexport const InvoiceStatus = {\n Approved: \"Approve\",\n Rejected: \"Reject\",\n};\n\n/**\n * Get the default currency symbol from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param currencyData - Optional pre-fetched currency data to avoid localStorage lookup\n */\nexport const defaultCurrencySymbol = (currencyData?: { symbol?: string }) => {\n if (currencyData?.symbol) {\n return currencyData.symbol;\n }\n try {\n const userData = JSON.parse(localStorage.getItem('user') || '{}');\n return userData?.currency_data?.symbol || \"\";\n } catch {\n return \"\";\n }\n};\n\n/**\n * Get the default currency format from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param currencyData - Optional pre-fetched currency data to avoid localStorage lookup\n */\nexport const defaultCurrencyFormat = (currencyData?: { number_format?: string }) => {\n if (currencyData?.number_format) {\n return currencyData.number_format;\n }\n try {\n const userData = JSON.parse(localStorage.getItem('user') || '{}');\n return userData?.currency_data?.number_format || \"\";\n } catch {\n return \"\";\n }\n};\n\n/**\n * Get the default company from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param userData - Optional pre-fetched user data to avoid localStorage lookup\n */\nexport const defaultCompany = (userData?: { accessCompanies?: number[]; company_id?: number | null }) => {\n let user = userData;\n if (!user) {\n try {\n user = JSON.parse(localStorage.getItem('user') || '{}');\n } catch {\n return null;\n }\n }\n const accessCompanies = user?.accessCompanies || [];\n const defaultCompanyId = user?.company_id || null;\n\n let dcId = defaultCompanyId;\n\n if (Array.isArray(accessCompanies) && accessCompanies?.length > 0) {\n if (!accessCompanies?.includes(defaultCompanyId as number)) {\n dcId = accessCompanies?.[0];\n }\n }\n\n return dcId ? Number(dcId) : null;\n};\n\nexport function omitDataKeys<T>(obj: T, extra?: Array<string>): T {\n // Default keys to omit\n const defaultOmitKeys = [\n \"created_at\",\n \"updated_at\",\n \"created_by\",\n \"created_user\",\n \"updated_by\",\n \"updated_user\",\n \"is_deleted\",\n \"deleted_user\",\n \"deleted_by\",\n \"deleted_at\",\n ...(extra ? extra : []),\n ];\n\n // Handle arrays separately without converting them to objects\n if (Array.isArray(obj)) {\n // Recursively process array elements\n return obj.map((item) => omitDataKeys(item, extra)) as unknown as T;\n }\n\n // Check if obj is an object\n if (_.isObject(obj) && !Array.isArray(obj)) {\n // Recursively apply omit on each property of the object\n return _.mapValues(\n _.omitBy(\n obj,\n (_, key) =>\n defaultOmitKeys.includes(key) ||\n key.endsWith(\"_data\") ||\n key.endsWith(\"_status\")\n ),\n (value) => {\n // Recurse on nested objects, excluding Day.js instances\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return omitDataKeys(value, extra);\n }\n return value;\n }\n ) as T;\n }\n\n // If it's neither an object nor an array, return the value as is (e.g., strings, numbers)\n return obj;\n}\n\n// Define a type for the input objects in the array\nexport interface DataObject {\n [key: string]: any;\n}\n\n// Define a type for the processed object with label and value\nexport interface LabelValueObject extends DataObject {\n label: string;\n value: string | number | null;\n}\n\n/**\n * A global function to process an array of objects and return formatted label-value pairs.\n *\n * @param {Array<T>} dataArray - The array of objects to be processed.\n * @param {Array<T>} fallbackArray - The fallback array if dataArray is empty.\n * @param {Array<keyof T | string>} labelKeys - The keys to be concatenated for the label.\n * @param {keyof T | string} valueKey - The key to be used for the value.\n * @param {Function} [labelFormatter] - Optional custom formatter for label.\n * @returns {Array<LabelValueObject>} - The processed array of label-value objects.\n */\nexport const getLabelValuePairs = <T extends DataObject>(\n dataArray: T[],\n fallbackArray: T[],\n labelKeys: (keyof T | string)[],\n valueKey: keyof T | string,\n labelFormatter?: (item: T) => string\n): LabelValueObject[] => {\n return (\n _.map(dataArray, (item: T) => {\n const label = labelFormatter\n ? labelFormatter(item)\n : _.compact(labelKeys.map((key) => _.get(item, key, \"\"))).filter(v => Boolean(v?.trim())).join(\", \");\n\n return {\n ...item,\n label,\n value: _.get(item, valueKey, null),\n };\n }) || fallbackArray\n );\n};\nexport function formatEmptyDataToNull<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatEmptyDataToNull(item)) as unknown as T;\n }\n\n // If it's an object, iterate through the values and apply transformations\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n // Recursively handle nested objects or arrays\n if (\n Array.isArray(value)\n ) {\n return (value);\n }\n if (\n _.isObject(value) &&\n !dayjs.isDayjs(value) &&\n !(value instanceof File)\n ) {\n return formatEmptyDataToNull(value);\n }\n\n // Replace empty values (except 0) with null\n if (!value && value !== 0 && value !== false) {\n return null;\n }\n\n // Special handling for specific key patterns\n if (\n (key.includes(\"_id\") && !key.includes(\"_ids\")) ||\n key.includes(\"_amount\")\n ) {\n // Convert values for '_id' or '_amount' keys to numbers\n return Array.isArray(value) ? value.map(Number) : Number(value);\n } else if (key.includes(\"date_time\")) {\n // Format date fields\n return formatDateTimeForPayload(value);\n } else if (key.includes(\"date\")) {\n // Format date fields\n return formatDateForPayload(value);\n } else if (key.includes(\"_time\")) {\n // Format time fields\n return formatTimeForPayload(value);\n } else if (Array.isArray(value)) {\n // Ensure arrays are not replaced by null if they're empty\n return value.length ? value : [];\n }\n\n // Return the original value if no other transformation applies\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\nexport function downloadFile(fileUrl: string, fileName = \"\") {\n console.log(fileUrl);\n if (!fileUrl || fileUrl === \"\") return;\n const a = document.createElement(\"a\");\n a.target = \"_blank\";\n a.href = fileUrl;\n a.download = fileName;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n}\n\n//Download Doc\n//eslint-disable-next-line\nexport const downloadDoc = async ({\n api,\n // fileName,\n raw\n}: {\n api: string,\n fileName: string,\n raw: any\n}) => {\n const headers = {\n \"Content-Type\": \"application/json\",\n ...getToken()\n };\n const response = await fetch(`${import.meta.env.VITE_BACKEND_BASE_URL}/${api}`,\n {\n method: \"POST\",\n headers,\n body: raw,\n redirect: \"follow\",\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n const blob = await response.blob();\n const url = window.URL.createObjectURL(blob);\n window.open(url, '_blank');\n // Revoke the blob URL after some time to avoid memory leaks\n setTimeout(() => window.URL.revokeObjectURL(url), 1000);\n // const a = document.createElement(\"a\");\n // a.href = url;\n // a.download = fileName;\n // document.body.appendChild(a);\n // a.click();\n // a.remove();\n // window.URL.revokeObjectURL(url);\n}\n\nexport function formatResponseDatesToDayJS<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatResponseDatesToDayJS(item)) as unknown as T;\n }\n\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return formatResponseDatesToDayJS(value);\n }\n\n if (key.includes(\"date\") && value) {\n return dayjs.utc(value);\n }\n if (key.includes(\"_time\") && value) {\n return dayjs(`${dayjs().utc().format(\"YYYY-MM-DD\")} ${value}`);\n }\n\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\nexport const toFixedWithNumbers = (num: number) => num > 0 ? Number(num)?.toFixed(2) : num;\n\nexport const findById = (arr: Array<any>, id: any) =>\n arr.find((a) => a.id == id);\n\nexport const getTaxAmountFromMultipleTaxCodes = (\n amount: number,\n taxCodes = [],\n detail = false\n) => {\n if (!amount) return 0;\n\n let totalTaxAmount = 0;\n const taxCodeDetail = taxCodes?.map((code: any) => {\n const taxAmount = amount * (code.rate / 100);\n totalTaxAmount += taxAmount;\n\n return {\n id: code.id,\n name: code.name,\n rate: code.rate,\n tax_amount: taxAmount,\n };\n });\n\n if (detail) {\n return taxCodeDetail;\n }\n return totalTaxAmount;\n};\n\nexport const getTaxAmountDataFromMultipleTaxCodes = (\n grossAmount: number,\n netAmount: number,\n taxCodes = [],\n detail = false\n) => {\n let totalTaxAmount = 0;\n let totalTaxRate = 0;\n const taxCodeDetail = taxCodes.map((code: any) => {\n const taxBaseAmount =\n code.applies_to === \"Gross\" ? netAmount : grossAmount;\n // const taxAmount = grossAmount * (code.rate / 100);\n const taxAmount = taxBaseAmount * (code.rate / 100);\n totalTaxAmount += taxAmount;\n totalTaxRate += code.rate;\n\n return {\n id: code.id,\n name: code.name,\n rate: code.rate,\n tax_amount: taxAmount,\n };\n });\n\n if (detail) {\n return taxCodeDetail;\n }\n return {\n amount: totalTaxAmount,\n rate: totalTaxRate,\n };\n};\n\nexport const calculateAmountData = (quantity: number, rate: number, discount_rate: number | null, discounted_items: any, taxCodes = []) => {\n const amount = quantity * rate;\n let discountAmount = Number(discount_rate);\n if (discounted_items?.discount_category === \"rate\") {\n discountAmount = discount_rate ? amount * (discount_rate / 100) : 0;\n }\n let grossAmount = amount - discountAmount || 0;\n if (grossAmount < 0) {\n grossAmount = 0;\n }\n const taxData = getTaxAmountDataFromMultipleTaxCodes(\n grossAmount,\n amount,\n taxCodes\n );\n\n const taxAmount = taxData?.amount || 0;\n const taxRate = taxData?.rate || 0;\n\n const netAmount = grossAmount + Number(taxAmount) || 0;\n const totalAmount = grossAmount + Number(taxAmount) || 0;\n\n return { grossAmount, taxAmount, taxRate, discountAmount, netAmount, totalAmount }\n}\n\nexport type AnyObject = Record<string, any>;\n\nexport const hasValue = (\n object: AnyObject,\n skipFields: string[] = []\n): boolean => {\n const checkValue = (value: any, skipFields: string[]): boolean => {\n if (_.isArray(value)) {\n // If it's an array, recursively check its elements\n return _.some(value, (item) => checkValue(item, skipFields));\n }\n\n if (_.isPlainObject(value)) {\n // If it's an object, recursively check its keys and values\n return _.some(value, (val, key) => {\n if (skipFields.includes(key)) return false; // Skip specified fields\n return checkValue(val, skipFields);\n });\n }\n\n // Return true for any non-null, non-undefined, and non-empty value\n return !_.isNil(value) && !_.isEmpty(value);\n };\n\n return checkValue(object, skipFields);\n};\nexport const formatAmountWithCurrency = (\n amount: number,\n currencySymbol?: string\n): string => {\n if (!amount) {\n return `${currencySymbol ? currencySymbol : \"\"}`;\n }\n const defaultSymbol = defaultCurrencySymbol();\n const symbol = currencySymbol || defaultSymbol;\n\n return `${symbol} ${Number(amount).toFixed(2)}`;\n};\nexport const formatAmountWithCurrencyData = (\n amount: number,\n currencySymbol?: string\n): string => {\n if (!amount) {\n return \"\";\n }\n const symbol = currencySymbol || '';\n\n return `${symbol} ${Number(amount).toFixed(2)}`;\n};\n\nexport type ManageItemsOptions = {\n key: string;\n action: \"add\" | \"update\" | \"delete\";\n value: any;\n items: any[];\n itemIndex: number\n};\n\nexport const manageItems = ({\n key,\n action,\n value,\n items = [],\n itemIndex\n}: ManageItemsOptions): any[] => {\n switch (action) {\n case \"add\": {\n // const existingItem = items?.find((item) => item[key] === value[key]);\n // if (existingItem) {\n // // Update the existing item\n // return items?.map((item) => (item[key] === value[key] ? value : item));\n // }\n // Add a new item\n return [...items, value];\n }\n\n case \"update\": {\n // Update an existing item\n return items.map((item, index) => ((itemIndex >= 0 ? itemIndex === index : item[key] === value[key]) ? value : item));\n }\n\n case \"delete\": {\n // Delete an item based on\n if (value?.index !== undefined) {\n return items.filter((_, index) => index !== value.index);\n }\n return items.filter((item) => item[key] !== value[key]);\n }\n\n default:\n console.warn(`Unsupported action type: ${action}`);\n return items;\n }\n};\n\nexport function getPartyName(\n party: Record<any, any> | null | undefined\n): string {\n if (!party) return \"\";\n\n const {\n name = \"\",\n first_name = \"\",\n middle_name = \"\",\n last_name = \"\",\n company_name = \"\",\n } = party;\n\n // Trim values and handle potential null values\n const trimmedName = name?.trim() || \"\";\n const trimmedFirstName = first_name?.trim() || \"\";\n const trimmedMiddleName = middle_name?.trim() || \"\";\n const trimmedLastName = last_name?.trim() || \"\";\n const trimmedCompanyName = company_name?.trim() || \"\";\n\n\n if (party?.account_type === 'Individual') {\n return [trimmedFirstName, trimmedMiddleName, trimmedLastName].filter(Boolean).join(' ');\n } else if (party?.account_type === 'Company') {\n return trimmedCompanyName\n } else {\n if (trimmedName) return trimmedName;\n if (trimmedFirstName) {\n return [trimmedFirstName, trimmedMiddleName, trimmedLastName].filter(Boolean).join(' ');\n }\n if (trimmedCompanyName) return trimmedCompanyName;\n }\n\n return \"\";\n}\n\nexport const partyEmailIds = (json: any): string => {\n if (!json) return \"\";\n\n try {\n const parsed = JSON.parse(json);\n return Array.isArray(parsed) ? parsed.join(\", \") : \"\";\n } catch {\n return json;\n }\n};\n\nexport function formatResponseOnlyDatesToDayJS<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatResponseDatesToDayJS(item)) as unknown as T;\n }\n\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return formatResponseDatesToDayJS(value);\n }\n\n if (key.includes(\"date\") && value) {\n return dayjs(value);\n }\n\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\n\n/* fetch exchange & reverse rates */\nexport const fetchExchageRate = async (id: string, type: string = 'Buying') => {\n try {\n const response = await postV1CurrencyInfo({\n currancy_id: id,\n type: type,\n ...getToken()\n });\n\n const { exchange_rate = 1, reverse_rate = 1 } = response?.data || {};\n return { exchange_rate, reverse_rate };\n } catch (error) {\n return { exchange_rate: 1, reverse_rate: 1 };\n }\n};\n\n\nexport const showSnackBar = (error: any) => {\n const message = getErrorMessage(error?.message)\n enqueueSnackbar(message, {\n variant: \"error\",\n });\n}\n\nexport const fetchCompanyLocations = async (companyId: number) => {\n\n const res = await fetchApi(\n {\n apiKey: 'location',\n filters: {\n filters: { '&company_id.in': companyId }\n }\n });\n return res?.data || []\n}\n\nexport const fetchItems = async (itemId: number, attributes?: string) => {\n\n const res = await fetchApi(\n {\n apiKey: 'items',\n filters: {\n filters: { '&id.in': itemId },\n select: attributes\n }\n });\n return res?.data || []\n}\n\n\nexport const getOptionsData = async (key: string, id: number, select?: any, isArray = false) => {\n const res = await fetchApi(\n {\n apiKey: key,\n filters: {\n filters: { '&id.in': id },\n select\n }\n });\n return isArray ? res?.data : Array.isArray(res?.data) ? res?.data[0] : null;\n}\n\n\nexport const fetchOptions = async (key: string, filters: any, select?: any, isArray = false) => {\n const res = await fetchApi(\n {\n apiKey: key,\n filters: {\n filters: filters,\n select\n }\n });\n return isArray ? res?.data : Array.isArray(res?.data) ? res?.data[0] : null;\n}\nexport const createdOnAndBy = (data: any) => {\n const { created_at = '', created_user = {}, created_by_data = {} } = data || {}\n const { first_name = '', last_name = '' } = Object.keys(created_user)?.length ? created_user : created_by_data\n const fName = first_name?.trim() || '';\n const lName = last_name?.trim() || '';\n const cAt = created_at?.trim() || '';\n\n const text = `Created on ${formatDate(cAt, 'DD MMM, YYYY')}`\n\n if (!(fName || lName)) return text;\n\n return `${text} · ${formatText(`${fName} ${lName}`)}`\n}\n\n/**\n * Returns the full name of an object based on the provided keys.\n * The object is expected to have the keys as its properties.\n * If the object is empty, returns a default value.\n * @param {Record<string, any>} obj - The object to process\n * @param {string[]} keys - The keys to use for forming the name\n * @returns {string} The full name of the object\n */\nexport const getName = (obj: Record<string, any>, keys: string[]) => {\n if (_.isEmpty(obj)) {\n // If the object is empty, return a default value\n return \"-\";\n }\n\n // Map over the keys and get the corresponding values from the object\n // Filter out any values that are falsy or have no trimmed value\n // Join the remaining values with a space in between\n return keys\n .map((key) => obj?.[key])\n .filter((n) => Boolean(n && n?.trim()))\n .join(\" \");\n};\n\nexport const getToken = () => {\n const timezone = moment.tz.guess();\n const offsetMinutes = moment.tz.zone(timezone).utcOffset(moment());\n const requestToken = {\n \"x-token\": localStorage.getItem(auth.storageTokenKeyName) || undefined,\n \"x-timezone\": offsetMinutes,\n };\n\n return requestToken;\n};\n\nexport const checkForDuplicate = async (payload: any) => {\n try {\n const response = await postV1PartiesCheck({ ...getToken(), ...payload })\n return response?.data?.party_exists || false\n } catch (error) {\n throw new Error('An error occurred while checking for duplicates.')\n }\n}\n\nexport const partyDuplicateCheck = async (\n activeTab: number | string,\n fValues: Record<string, any>,\n defaultValues?: Record<string, any>\n): Promise<string | null> => {\n\n const values = { ...fValues };\n // Return early if activeTab is not 0 or required fields are not present\n if (activeTab !== 0 || !(values?.contact_no || values?.company_name)) {\n return null;\n }\n\n if (activeTab !== 0 || (!values?.contact_no && values?.company_name && values?.account_type !== 'Company')) {\n return null;\n }\n\n const phoneNumber = parsePhoneNumberFromString(values?.contact_no?.includes('+') ? values?.contact_no : `+${values?.contact_no}`);\n values.contact_no = phoneNumber?.nationalNumber || '';\n values.country_code = phoneNumber?.countryCallingCode || '';\n\n // Determine if contact number or company name values have changed\n const cDefaultValueContactNo = defaultValues?.contact_no || ''\n const cValueContactNo = displayPhone(values)\n\n const isDirtyPhone =\n !defaultValues ||\n cDefaultValueContactNo?.trim() !== cValueContactNo?.trim();\n const isDirtyCompanyName =\n !defaultValues ||\n defaultValues?.company_name?.trim() !== values?.company_name?.trim();\n\n // If neither field has changed, no need to check for duplicates\n if (!isDirtyPhone && !isDirtyCompanyName) {\n return null;\n }\n\n // Parse phone number to extract country code and national number\n const countryCode = phoneNumber?.nationalNumber ? phoneNumber?.countryCallingCode\n ? `+${phoneNumber?.countryCallingCode}` : ''\n : values?.country_code;\n const contactNo = phoneNumber?.nationalNumber || values?.contact_no;\n\n // Construct payload for duplicate check\n const duplicateCheckPayload = {\n party: {\n account_type: values?.account_type, // \"Individual\" or \"Company\"\n ...(isDirtyPhone && countryCode ? { country_code: countryCode } : {}),\n ...(isDirtyPhone && contactNo ? { contact_no: contactNo } : {}),\n ...(values?.account_type === 'Company' && isDirtyCompanyName\n ? { company_name: values?.company_name }\n : {}),\n },\n };\n\n try {\n // Call API to check for duplicates\n const isDuplicate = await checkForDuplicate(duplicateCheckPayload);\n\n if (isDuplicate) {\n // Prepare and return an appropriate error message\n const duplicateType =\n values?.account_type === 'Company' ? phoneNumber?.nationalNumber ? 'company name or phone' : 'company name' : 'phone number';\n return `Added ${duplicateType} already exists. Please add a different ${duplicateType}.`;\n }\n } catch (error: any) {\n // Return error message in case of API failure\n return error.message || 'An error occurred while checking for duplicates.';\n }\n\n // Return null if no duplicates are found\n return null;\n};\n\nexport const displayPhone = (data: Record<string, any>) => {\n const { contact_no = '', country_code = '' } = data || {}\n\n if (!contact_no) return ''\n\n if (country_code) {\n if (country_code?.includes(\"+\")) {\n return `${country_code}${contact_no}`\n }\n return `+${country_code}${contact_no}`\n }\n\n return contact_no?.includes(\"+\") ? contact_no : `+${contact_no}`\n}\n\nexport const getPartyDependentData = async (\n id: number,\n options?: any\n) => {\n let ad: any[] = [],\n co: any[] = [],\n cr = options?.currencies || [],\n cm = options?.companies || [],\n dsa = null,\n dba = null,\n pt = null,\n sp = null;\n\n const res = await getV1PartiesId({ id, ...getToken() });\n const p = res?.data?.parties?.party?.data || null;\n if (p) {\n const {\n payment_term = null,\n party_address_data = [],\n party_contact_data = [],\n currencies_data = [],\n companies_data = [],\n salesperson = null\n } = p;\n\n ad = party_address_data\n co = party_contact_data;\n cr = currencies_data;\n cm = companies_data;\n pt = payment_term;\n dsa = party_address_data?.find((addr: any) => Boolean(addr?.default_shipping_address));\n dba = party_address_data?.find((addr: any) => Boolean(addr?.default_billing_address));\n sp = salesperson\n }\n\n return {\n addresses: ad,\n contacts: co,\n currencies: cr,\n currencyIds: cr.map((c: any) => c.id),\n companies: cm,\n companyIds: cm.map((c: any) => c.id),\n paymentTerm: pt,\n defaultShipping: dsa,\n defaultBilling: dba,\n salesperson: sp\n };\n};\n\nexport interface PayloadMapping {\n [key: string]: string | string[] | ((values: Record<string, any>) => any);\n}\n\n/**\n * Maps API payload by transforming values based on the provided mapping configuration.\n * \n * @param {PayloadMapping} payloadMapping - An object defining the mapping configuration.\n * @param {Record<string, any>} values - The source values to be transformed.\n * @returns {Record<string, any>} The transformed payload object.\n */\nconst isEmptyValue = (value: any): boolean => {\n return _.isNil(value) || value === '' || (_.isObject(value) && _.isEmpty(value));\n};\n\nexport const mapApiPayload = (payloadMapping: PayloadMapping, values: Record<string, any>): Record<string, any> => {\n return _.mapValues(payloadMapping, (val) => {\n // If the mapping value is a function, execute it with the values as the argument\n if (_.isFunction(val)) {\n return (val as (values: Record<string, any>) => any)(values);\n }\n // If the mapping value is an array, map each element to its corresponding value in the source\n if (_.isArray(val)) {\n return (val as string[]).map((key) => _.get(values, key, null));\n }\n // If the mapping value is an object (excluding Day.js), recursively process it\n if (_.isObject(val) && !_.isFunction(val) && !dayjs.isDayjs(val)) {\n return mapApiPayload(val as PayloadMapping, values);\n }\n // Directly map a single key to its value in the source\n const result = _.get(values, val, null)\n return isEmptyValue(result) ? null : result\n });\n};\n\nexport const mapAsyncApiPayload = async (payloadMapping: PayloadMapping, values: Record<string, any>): Promise<Record<string, any>> => {\n const entries = Object.entries(payloadMapping).map(async ([key, val]) => {\n if (_.isFunction(val)) {\n return [key, await val(values)];\n }\n if (_.isArray(val)) {\n const resolvedArray = await Promise.all(val.map(async (key) => _.get(values, key, null)));\n return [key, resolvedArray];\n }\n if (_.isObject(val) && !_.isFunction(val) && !dayjs.isDayjs(val)) {\n return [key, await mapAsyncApiPayload(val as PayloadMapping, values)];\n }\n return [key, _.get(values, val, null)];\n });\n\n return Object.fromEntries(await Promise.all(entries));\n};\n\n\nexport const isBetweenTheDates = (startDate: any, endDate: any) => {\n if (!startDate || !endDate) return false;\n const start = dayjs(startDate).startOf('day');\n const end = dayjs(endDate).endOf('day');\n const currentDate = dayjs();\n return currentDate.isAfter(start) && currentDate.isBefore(end) || currentDate.isSame(start) || currentDate.isSame(end);\n};\n\nexport const setRateBasedOnPriceRules = (salesPrice: any, priceRules: any, addedQuantity: any) => {\n let updatedRate = salesPrice\n if (priceRules?.length) {\n const sortedPriceRules = _.orderBy(\n priceRules,\n ['minimum_quantity'],\n ['desc']\n );\n for (const pRules of sortedPriceRules) {\n if (Number(addedQuantity) >= Number(pRules?.minimum_quantity)) {\n if (isBetweenTheDates(pRules?.start_date, pRules?.end_date)) {\n updatedRate = Number(pRules?.unit_price) || undefined;\n break;\n }\n }\n }\n }\n return updatedRate\n};\n\n\nexport const uploadAttachments = async (files: any) => {\n let existingAttachments =\n files?.filter((i: File | string) => !(i instanceof File)) || [];\n const newFiles = files?.filter((i: File | string) => i instanceof File) || [];\n const bUrl = import.meta.env.VITE_S3_BUCKET_URL;\n existingAttachments = existingAttachments.map((ea: string) =>\n ea.replace(bUrl, \"\")\n );\n\n let uplaodedAttachments: string[] = [];\n\n if (newFiles.length) {\n uplaodedAttachments = await uploadFiles(newFiles, \"sales\");\n }\n\n uplaodedAttachments = [...uplaodedAttachments, ...existingAttachments];\n if (Array.isArray(uplaodedAttachments) && uplaodedAttachments?.length) {\n return uplaodedAttachments.join(\",\");\n }\n return null;\n};\n\nexport const addOrEditArray = (array: any[] = [], data: any) => {\n const { itemIndex, ...updatedData } = data;\n\n const newArray = [...array];\n\n if (newArray[itemIndex]) {\n newArray[itemIndex] = { ...updatedData };\n return newArray;\n }\n\n return [...newArray, updatedData];\n};\nexport const getAccessibleModules = (moduleNames: string[] = []): string[] => {\n const uData = localStorage.getItem(\"_u_data\");\n const userData = uData ? JSON.parse(uData) : {};\n const accessModules = userData?.module_access || [];\n\n const findSubModules = accessModules\n .filter(module => moduleNames.includes(module.module_name))\n .map(module => ({\n ...module,\n sub_modules: [...(module.sub_modules || []), { sub_module_name: \"dashboard\" }],\n }));\n\n const subModuleNamesSet = new Set(\n findSubModules.flatMap(module => module.sub_modules.map(subModule => subModule.sub_module_name))\n );\n\n const permission = JSON.parse(localStorage.getItem(\"role-permission\") || \"{}\");\n return Array.from(subModuleNamesSet).filter(subModule =>\n Object.keys(permission).some(key => key.startsWith(subModule.split(\"/\").pop()))\n ) as string[];\n};\n\nexport const filterAccessibleModules = (menu: any, moduleNames: string[] = []) => {\n const accessibleMenus = new Set(getAccessibleModules(moduleNames))\n\n\n return menu.reduce((filtered, item) => {\n const isSubModuleValid = item.bacSubModuleName && accessibleMenus.has(item.bacSubModuleName);\n const filteredSubmenu = item.submenu?.length ? filterAccessibleModules(item.submenu, moduleNames) : [];\n\n if (isSubModuleValid || filteredSubmenu.length) {\n filtered.push({ ...item, submenu: filteredSubmenu });\n }\n return filtered;\n }, []);\n}\n\n// Usage example:\n// const accessibleModules = getAccessibleModules([\"manufacturing\", \"inventory\", \"sales\"]);\n\n\nexport const checkDuplicateTracking = (data: any, typeOfTrcebility: string, trackRows: any[]) => {\n\n let isDuplicate = false\n let errorMsg = null\n // Check for duplicate tracking numbers\n const isSerialTracking = typeOfTrcebility === 'Serial Number Tracking';\n const trackingField = isSerialTracking ? 'serial_number' : 'lot_number';\n const inputValue = isSerialTracking\n ? data?.add_stock_transfer?.lot_number?.serial_number\n : data?.add_stock_transfer?.lot_number?.lot_number;\n errorMsg = isSerialTracking\n ? \"This serial Number is already available\"\n : \"This lot Number is already available\";\n\n if (trackRows[data?.itemIndex]?.[trackingField] == inputValue) {\n return { isDuplicate: false }\n }\n if (['Serial Number Tracking', 'Lot Tracking'].includes(typeOfTrcebility)) {\n isDuplicate = trackRows.some((o) =>\n o?.[trackingField] === inputValue\n );\n }\n return {\n isDuplicate,\n errorMsg\n }\n}\nexport function getNestedValue(obj: any, path: any) {\n return path.split('.').reduce((acc: any, key: any) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);\n}\n\n// export const calculatePeriods = (startDateTime: Date, endDateTime: Date) => {\n// const start = dayjs(startDateTime);\n// const end = dayjs(endDateTime);\n\n// if (end.isBefore(start)) {\n// return null;\n// }\n\n// const totalMinutes = end.diff(start, 'minute');\n// if (totalMinutes < 0) {\n// return null;\n// }\n\n// let current = dayjs(start);\n// let years = 0;\n// let months = 0;\n// let days = 0;\n// let hours = 0;\n// // let minutes = 0;\n\n// // Calculate years\n// while (current.add(1, 'year').isBefore(end) || current.add(1, 'year').isSame(end)) {\n// years++;\n// current = current.add(1, 'year');\n// }\n\n// // Calculate months\n// while (current.add(1, 'month').isBefore(end) || current.add(1, 'month').isSame(end)) {\n// months++;\n// current = current.add(1, 'month');\n// }\n\n// // Calculate days \n// while (current.add(1, 'day').isBefore(end) || current.add(1, 'day').isSame(end)) {\n// days++;\n// current = current.add(1, 'day');\n// }\n\n// // Calculate hours\n// while (current.add(1, 'hour').isBefore(end) || current.add(1, 'hour').isSame(end)) {\n// hours++;\n// current = current.add(1, 'hour');\n// }\n\n// // Calculate remaining minutes\n// // minutes = end.diff(current, 'minute');\n\n// const parts = [];\n\n// if (years > 0) {\n// parts.push(`${years} ${years === 1 ? 'Year' : 'Years'}`);\n// }\n// if (months > 0) {\n// parts.push(`${months} ${months === 1 ? 'Month' : 'Months'}`);\n// }\n// if (days > 0) {\n// parts.push(`${days} ${days === 1 ? 'Day' : 'Days'}`);\n// }\n// if (hours > 0) {\n// parts.push(`${hours} ${hours === 1 ? 'Hour' : 'Hours'}`);\n// }\n// // if (minutes > 0) {\n// // parts.push(`${minutes} ${minutes === 1 ? 'Minute' : 'Minutes'}`);\n// // }\n\n// if (parts.length === 0) {\n// return '0 Minutes';\n// }\n\n// return parts.join(' ');\n// };\n//eslint-disable-next-line\nexport const calculatePeriods = (\n startDateTime: Date,\n endDateTime: Date,\n mode: 'Day' | 'Week' | 'Month' | 'Calendar Month' | 'Year' | 'Hour' = 'Month'\n) => {\n const start = dayjs(startDateTime);\n const end = dayjs(endDateTime);\n\n if (end.isBefore(start)) {\n return null;\n }\n\n switch (mode) {\n case 'Year': {\n const years = end.diff(start, 'year');\n const remainingMonths = end.diff(start.add(years, 'year'), 'month');\n return `${years} ${years === 1 ? 'Year' : 'Years'}${remainingMonths > 0 ? `, ${remainingMonths} ${remainingMonths === 1 ? 'Month' : 'Months'}` : ''}`;\n }\n\n case 'Month':\n case 'Calendar Month': {\n const months = end.diff(start, 'month');\n const remainingDays = end.diff(start.add(months, 'month'), 'day');\n return `${months} ${months === 1 ? 'Month' : 'Months'}${remainingDays > 0 ? `, ${remainingDays} ${remainingDays === 1 ? 'Day' : 'Days'}` : ''}`;\n }\n\n case 'Week': {\n const weeks = end.diff(start, 'week');\n const remainingDaysWeekly = end.diff(start.add(weeks, 'week'), 'day');\n return `${weeks} ${weeks === 1 ? 'Week' : 'Weeks'}${remainingDaysWeekly > 0 ? `, ${remainingDaysWeekly} ${remainingDaysWeekly === 1 ? 'Day' : 'Days'}` : ''}`;\n }\n\n case 'Day': {\n const totalHours = end.diff(start, 'hour');\n const days = Math.floor(totalHours / 24);\n const remainingHours = totalHours % 24;\n\n if (remainingHours > 0) {\n return `${days + 1} ${days + 1 === 1 ? 'Day' : 'Days'}`;\n }\n return `${days} ${days === 1 ? 'Day' : 'Days'}`;\n }\n\n case 'Hour': {\n const hours = end.diff(start, 'hour');\n return `${hours} ${hours === 1 ? 'Hour' : 'Hours'}`;\n }\n\n default:\n return 'Invalid mode';\n }\n};\nexport const removeIdFromObject = (array: any) => array?.map(i => ({\n ...i,\n id: undefined\n}))\n\nexport const fetchRentalResponseItems = async (filters: string) => {\n //eslint-disable-next-line\n try {\n const response = await getV1CrossHireRfqResponseItems({\n filters,\n ...getToken(),\n });\n\n return response?.data?.rfq_response_items ?? [];\n } catch (error) {\n throw error;\n }\n};\nexport const fetchRfqItemsByIdForResponse = async (filters: string) => {\n //eslint-disable-next-line\n try {\n const response = await getV1RfqResponseItems({\n filters,\n ...getToken(),\n });\n\n return response?.data?.rfq_response_items ?? [];\n } catch (error) {\n throw error;\n }\n};\n\nexport const appendConditionSafely = (original: string | undefined, newCondition: string): string => {\n const cleanConditionString = (str: string): string => {\n // Remove leading special chars except '('\n return str.trim().replace(/^([^\\w(]+)/, '');\n };\n\n const extractConditions = (str: string): string[] => {\n // Remove outermost brackets if they exist, then split by '&' or ','\n return str\n .trim()\n .replace(/^[(]|[)]$/g, '')\n .split(/[&,]/)\n .map((cond) => cond.trim())\n .filter(Boolean);\n };\n\n // If no original, clean newCondition and wrap in ()\n if (!original || typeof original !== 'string' || original.trim() === '') {\n const cleaned = cleanConditionString(newCondition);\n return `(${cleaned})`;\n }\n\n // Extract existing and new conditions\n const existingConditions = new Set<string>(extractConditions(original));\n const incomingConditions = extractConditions(newCondition);\n\n // Filter out duplicates\n const filteredNew = incomingConditions.filter(\n (cond) => !existingConditions.has(cond)\n );\n\n // Combine both\n const allConditions = [...existingConditions, ...filteredNew];\n return `(${allConditions.join('&')})`;\n};\n\n\nexport const fetchAssemblyItemData = async (itemId: number) => {\n const response = await getV1AssemblyItemsId({\n id: itemId,\n ...getToken()\n });\n return response?.data?.data || null;\n};\nexport const getFileName = (file) => {\n if (!file) return \"\"\n if (file instanceof File) {\n return file.name\n } else if (typeof file === 'string') {\n const parts = file?.split('/');\n return parts?.[parts?.length - 1];\n } else if (Array.isArray(file) && file?.length > 0) {\n return file.map(f => {\n if (f instanceof File) {\n return f.name\n }\n const parts = f?.split('/');\n return parts?.[parts?.length - 1];\n }).join(', ')\n }\n}\n\nexport const getFieldFilters = (fields: any[], fieldNames: string | string[]) => {\n if (!fields?.length) return Array.isArray(fieldNames) ? new Map() : {};\n const filters = new Map()\n if (Array.isArray(fieldNames) && fieldNames?.length) {\n fieldNames.forEach(f => {\n const filt = fields.find(fi => fi.name === f)?.field_properties?.customeFilter || {}\n filters.set(f, filt)\n })\n return filters\n }\n return fields.find(fi => fi.name === fieldNames)?.field_properties?.customeFilter || {}\n};\n\nexport const getNextScheduleDate = (currentDate: any, billingCycle: any) => {\n switch (billingCycle?.duration) {\n case 'Hour':\n return dayjs(currentDate).add(1, 'hour');\n case 'Day':\n return dayjs(currentDate).add(1, 'day');\n case 'Week':\n return dayjs(currentDate).add(1, 'week');\n case '2 Week':\n return dayjs(currentDate).add(2, 'week');\n case 'Month':\n // \"Month\" means actual 1 month (30 days)\n return dayjs(currentDate).add(30, 'day');\n case 'Calendar Month':\n // \"Calendar Month\" means end of the month\n return dayjs(currentDate).endOf('month').add(1, 'day').startOf('day');\n case 'Quarter':\n case '3 Month':\n return dayjs(currentDate).add(3, 'month');\n case '6 Month':\n return dayjs(currentDate).add(6, 'month');\n case 'Year':\n case '1 Year':\n return dayjs(currentDate).add(1, 'year');\n case '3 Year':\n return dayjs(currentDate).add(3, 'year');\n case '5 Year':\n case '5Year':\n return dayjs(currentDate).add(5, 'year');\n default:\n return dayjs(currentDate).add(1, 'month');\n }\n};\n//eslint-disable-next-line\nexport const getCountryIdByName = async (name: string) => {\n const response = await getV1LocationsCountries({\n filters: `(name.like=%${name}%)`,\n ...getToken(),\n });\n return response?.data?.countries?.[0]?.id || null;\n\n}\nexport const getSlicedValue = (value: string, length: number): string => {\n if (!value) return '';\n return value.slice(0, length);\n};\n\nexport const skuGenerator = ({\n name,\n category,\n sequence = '0001'\n}: {\n name: string;\n category: string;\n sequence?: string;\n}): string => {\n const cleanCategory = category.replace(/[^a-zA-Z0-9]/g, '');\n const cleanName = name.replace(/[^a-zA-Z0-9]/g, '');\n\n const categoryPart = getSlicedValue(cleanCategory, 3).toUpperCase();\n const namePart = getSlicedValue(cleanName, 3).toUpperCase();\n\n return `${categoryPart}-${namePart}-${sequence}`;\n};\n\nexport const checkSkuAndItemName = async (payload: any) => {\n const response = await postV1InventoryItemsCheck({\n ...payload,\n ...getToken(),\n });\n return response?.data?.item_exists || null;\n}\n\nexport interface FormValues {\n [key: string]: any;\n}\n\n/**\n * Helper function to process field disabling logic\n */\nconst processFieldDisabling = (\n currentFieldValue: any,\n valueConfig: any,\n fieldsToDisableSet: Set<string>\n): void => {\n if (currentFieldValue !== null && currentFieldValue !== undefined) {\n // Convert current value to string for consistent comparison\n const valueKey = String(currentFieldValue);\n\n // Check for exact match first\n if (valueConfig[valueKey]) {\n valueConfig[valueKey].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n // Check for type-specific matches (boolean, number)\n else if (typeof currentFieldValue === 'boolean' && valueConfig[currentFieldValue]) {\n valueConfig[currentFieldValue].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n else if (typeof currentFieldValue === 'number' && valueConfig[currentFieldValue]) {\n valueConfig[currentFieldValue].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n } else if (valueConfig?.['NO_VALUE']) {\n // Handle NO_VALUE case when field is empty/null/undefined\n valueConfig['NO_VALUE'].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n};\n\n// Types for the configuration object\nexport interface UpdateFieldsDisabledConfig {\n data: any[];\n materialCostingType: string;\n formValues: FormValues;\n fieldsConfig?: FieldDisableConfig;\n isEditMode?: boolean;\n isAddMode?: boolean;\n alwaysDisabledFields?: string[];\n editModeDisabledFields?: string[];\n addModeDisabledFields?: string[];\n}\n\nexport const updateFieldsDisabledState = ({\n data,\n materialCostingType,\n formValues,\n fieldsConfig = INVENTORY_FIELDS_TO_BE_DISABLED,\n isEditMode = false,\n isAddMode = false,\n alwaysDisabledFields = INVENTORY_ALWAYS_DISABLED_FIELDS,\n editModeDisabledFields = INVENTORY_EDIT_MODE_DISABLED_FIELDS,\n addModeDisabledFields = INVENTORY_ADD_MODE_DISABLED_FIELDS\n}: UpdateFieldsDisabledConfig): any[] => {\n // Create a set to track all fields that should be disabled conditionally\n const conditionallyDisabledFields = new Set<string>();\n\n // Get all field names for the current material type (for material-specific fields)\n const materialTypeFieldNames = new Set(\n data\n ?.filter(field => field?.field_properties?.type === materialCostingType)\n ?.map(field => field?.name) || []\n );\n\n // Get all field names in the form (for global fields)\n const allFieldNames = new Set(data?.map(field => field?.name) || []);\n\n // Process each configuration entry for conditional disabling\n Object.entries(fieldsConfig).forEach(([configKey, valueConfig]) => {\n if (configKey === materialCostingType) {\n // Material-specific configuration (like pipe_costing)\n Object.entries(valueConfig).forEach(([dependentFieldName, nestedValueConfig]) => {\n if (materialTypeFieldNames.has(dependentFieldName)) {\n const fieldValue = formValues?.[dependentFieldName];\n processFieldDisabling(fieldValue, nestedValueConfig, conditionallyDisabledFields);\n }\n });\n } else if (allFieldNames.has(configKey)) {\n // Global field configuration (like is_rental)\n const currentFieldValue = formValues?.[configKey];\n processFieldDisabling(currentFieldValue, valueConfig, conditionallyDisabledFields);\n }\n });\n\n // Update form fields with disabled state\n return data.map(field => {\n // Check different types of disabled states\n const isAlwaysDisabled = alwaysDisabledFields.includes(field.name);\n const isEditModeDisabled = isEditMode && editModeDisabledFields.includes(field.name);\n const isAddModeDisabled = isAddMode && addModeDisabledFields.includes(field.name);\n const isConditionallyDisabled = conditionallyDisabledFields.has(field.name);\n // const hasOriginalDisabled = field.disabled === true; // Only respect explicit true values\n\n // Field is disabled if any condition is met\n const isDisabled = isAlwaysDisabled || isEditModeDisabled || isAddModeDisabled || isConditionallyDisabled;\n\n return {\n ...field,\n disabled: isDisabled,\n disableTableAddButton: isDisabled,\n disableDefaultActionColumn: isDisabled || Boolean(field?.disableDefaultActionColumn)\n };\n });\n};\n\nexport const remainingMaterialCostingTypes = (type: string) => {\n return INVENTORY_MATERIAL_COSTING_TYPE_ARR.filter(mct => mct !== type)\n}\nexport const matchedMaterialCostingTypeLabel = (type: string) => {\n return INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS.find(o => o.value === type)?.label || null\n}\n\nexport const fetchDataLocally = (params: any, arr: any) => {\n const { search = '', limit = 25, skip = 0 } = params;\n\n // Filter entityFields based on search term\n let filteredData = arr || [];\n if (search && search.length > 0) {\n const searchLower = search.toLowerCase();\n filteredData = filteredData.filter((item: any) => {\n const label = item?.label || item?.name || '';\n return label.toLowerCase().includes(searchLower);\n });\n }\n\n const totalCount = filteredData.length;\n\n const paginatedData = filteredData.slice(skip, skip + limit).map((item: any) => ({\n ...item,\n label: item?.label || item?.name,\n value: item?.value || item?.id || item?.name\n }));\n\n return {\n data: paginatedData,\n pagination: {\n totalCount\n }\n };\n}"],"names":["token","localStorage","getItem","auth","storageTokenKeyName","spliceUploadedLocation","uploadedlocation","splitLocation","split","length","splice","join","async","fetchWithRetry","url","options","maxRetries","retryDelay","lastError","attempt","response","fetch","status","Error","statusText","error","name","delay","Math","pow","Promise","resolve","setTimeout","handleRegularUpload","files","controller","module","BASE_URL","COMPLETE_BASE_URL","authToken","onProgress","chunkSize","retryAttempts","uploaded","fileIndex","file","signal","aborted","uploadedLocation","uploadSingleFile","push","fileError","message","totalFiles","baseUrl","completeUrl","isMultipart","size","totalParts","ceil","preSignedResponse","encodeURIComponent","type","method","headers","toString","ok","errorData","json","catch","pData","preSignedData","_a","data","uploadId","preSignedUrls","presignedUrl","location","handleMultipartUpload","handleSinglePartUpload","_b","body","fileName","progress","bytesUploaded","totalBytes","totalBytesUploaded","i","partNumber","start","end","min","chunk","slice","partResponse","round","completeResponse","JSON","stringify","completeData","uploadFiles","Array","isArray","filter","uFiles","bUrl","bUrl2","replace","AbortController","iFiles","existingFiles","File","validFiles","_c","map","f","Boolean","errorMessage","formatDateForPayload","date","dayjs","isValid","format","formatTimeForPayload","formatDateTimeForPayload","isJSONString","str","parse","e","getErrorMessage","defaultCurrencySymbol","currencyData","symbol","userData","currency_data","formatResponseDatesToDayJS","obj","item","_","isObject","mapValues","value","key","isDayjs","includes","utc","getTaxAmountDataFromMultipleTaxCodes","grossAmount","netAmount","taxCodes","detail","totalTaxAmount","totalTaxRate","taxCodeDetail","code","taxAmount","applies_to","rate","id","tax_amount","amount","getToken","timezone","moment","tz","guess","offsetMinutes","zone","utcOffset","checkForDuplicate","payload","postV1PartiesCheck","party_exists","displayPhone","contact_no","country_code","mapApiPayload","payloadMapping","values","val","isFunction","get","result","isNil","isEmpty","mapAsyncApiPayload","entries","Object","all","fromEntries","isBetweenTheDates","startDate","endDate","startOf","endOf","currentDate","isAfter","isBefore","isSame","getAccessibleModules","moduleNames","uData","findSubModules","module_access","module_name","sub_modules","sub_module_name","subModuleNamesSet","Set","flatMap","subModule","permission","from","keys","some","startsWith","pop","filterAccessibleModules","menu","accessibleMenus","reduce","filtered","isSubModuleValid","bacSubModuleName","has","filteredSubmenu","submenu","getSlicedValue","processFieldDisabling","currentFieldValue","valueConfig","fieldsToDisableSet","valueKey","String","forEach","fieldName","add","Approved","Rejected","array","itemIndex","updatedData","newArray","original","newCondition","extractConditions","trim","cond","existingConditions","filteredNew","quantity","discount_rate","discounted_items","discountAmount","Number","discount_category","taxData","taxRate","totalAmount","startDateTime","endDateTime","mode","years","diff","remainingMonths","months","remainingDays","weeks","remainingDaysWeekly","totalHours","days","floor","hours","typeOfTrcebility","trackRows","isDuplicate","errorMsg","isSerialTracking","trackingField","inputValue","add_stock_transfer","lot_number","serial_number","_d","_e","o","postV1InventoryItemsCheck","item_exists","created_at","created_user","created_by_data","first_name","last_name","fName","lName","cAt","text","formatDate","formatText","user","accessCompanies","defaultCompanyId","company_id","dcId","number_format","api","raw","redirect","blob","window","URL","createObjectURL","open","revokeObjectURL","fileUrl","a","document","createElement","target","href","download","appendChild","click","removeChild","itemId","getV1AssemblyItemsId","companyId","res","fetchApi","apiKey","filters","params","arr","search","limit","skip","filteredData","searchLower","toLowerCase","label","totalCount","pagination","postV1CurrencyInfo","currancy_id","exchange_rate","reverse_rate","attributes","select","getV1CrossHireRfqResponseItems","rfq_response_items","getV1RfqResponseItems","allCoa","coa","ic","company_ids","c","find","position","parseFloat","isNaN","num","toFixed","formatter","Intl","NumberFormat","minimumFractionDigits","maximumFractionDigits","formattedAmount","currencySymbol","defaultSymbol","formatEmptyDataToNull","keysInOrder","string","fieldsConfig","defaultOperators","textOperators","numberOperators","selectOperators","dropdownOperators","dateOperators","isFilterAllowed","field","is_aggregate","table","fieldType","operators","valueEditorType","inputType","datatype","enum","fieldArr","boolean","comparator","rule","operatorMap","null","notNull","contains","beginsWith","endsWith","doesNotContain","doesNotBeginWith","doesNotEndWith","in","notIn","processRules","rules","ruleValue","rv","combinator","operator","formatValue","concatString","uniqueStringId","Date","now","random","uniqueNumberId","getV1LocationsCountries","countries","request","pathParts","pathname","currentPath","currentModule","moduleName","combinedFilters","specificFilters","title","filterQueryString","cleanedFilterQueryString","subModuleName","subModuleMappings","queryParams","selectedIds","queryString","URLSearchParams","resource","fields","fieldNames","Map","filt","fi","field_properties","customeFilter","set","parts","dataArray","fallbackArray","labelKeys","labelFormatter","compact","v","n","path","acc","billingCycle","duration","filterFields","booleanOperators","rField","ff","operatorLable","to","no","so","dwo","dto","_f","_g","bo","ad","co","cr","currencies","cm","companies","dsa","dba","pt","sp","getV1PartiesId","p","parties","party","payment_term","party_address_data","party_contact_data","currencies_data","companies_data","salesperson","addr","default_shipping_address","default_billing_address","addresses","contacts","currencyIds","companyIds","paymentTerm","defaultShipping","defaultBilling","middle_name","company_name","trimmedName","trimmedFirstName","trimmedMiddleName","trimmedLastName","trimmedCompanyName","account_type","object","skipFields","checkValue","isPlainObject","jsonString","err","action","items","index","INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS","omitDataKeys","extra","defaultOmitKeys","omitBy","activeTab","fValues","defaultValues","phoneNumber","parsePhoneNumberFromString","nationalNumber","countryCallingCode","cDefaultValueContactNo","cValueContactNo","isDirtyPhone","isDirtyCompanyName","countryCode","contactNo","duplicateCheckPayload","duplicateType","parsed","mainModule","INVENTORY_MATERIAL_COSTING_TYPE_ARR","mct","ele","_id","salesPrice","priceRules","addedQuantity","updatedRate","sortedPriceRules","orderBy","pRules","minimum_quantity","start_date","end_date","unit_price","enqueueSnackbar","variant","category","sequence","cleanCategory","cleanName","toUpperCase","materialCostingType","formValues","INVENTORY_FIELDS_TO_BE_DISABLED","isEditMode","isAddMode","alwaysDisabledFields","INVENTORY_ALWAYS_DISABLED_FIELDS","editModeDisabledFields","INVENTORY_EDIT_MODE_DISABLED_FIELDS","addModeDisabledFields","INVENTORY_ADD_MODE_DISABLED_FIELDS","conditionallyDisabledFields","materialTypeFieldNames","allFieldNames","configKey","dependentFieldName","nestedValueConfig","fieldValue","isAlwaysDisabled","isEditModeDisabled","isAddModeDisabled","isConditionallyDisabled","isDisabled","disabled","disableTableAddButton","disableDefaultActionColumn","existingAttachments","newFiles","ea","uplaodedAttachments","discountDueDateBasedOn","discountValidity","dateObj","discountEndDate","setDate","getDate","parseInt","getFullYear","getMonth","setMonth"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../../src/utils/common.ts"],"sourcesContent":["import dayjs from \"dayjs\";\nimport { auth } from \"../constants/auth\";\nimport _ from \"lodash\";\nimport { getV1PartiesId, postV1CurrencyInfo, postV1PartiesCheck } from \"../api-client/api.accounting/api\";\nimport { enqueueSnackbar } from \"notistack\";\nimport { fetchApi } from \"./api\";\nimport formatText from \"./format-text\";\nimport { formatDate } from \"./dateFormat\";\nimport { subModuleMappings, specificFilters } from './export-filters'\nimport parsePhoneNumberFromString from \"libphonenumber-js\";\nimport moment from 'moment-timezone'\nimport { getV1CrossHireRfqResponseItems } from \"../api-client/api.rental/api\";\nimport { getV1RfqResponseItems } from \"../api-client/api.purchase/api\";\nimport { getV1AssemblyItemsId, postV1InventoryItemsCheck } from \"../api-client/api.inventory/api\";\nimport { getV1LocationsCountries } from \"../api-client/api.rbac/api\";\nimport { FieldDisableConfig, INVENTORY_ADD_MODE_DISABLED_FIELDS, INVENTORY_ALWAYS_DISABLED_FIELDS, INVENTORY_EDIT_MODE_DISABLED_FIELDS, INVENTORY_FIELDS_TO_BE_DISABLED, INVENTORY_MATERIAL_COSTING_TYPE_ARR, INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS } from \"./constant\";\n\nexport const isJsonParse = (jsonString?: string) => {\n if (!jsonString) return false;\n try {\n return JSON.parse(jsonString);\n } catch (err) {\n return false;\n }\n};\n\nexport const generateRandomId = (concatString: string = \"\") => {\n const uniqueStringId = `${Date.now()}${concatString}${Math.random()}`.replace(\n \".\",\n \"\"\n );\n const uniqueNumberId = Number(uniqueStringId.replace(concatString, \"\"));\n\n return { uniqueStringId, uniqueNumberId };\n};\n\nexport const generateAndFormatStringFromObj = (\n obj: any = {},\n keysInOrder: string[] = []\n) => {\n let string = \"\";\n\n keysInOrder?.forEach((key) => {\n if (obj?.[key]) {\n string = string ? string + ` ${obj?.[key]}` : obj?.[key];\n }\n });\n\n return string;\n};\n\nexport const generateFields = (fieldsConfig: any) => {\n const defaultOperators = [\n { name: \"null\", label: \"is null\" },\n { name: \"notNull\", label: \"is not null\" },\n ];\n\n const textOperators = [\n { name: \"contains\", label: \"contains\" },\n { name: \"beginsWith\", label: \"begins with\" },\n { name: \"endsWith\", label: \"ends with\" },\n { name: \"doesNotContain\", label: \"does not contain\" },\n { name: \"doesNotBeginWith\", label: \"does not begin with\" },\n { name: \"doesNotEndWith\", label: \"does not end with\" },\n ...defaultOperators,\n ];\n\n const numberOperators = [\n { name: \"=\", label: \"equal to\" },\n { name: \"<\", label: \"less than\" },\n { name: \"<=\", label: \"less than or equal to\" },\n { name: \">\", label: \"greater than\" },\n { name: \">=\", label: \"greater than or equal to\" },\n ...defaultOperators,\n ];\n\n const selectOperators = [\n { name: \"in\", label: \"in\" },\n { name: \"notIn\", label: \"not in\" },\n ...defaultOperators,\n ];\n\n const dropdownOperators = [{ name: \"in\", label: \"in\" }];\n\n const dateOperators = [\n { name: \"=\", label: \"on\" },\n { name: \"!=\", label: \"not on\" },\n { name: \"<\", label: \"before\" },\n { name: \"<=\", label: \"on or before\" },\n { name: \">\", label: \"after\" },\n { name: \">=\", label: \"on or after\" },\n ...defaultOperators,\n ];\n\n // const booleanOperators = [{ name: \"=\", label: \"is\" }];\n\n const getFieldConfig = (field: any) => {\n\n let { type, values } = field;\n const { is_aggregate = false, table = null } = field;\n const { key: name, label, fieldType } = field;\n let operators, valueEditorType, inputType, datatype;\n\n if (field?.enum) {\n type = \"select\";\n\n let fieldArr = field.enum;\n\n if (\n fieldArr &&\n !Array.isArray(fieldArr) &&\n typeof fieldArr === \"object\"\n ) {\n fieldArr = Object.values(fieldArr);\n }\n\n values = fieldArr.map((value) => ({ name: value, label: value }));\n }\n\n if (fieldType === \"select\") {\n type = \"select\";\n\n values = field?.options;\n }\n\n if (field?.boolean) {\n type = \"select\";\n\n values = field?.values || [];\n }\n\n if (field?.table) {\n type = \"table\";\n }\n\n switch (type) {\n case \"string\":\n operators = textOperators;\n valueEditorType = \"text\";\n inputType = \"text\";\n break;\n case \"number\":\n operators = numberOperators;\n valueEditorType = \"text\";\n inputType = \"number\";\n break;\n case \"select\":\n operators = selectOperators;\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n case \"table\":\n operators = dropdownOperators;\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n case \"datetime\":\n operators = dateOperators;\n valueEditorType = \"text\";\n inputType = \"date\";\n datatype = \"date\";\n break;\n case \"date\":\n operators = dateOperators;\n valueEditorType = \"text\";\n inputType = \"date\";\n datatype = \"date\";\n break;\n case \"boolean\":\n operators = [...dropdownOperators, ...defaultOperators];\n valueEditorType = \"select\";\n inputType = \"select\";\n break;\n default:\n operators = textOperators;\n valueEditorType = \"text\";\n inputType = \"text\";\n }\n\n return {\n name: name.replace(\"__replaceKey\", ''),\n // name,\n label,\n valueEditorType,\n operators,\n inputType,\n datatype,\n comparator: \"datatype\",\n values,\n is_aggregate,\n table,\n };\n };\n\n return fieldsConfig.filter((f: any) => f.isFilterAllowed && f?.type).map(getFieldConfig);\n};\n\nexport const generateQueryString = (rule: any) => {\n const operatorMap = {\n null: \"eq\",\n notNull: \"ne\",\n contains: \"like\",\n beginsWith: \"like\",\n endsWith: \"like\",\n doesNotContain: \"ne\",\n doesNotBeginWith: \"ne\",\n doesNotEndWith: \"ne\",\n \"<\": \"lt\",\n \"<=\": \"lte\",\n \">\": \"gt\",\n \">=\": \"gte\",\n \"=\": \"eq\",\n \"!=\": \"ne\",\n in: \"in\",\n notIn: \"nin\",\n };\n\n const formatValue = (operator: any, value: any) => {\n if ([\"in\", \"notIn\"].includes(operator)) {\n return `[${value}]`;\n } else if ([\"like\", \"ilike\"].includes(operator)) {\n if (operator === \"beginsWith\") return `${value}%`;\n if (operator === \"endsWith\") return `%${value}`;\n return `%${value}%`;\n } else if (operator === \"null\" || operator === \"notNull\") {\n return \"\";\n } else {\n return value;\n }\n };\n\n const processRules = (rules: any) => {\n return rules.map((rule) => {\n let ruleValue = rule.value;\n if (Array.isArray(ruleValue)) {\n ruleValue = ruleValue.map(rv => {\n if (typeof rv === 'object') {\n rv = rv.name\n }\n return rv\n })\n }\n if (rule.rules) {\n\n const combinator = rule.combinator === \"or\" ? \"|\" : \"&\";\n const nestedRules = processRules(rule.rules);\n return `${nestedRules.join(combinator)}`;\n } else {\n let operator = operatorMap[rule.operator];\n\n if (\n (operator === \"in\" || operator === \"notIn\") &&\n typeof ruleValue === \"string\"\n ) {\n operator = \"eq\";\n }\n\n if (rule.operator === \"null\" || rule.operator === \"notNull\") {\n ruleValue = null;\n }\n\n const value = formatValue(operator, ruleValue);\n if (operator === \"eq\" || operator === \"ne\") {\n return `${rule.field}.${operator}=${value}`;\n }\n return `${rule.field}.${operator}=${value}`;\n }\n });\n };\n\n const combinator = rule.combinator === \"or\" ? \"|\" : \"&\";\n const processedRules = processRules(rule.rules);\n return `(${processedRules.join(combinator)})`.replace(/ /g, \"---\");\n};\n\n\n// export const formatAmount = (\n// \tamount: number | string = '',\n// \tformat: string = '',\n// \tposition: 'after' | 'before' = 'after',\n// \tsymbol?: string\n// ) => {\n\n// \tlet isNegative = false;\n// \tamount = amount.toString();\n// \tif (amount.includes('-')) {\n// \t\tamount = amount.replace('-', '');\n// \t\tisNegative = true;\n// \t}\n\n// \tif (format && amount) {\n// \t\t// Split the format into integer and decimal parts\n// \t\tconst [integerFormat, decFormat] = format.split('.');\n// \t\tlet intFormat: string | string[] = integerFormat;\n// \t\t// Convert amount to string and split into integer and decimal parts\n// \t\tconst [integerAmount, decAmount] = Math.abs(Number(amount))\n// \t\t\t.toFixed(decFormat ? decFormat.length : 0)\n// \t\t\t.toString()\n// \t\t\t.trim()\n// \t\t\t.split('.');\n// \t\tlet intAmount: string | string[] = integerAmount;\n// \t\t// let [intAmount, decAmount] = Math.abs(amount).toFixed(decFormat ? decFormat.length : 0).split('.');\n\n// \t\tconst am = intAmount.split('').reverse().join('');\n// \t\tconst formatArr: string[] = intFormat.split(',').reverse();\n\n// \t\tif (intFormat.length !== 1) {\n// \t\t\twhile (formatArr.join('').length < am.length) {\n// \t\t\t\tif (formatArr.length >= 2) {\n// \t\t\t\t\tformatArr.splice(1, 0, formatArr[1]);\n// \t\t\t\t} else {\n// \t\t\t\t\tformatArr.push(formatArr[formatArr.length - 1]);\n// \t\t\t\t}\n// \t\t\t}\n// \t\t} else {\n// \t\t\tconst formatZeroIndex = am?.split('')?.reduce((lv: string) => {\n// \t\t\t\treturn lv + '#';\n// \t\t\t}, '');\n\n// \t\t\tformatArr[0] = formatZeroIndex;\n// \t\t}\n\n// \t\tintFormat = formatArr.join(',').split('');\n\n// \t\t// Reverse the integer amount and format for easier processing from right to left\n// \t\tintAmount = intAmount.split('').reverse();\n\n// \t\tlet formattedInt = '';\n// \t\tlet intIndex = 0;\n// \t\tfor (let i = 0; i < intFormat.length; i++) {\n// \t\t\tif (intFormat[i] === '#') {\n// \t\t\t\tformattedInt +=\n// \t\t\t\t\tintAmount[intIndex] !== undefined ? intAmount[intIndex++] : '';\n// \t\t\t} else if (intFormat[i] === ',') {\n// \t\t\t\tformattedInt += intIndex > 0 ? ',' : '';\n// \t\t\t} else {\n// \t\t\t\tformattedInt += intFormat[i];\n// \t\t\t}\n// \t\t}\n\n// \t\t// Reverse back to the original order\n// \t\tformattedInt = formattedInt.split('').reverse().join('');\n\n// \t\t// Handle the decimal part\n// \t\tlet formattedDec = '';\n// \t\tif (decFormat && decAmount) {\n// \t\t\tfor (let i = 0; i < decFormat.length; i++) {\n// \t\t\t\tformattedDec +=\n// \t\t\t\t\tdecFormat[i] === '#'\n// \t\t\t\t\t\t? decAmount[i] !== undefined\n// \t\t\t\t\t\t\t? decAmount[i]\n// \t\t\t\t\t\t\t: ''\n// \t\t\t\t\t\t: decFormat[i];\n// \t\t\t}\n// \t\t}\n\n// \t\twhile (formattedInt?.startsWith(',')) {\n// \t\t\tformattedInt = formattedInt.replace(',', '');\n// \t\t}\n\n// \t\t// Combine integer and decimal parts\n// \t\tlet formattedAmount = formattedInt;\n// \t\tif (formattedDec) {\n// \t\t\tformattedAmount += '.' + formattedDec;\n// \t\t}\n\n// \t\t// Add negative sign if the amount is negative\n// \t\tif (isNegative) {\n// \t\t\tformattedAmount = '-' + formattedAmount;\n// \t\t}\n\n// \t\t// Add symbol on specific position\n// \t\tif (symbol && position) {\n\n// \t\t\tif (position === 'after') {\n// \t\t\t\tformattedAmount = formattedAmount + ' ' + symbol;\n// \t\t\t} else if (position === 'before') {\n// \t\t\t\tformattedAmount = symbol + ' ' + formattedAmount;\n// \t\t\t}\n// \t\t}\n// \t\treturn formattedAmount;\n// \t}\n\n// \treturn isNegative ? '-' + amount : amount;\n// };\n\n\nexport const getOperatorLabel = (rule: any, filterFields: any[]) => {\n const defaultOperators = [\n { name: 'null', label: 'Is null' },\n { name: 'notNull', label: 'Is not null' }\n ];\n\n const textOperators = [\n { name: 'contains', label: 'Contains' },\n { name: 'beginsWith', label: 'Begins with' },\n { name: 'endsWith', label: 'Ends with' },\n { name: 'doesNotContain', label: 'Does not contain' },\n { name: 'doesNotBeginWith', label: 'Does not begin with' },\n { name: 'doesNotEndWith', label: 'Does not end with' },\n ...defaultOperators\n ];\n\n const numberOperators = [\n { name: '=', label: 'Equal to' },\n { name: '<', label: 'Less than' },\n { name: '<=', label: 'Less than or equal to' },\n { name: '>', label: 'Greater than' },\n { name: '>=', label: 'Greater than or equal to' },\n ...defaultOperators\n ];\n\n const selectOperators = [\n { name: 'in', label: 'In' },\n { name: 'notIn', label: 'Not in' },\n ...defaultOperators\n ];\n\n const dropdownOperators = [{ name: 'in', label: 'In' }];\n\n const dateOperators = [\n { name: '=', label: 'On' },\n { name: '!=', label: 'Not on' },\n { name: '<', label: 'Before' },\n { name: '<=', label: 'On or before' },\n { name: '>', label: 'After' },\n { name: '>=', label: 'On or after' },\n ...defaultOperators\n ];\n\n const booleanOperators = [{ name: '=', label: 'is' }, ...defaultOperators];\n const { field: rField, operator } = rule;\n const field = filterFields?.find(\n (ff) => ff.key.replace('__replaceKey', '') == rField\n );\n let operatorLable = '';\n if (field) {\n let { type } = field || {};\n // const { is_aggregate = false, table = null } = field || {};\n const { fieldType } = field;\n\n if (field?.enum) {\n type = 'select';\n }\n\n if (fieldType === 'select') {\n type = 'select';\n }\n\n if (field?.boolean) {\n type = 'select';\n }\n\n if (field?.table) {\n type = 'table';\n }\n\n switch (type) {\n case 'string':\n operatorLable =\n textOperators.find((to) => to.name == operator)?.label || '';\n break;\n case 'number':\n operatorLable =\n numberOperators.find((no) => no.name == operator)?.label || '';\n break;\n case 'select':\n operatorLable =\n selectOperators.find((so) => so.name == operator)?.label || '';\n break;\n case 'table':\n operatorLable =\n dropdownOperators.find((dwo) => dwo.name == operator)?.label || '';\n break;\n case 'datetime':\n operatorLable =\n dateOperators.find((dto) => dto.name == operator)?.label || '';\n break;\n case 'date':\n operatorLable =\n dateOperators.find((dto) => dto.name == operator)?.label || '';\n break;\n case 'boolean':\n operatorLable =\n booleanOperators.find((bo) => bo.name == operator)?.label || '';\n break;\n }\n }\n\n return operatorLable;\n};\n\nexport const formatAmount = (\n amount: number | string = \"\",\n format: string = \"\",\n position: \"after\" | \"before\" = \"before\",\n symbol?: string\n): string => {\n if (amount === \"\" || amount === null || amount === undefined) {\n amount = 0;\n }\n\n if (typeof amount === \"string\") {\n amount = parseFloat(amount.replace(/[^\\d.-]/g, \"\"));\n if (isNaN(amount)) return \"\";\n }\n\n const num = parseFloat((amount as number).toFixed(2));\n\n let formatter: Intl.NumberFormat;\n\n switch (format) {\n case \"#,###.##\":\n formatter = new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#.###,##\":\n formatter = new Intl.NumberFormat(\"de-DE\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"# ###.##\":\n formatter = new Intl.NumberFormat(\"fr-FR\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"# ###,##\":\n formatter = new Intl.NumberFormat(\"es-ES\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#’ ###. ##\":\n formatter = new Intl.NumberFormat(\"de-CH\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n case \"#, ###.##\":\n formatter = new Intl.NumberFormat(\"en-GB\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n break;\n default:\n formatter = new Intl.NumberFormat(\"en-US\", {\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n });\n }\n\n let formattedAmount = formatter.format(num);\n\n // Handle specific spacing for formats\n if (format === \"# ###.##\" || format === \"# ###,##\") {\n formattedAmount = formattedAmount.replace(/\\u00A0/g, \" \");\n }\n if (format === \"#’ ###. ##\") {\n formattedAmount = formattedAmount.replace(/\\u00A0/g, \" \").replace(/'/g, \"’\");\n }\n if (format === \"#, ###.##\") {\n formattedAmount = formattedAmount.replace(/,/g, \", \");\n }\n\n if (symbol) {\n return position === \"after\"\n ? `${formattedAmount} ${symbol}`\n : `${symbol} ${formattedAmount}`;\n }\n\n return formattedAmount;\n};\n\n\nexport const filterCoaByCompanyIdOrNull = (\n allCoa: any[],\n { companyId }: { companyId?: number | string | null | any[] }\n) => {\n if (!allCoa?.length) return [];\n\n return allCoa.filter((coa) => {\n if (companyId) {\n const ic = Array.isArray(companyId)\n ? companyId.map(Number)\n : [Number(companyId)];\n return !coa.company_ids || coa.company_ids.some((c) => ic.includes(c.id));\n }\n return !coa.company_ids;\n });\n};\n\n// type DiscountDueDateBasedOn = \"DAYS_AFTER_INVOICE_DATE\" | \"DAYS_AFTER_INVOICE_MONTH\" | \"MONTHS_AFTER_INVOICE_MONTH\";\n\nexport const validateDiscountValidity = (\n date,\n discountDueDateBasedOn,\n discountValidity\n) => {\n const currentDate = new Date();\n const dateObj = new Date(date);\n let discountEndDate;\n\n switch (discountDueDateBasedOn) {\n case \"DAYS_AFTER_INVOICE_DATE\":\n discountEndDate = new Date(dateObj);\n discountEndDate.setDate(\n discountEndDate.getDate() + parseInt(discountValidity)\n );\n break;\n case \"DAYS_AFTER_INVOICE_MONTH\":\n discountEndDate = new Date(\n dateObj.getFullYear(),\n dateObj.getMonth() + 1,\n parseInt(discountValidity)\n );\n break;\n case \"MONTHS_AFTER_INVOICE_MONTH\":\n discountEndDate = new Date(dateObj);\n discountEndDate.setMonth(\n discountEndDate.getMonth() + parseInt(discountValidity)\n );\n discountEndDate = new Date(\n discountEndDate.getFullYear(),\n discountEndDate.getMonth() + 1,\n 0\n ); // End of the month\n break;\n default:\n throw new Error(\"Invalid discount_due_date_based_on value\");\n }\n\n return currentDate <= discountEndDate;\n};\n\nconst token = localStorage.getItem(auth.storageTokenKeyName) || undefined;\nexport const postImportSheet = async (request: any, moduleName: string) => {\n\n let mainModule = window.location.pathname.split('/')[2]\n const subModuleName = window.location.pathname.split('/')[3]\n console.log(\"mainModule\", mainModule, moduleName)\n let type = ''\n if (mainModule == \"crm\") {\n mainModule = \"sales\"\n }\n if (mainModule == \"procurement\") {\n mainModule = \"purchase\"\n }\n if (mainModule == 'rental' && subModuleName == 'item') {\n mainModule = 'inventory'\n }\n if (mainModule == 'rental' && moduleName == 'quotation') {\n moduleName = 'rental-quotations'\n }\n if (mainModule == 'rental' && moduleName == 'lead') {\n moduleName = 'rental-lead'\n }\n if (mainModule == 'rental' && moduleName == 'rfq') {\n mainModule = 'purchase'\n }\n if (mainModule == 'rental' && moduleName == 'purchase-orders') {\n mainModule = 'purchase'\n }\n if (mainModule == 'rental' && moduleName == 'opportunity') {\n moduleName = 'rental-opportunity'\n }\n\n if (moduleName == 'collection-entries') {\n moduleName = 'payment-entries'\n type = 'receive'\n }\n\n\n\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}/${mainModule}`;\n\n const headers = {};\n\n headers[\"x-token\"] = token;\n // headers['Content-type'] = 'application/json; charset=utf-8';\n\n const response = await fetch(`${baseUrl}/v1/${moduleName}/import${type ? `?type=${type}` : ''}`, {\n method: \"POST\",\n body: request,\n headers,\n });\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response.json();\n};\n\nexport const getExcelTemplateGenerateTemplate = async (request: any) => {\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}/accounting`;\n\n const headers = {};\n\n if (request[\"x-token\"] !== undefined) {\n headers[\"x-token\"] = request[\"x-token\"];\n delete request[\"x-token\"];\n }\n if (request[\"Content-Type\"] !== undefined) {\n headers[\"Content-Type\"] = request[\"Content-Type\"];\n delete request[\"Content-Type\"];\n }\n console.log(\"request\", request.resource)\n const response = await fetch(\n `${baseUrl}/v1/excel-template/generate-template?resource=${request.resource.toString()}`,\n {\n headers,\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response;\n};\n\n\nexport const getExcelExportTemplate = async (request: any) => {\n const baseUrl = `${import.meta.env.VITE_BACKEND_BASE_URL}`;\n\n const headers = {};\n\n if (request[\"x-token\"] !== undefined) {\n headers[\"x-token\"] = request[\"x-token\"];\n delete request[\"x-token\"];\n }\n if (request[\"Content-Type\"] !== undefined) {\n headers[\"Content-Type\"] = request[\"Content-Type\"];\n delete request[\"Content-Type\"];\n }\n const pathParts = window.location.pathname.split(\"/\");\n const currentPath = pathParts.pop();\n const currentModule = pathParts[3];\n let moduleName = pathParts[2];\n console.log(\"selectedIds\", request)\n console.log(\"moduleName\", moduleName, currentPath, currentModule)\n if (currentPath == \"demand-planning\") {\n moduleName = \"purchase\"\n }\n if (moduleName == \"crm\") {\n moduleName = \"sales\"\n }\n if (moduleName == \"procurement\") {\n moduleName = \"purchase\"\n }\n let combinedFilters = \"\";\n const excelpath = \"generate-excel\";\n if (currentPath && specificFilters[currentPath]) {\n combinedFilters = specificFilters[currentPath];\n }\n if (currentPath === \"items\" || currentPath === 'item') {\n if (request?.title && request?.title == \"Non Inventory\") {\n request.title = \"non-inventory\"\n } else if (request?.title && request?.title == \"Assembly (Finished product)\") {\n request.title = \"assembly\"\n }\n combinedFilters += `&type.eq=${request?.title.toLowerCase()}`\n }\n if (request.filterQueryString) {\n const cleanedFilterQueryString = request.filterQueryString.replace(/[{}()]/g, \"\");\n if (combinedFilters) {\n combinedFilters = `(${combinedFilters}&${cleanedFilterQueryString})`;\n } else {\n combinedFilters = `(${cleanedFilterQueryString})`;\n }\n } else {\n combinedFilters = `(${combinedFilters})`;\n }\n if (combinedFilters.includes(\"is_variant.eq=false|self_variant.eq=true\")) {\n if (moduleName == \"rental\") {\n combinedFilters = combinedFilters.replace(\"is_variant.eq=false|self_variant.eq=true\", \"(is_variant.eq=false|self_variant.eq=true&is_rental.eq=1)\");\n } else {\n combinedFilters = combinedFilters.replace(\"is_variant.eq=false|self_variant.eq=true\", \"(is_variant.eq=false|self_variant.eq=true)\");\n }\n }\n\n\n\n if (currentPath && !specificFilters[currentPath] && !request.filterQueryString) {\n combinedFilters = \"\"\n }\n\n let subModuleName = subModuleMappings[currentPath || \"\"] || currentPath;\n console.log(\"combinedFiltersNEWWWWWWWWWW\", moduleName, subModuleName, combinedFilters)\n if (moduleName == \"sales\" && subModuleName == \"quotation\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == \"sales\" && subModuleName == \"sales-orders\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == \"rental\" && subModuleName == \"rental-lead\") {\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == \"sales\" && subModuleName == \"lead\") {\n combinedFilters = '(is_rental.eq=0)'\n }\n\n if (\n moduleName === \"purchase\" &&\n (subModuleName === \"purchase-requests\" || subModuleName === \"rfq\" || subModuleName === \"purchase-orders\")\n ) {\n combinedFilters = '(is_rental.eq=0)';\n }\n\n if (moduleName == \"rental\" && subModuleName == \"quotation\") {\n console.log(\"rental quotation::::::::::::::::::;\")\n subModuleName = \"rental-quotations\"\n }\n if (moduleName == \"rental\" && subModuleName == \"opportunity\") {\n subModuleName = \"rental-opportunity\"\n }\n if (moduleName == 'rental' && subModuleName == 'item') {\n moduleName = \"inventory\"\n subModuleName = 'inventory-items'\n }\n if (moduleName == 'rental' && subModuleName == 'category') {\n moduleName = \"inventory\"\n subModuleName = 'category-items'\n }\n if (moduleName == 'rental' && subModuleName == 'purchase-requests') {\n subModuleName = 'cross-hire-requests'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'rfq' && currentModule != 'purchase') {\n subModuleName = 'cross-hire-rfq'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'rfq' && currentModule == 'purchase') {\n moduleName = 'purchase'\n combinedFilters = '(is_rental.eq=0)'\n }\n\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title !== 'Rental Orders' && request.title !== 'Replacement Orders') {\n console.log(\"combinedFilters\", combinedFilters);\n subModuleName = 'cross-hire-orders'\n combinedFilters = '(is_rental.eq=1)'\n }\n if (moduleName == 'rental' && (subModuleName == 'orders' || subModuleName == 'cross-hire-orders') && currentModule == 'purchase') {\n moduleName = 'purchase'\n subModuleName = \"purchase-orders\"\n combinedFilters = '(is_rental.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'rental-quotations' && request.title == \"Quotations\") {\n combinedFilters = '(is_visible.eq=1&is_rental.eq=1&is_replacement.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'rental-quotations' && request.title == \"Replacement Quotations\") {\n combinedFilters = '(is_visible.eq=1&is_rental.eq=1&is_replacement.eq=1)'\n }\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title == 'Rental Orders') {\n subModuleName = 'rental-orders'\n combinedFilters = '(is_rental.eq=1&is_replacement.eq=0)'\n }\n if (moduleName == 'rental' && subModuleName == 'orders' && request.title == 'Replacement Orders') {\n subModuleName = 'rental-orders'\n combinedFilters = '(is_rental.eq=1&is_replacement.eq=1)'\n }\n console.log(\"moduleName\", moduleName, subModuleName, request.title)\n const queryParams: Record<string, string> = {};\n if (request.selectedIds && combinedFilters) {\n if (request.selectedIds.length > 0) {\n combinedFilters = `(${combinedFilters}&id.in=${request.selectedIds})`;\n }\n } else if (request.selectedIds) {\n if (request.selectedIds.length > 0) {\n combinedFilters = `(id.in=${request.selectedIds})`;\n }\n }\n if (combinedFilters) {\n queryParams.filters = combinedFilters;\n }\n const queryString = new URLSearchParams(queryParams).toString();\n const response = await fetch(\n `${baseUrl}/${moduleName}/v1/${subModuleName}/${excelpath}${queryString ? `?${queryString}` : \"\"\n }`,\n {\n headers,\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n\n return await response;\n};\n\nexport const removeIdStaticIdsFromMongoObject = (data: any) => {\n const newData = data.map((ele: { _id: string | number }) => {\n if (typeof ele._id === \"number\") {\n return { ...ele, _id: null };\n }\n return ele;\n });\n\n return newData;\n};\n\n/**\n * * FILE UPLOAD\n */\nconst spliceUploadedLocation = (uploadedlocation: string) => {\n const splitLocation = uploadedlocation.split(\"/\");\n if (splitLocation.length) {\n splitLocation.splice(0, splitLocation.length - 2);\n return splitLocation.join(\"/\");\n }\n\n return uploadedlocation;\n};\n\n/**\n * Fetch with retry logic for network resilience\n */\nasync function fetchWithRetry(\n url: string,\n options: RequestInit,\n maxRetries: number,\n retryDelay: number\n): Promise<Response> {\n let lastError: Error;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n\n // If it's a server error (5xx), retry\n if (response.status >= 500 && attempt < maxRetries) {\n throw new Error(`Server error: ${response.status} ${response.statusText}`);\n }\n\n return response;\n } catch (error: any) {\n lastError = error;\n\n // Don't retry for abort signals or client errors (4xx)\n if (error.name === 'AbortError') {\n throw error;\n }\n\n if (attempt < maxRetries) {\n const delay = retryDelay * Math.pow(2, attempt); // Exponential backoff\n console.warn(`Attempt ${attempt + 1} failed, retrying in ${delay}ms...`, error.message);\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n }\n }\n\n throw lastError!;\n}\n\n/**\n * Helper function to format file size in human-readable format\n */\nfunction formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n}\n\n// Interface declarations moved to exported section below\nexport interface UploadOptions {\n onProgress?: (progress: ProgressInfo) => void;\n chunkSize?: number;\n retryAttempts?: number;\n retryDelay?: number;\n}\n\nexport interface ProgressInfo {\n fileName: string;\n progress: number;\n bytesUploaded: number;\n totalBytes: number;\n fileIndex?: number;\n totalFiles?: number;\n}\n\nexport interface FileUploadResponse {\n data: {\n preSignedData: {\n uploadId: string;\n fileName: string;\n preSignedUrls: Array<{\n partNumber: number;\n presignedUrl: string;\n }>;\n location?: string;\n presignedUrl?: string; // For single part uploads\n };\n };\n}\n\nexport interface CompleteUploadResponse {\n data: {\n location: string;\n };\n}\n\nexport interface UploadPart {\n partNumber: number;\n etag: string;\n}\n\nexport const handleRegularUpload = async (\n files: File[],\n controller: AbortController,\n module: string,\n options: UploadOptions = {}\n): Promise<string[]> => {\n const BASE_URL = `${import.meta.env.VITE_BACKEND_BASE_URL}/${module}/v1/file-upload/`;\n const COMPLETE_BASE_URL = `${import.meta.env.VITE_BACKEND_BASE_URL}/${module}/v1/file-upload/mark-complete`;\n const authToken = localStorage.getItem(auth.storageTokenKeyName);\n\n const {\n onProgress,\n chunkSize = 5 * 1024 * 1024, // 5MB default chunk size (S3 minimum for multipart)\n retryAttempts = 3,\n retryDelay = 1000\n } = options;\n\n if (!authToken) {\n throw new Error('Authentication token not found. Please log in again.');\n }\n\n // Validate chunk size for multipart uploads\n // if (chunkSize < 1024 * 1024) {\n // console.warn('Chunk size less than 5MB may cause issues with S3 multipart uploads');\n // }\n\n try {\n const uploaded: string[] = [];\n\n // Process files sequentially to maintain order and avoid overwhelming the server\n for (let fileIndex = 0; fileIndex < files.length; fileIndex++) {\n const file = files[fileIndex];\n\n if (controller.signal.aborted) {\n throw new Error('Upload cancelled by user');\n }\n\n console.log(`🚀 Uploading file ${fileIndex + 1}/${files.length}:`, file.name, `(${formatFileSize(file.size)})`);\n\n try {\n const uploadedLocation = await uploadSingleFile(\n file,\n fileIndex,\n files.length,\n controller,\n BASE_URL,\n COMPLETE_BASE_URL,\n authToken,\n chunkSize,\n retryAttempts,\n retryDelay,\n onProgress\n );\n\n uploaded.push(uploadedLocation);\n console.log(`✅ Successfully uploaded: ${file.name}`);\n\n } catch (fileError: any) {\n console.error(`❌ Failed to upload ${file.name}:`, fileError.message);\n throw new Error(`Failed to upload ${file.name}: ${fileError.message}`);\n }\n }\n\n return uploaded;\n } catch (error: any) {\n console.error('❌ Upload process failed:', error.message);\n throw new Error(error.message || 'Upload failed');\n }\n};\n\nconst uploadSingleFile = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n controller: AbortController,\n baseUrl: string,\n completeUrl: string,\n authToken: string,\n chunkSize: number,\n retryAttempts: number,\n retryDelay: number,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n const isMultipart = file.size > chunkSize;\n const totalParts = isMultipart ? Math.ceil(file.size / chunkSize) : 1;\n\n // Step 1: Get pre-signed URLs\n console.log(`📋 Requesting ${totalParts} pre-signed URLs for ${file.name}`);\n\n const preSignedResponse = await fetchWithRetry(\n `${baseUrl}?key=${encodeURIComponent(file.name)}&partCount=${totalParts}&mimeType=${encodeURIComponent(file.type)}`,\n {\n method: 'GET',\n headers: {\n \"Content-Type\": \"application/json\",\n \"file-size\": file.size.toString(),\n \"x-token\": authToken,\n },\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!preSignedResponse.ok) {\n const errorData = await preSignedResponse.json().catch(() => ({}));\n throw new Error(`Failed to get pre-signed URL: ${errorData.message || preSignedResponse.statusText}`);\n }\n\n const pData: FileUploadResponse = await preSignedResponse.json();\n const preSignedData = pData?.data?.preSignedData;\n\n if (!preSignedData) {\n throw new Error('Invalid pre-signed URL response format');\n }\n\n const { uploadId, preSignedUrls, presignedUrl, location } = preSignedData;\n\n // Step 2: Upload file parts\n if (isMultipart) {\n return await handleMultipartUpload(\n file,\n fileIndex,\n totalFiles,\n uploadId,\n preSignedUrls,\n controller,\n completeUrl,\n authToken,\n chunkSize,\n retryAttempts,\n retryDelay,\n onProgress\n );\n } else {\n return await handleSinglePartUpload(\n file,\n fileIndex,\n totalFiles,\n presignedUrl || preSignedUrls?.[0]?.presignedUrl,\n location,\n controller,\n onProgress\n );\n }\n};\n\nconst handleSinglePartUpload = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n presignedUrl: string,\n location: string | undefined,\n controller: AbortController,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n if (!presignedUrl) {\n throw new Error('No presigned URL provided for single part upload');\n }\n\n console.log(`📤 Uploading single part for ${file.name}`);\n\n const response = await fetch(presignedUrl, {\n method: \"PUT\",\n body: file,\n headers: {\n \"Content-Type\": file.type || \"application/octet-stream\",\n \"Content-Length\": file.size.toString(),\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Single part upload failed: ${response.statusText}`);\n }\n\n // Report completion\n onProgress?.({\n fileName: file.name,\n progress: 100,\n bytesUploaded: file.size,\n totalBytes: file.size,\n fileIndex: fileIndex + 1,\n totalFiles\n });\n\n if (!location) {\n throw new Error('No location provided for single part upload');\n }\n\n return spliceUploadedLocation(location);\n};\n\nconst handleMultipartUpload = async (\n file: File,\n fileIndex: number,\n totalFiles: number,\n uploadId: string,\n preSignedUrls: Array<{ partNumber: number; presignedUrl: string }>,\n controller: AbortController,\n completeUrl: string,\n authToken: string,\n chunkSize: number,\n retryAttempts: number,\n retryDelay: number,\n onProgress?: (progress: ProgressInfo) => void\n): Promise<string> => {\n if (!uploadId || !preSignedUrls || preSignedUrls.length === 0) {\n throw new Error('Invalid multipart upload data: missing uploadId or preSignedUrls');\n }\n\n console.log(`📤 Starting multipart upload for ${file.name} (${preSignedUrls.length} parts)`);\n\n const uploadedParts: UploadPart[] = [];\n let totalBytesUploaded = 0;\n\n // Upload each part\n for (let i = 0; i < preSignedUrls.length; i++) {\n if (controller.signal.aborted) {\n throw new Error('Upload cancelled by user');\n }\n\n const { partNumber, presignedUrl } = preSignedUrls[i];\n const start = i * chunkSize;\n const end = Math.min(start + chunkSize, file.size);\n const chunk = file.slice(start, end);\n\n console.log(`📦 Uploading part ${partNumber}/${preSignedUrls.length} (${start}-${end})`);\n\n try {\n const partResponse = await fetchWithRetry(\n presignedUrl,\n {\n method: \"PUT\",\n body: chunk,\n headers: {\n \"Content-Type\": \"application/octet-stream\",\n \"Content-Length\": chunk.size.toString(),\n },\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!partResponse.ok) {\n throw new Error(`Part ${partNumber} upload failed: ${partResponse.statusText}`);\n }\n\n // Extract ETag from response headers (required for completion)\n // const etag = partResponse.headers.get('ETag');\n // if (!etag) {\n // throw new Error(`Part ${partNumber} upload succeeded but no ETag received`);\n // }\n\n uploadedParts.push({\n partNumber\n });\n\n totalBytesUploaded += chunk.size;\n\n // Report progress\n const progress = Math.round((totalBytesUploaded / file.size) * 100);\n onProgress?.({\n fileName: file.name,\n progress,\n bytesUploaded: totalBytesUploaded,\n totalBytes: file.size,\n fileIndex: fileIndex + 1,\n totalFiles\n });\n\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('Upload cancelled by user');\n }\n throw new Error(`Failed to upload part ${partNumber}: ${error.message}`);\n }\n }\n\n // Step 3: Complete the multipart upload\n console.log(`🔗 Completing multipart upload for ${file.name}`);\n\n // Sort parts by part number to ensure correct order\n uploadedParts.sort((a, b) => a.partNumber - b.partNumber);\n\n const completeResponse = await fetchWithRetry(\n completeUrl,\n {\n method: 'POST',\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-token\": authToken,\n },\n body: JSON.stringify({\n fileName: file.name,\n uploadId: uploadId,\n //parts: uploadedParts // Include the uploaded parts with ETags\n }),\n signal: controller.signal,\n },\n retryAttempts,\n retryDelay\n );\n\n if (!completeResponse.ok) {\n const errorData = await completeResponse.json().catch(() => ({}));\n throw new Error(`Failed to complete multipart upload: ${errorData.message || completeResponse.statusText}`);\n }\n\n const completeData: CompleteUploadResponse = await completeResponse.json();\n\n if (!completeData.data?.location) {\n throw new Error('Invalid completion response format - no location received');\n }\n\n return spliceUploadedLocation(completeData.data.location);\n};\n\n/**\n * Main upload function - handles file validation and orchestrates the upload process\n * @param files - Single file or array of files to upload\n * @param module - Module name for the upload endpoint (default: \"sales\")\n * @param options - Optional upload configuration\n * @returns Promise<string[]> - Array of uploaded file locations\n */\nexport const uploadFiles = async (\n files: any,\n module = \"sales\",\n options: UploadOptions = {}\n): Promise<string[]> => {\n if (Array.isArray(files) && files?.filter(i => i)?.length === 0) return [];\n try {\n let uFiles: string[] = [];\n const bUrl = import.meta.env.VITE_S3_BUCKET_URL;\n const bUrl2 = bUrl?.replace(\"https://\", \"\");\n\n const controller = new AbortController();\n\n // Normalize input to array and filter valid files\n const iFiles = files ? (Array.isArray(files) ? files : [files]) : [];\n\n const existingFiles = iFiles.filter((file) => !(file instanceof File));\n if (iFiles && iFiles.length) {\n // Filter to ensure only File objects are processed\n const validFiles = iFiles.filter((file) => file instanceof File);\n\n if (validFiles && validFiles.length) {\n console.log(`📁 Starting upload of ${validFiles.length} file(s) to module: ${module}`);\n uFiles = await handleRegularUpload(validFiles, controller, module, options);\n console.log(`✅ Successfully uploaded ${uFiles.length} file(s)`);\n } else {\n console.warn('⚠️ No valid File objects found in the provided input');\n }\n }\n\n return [...uFiles, ...existingFiles]?.map(f => f?.split(bUrl)?.join('')?.split(bUrl2)?.join(''))?.filter(Boolean) || [];\n } catch (error) {\n let errorMessage: string = \"Something went wrong during file upload.\";\n\n if (error instanceof Error) {\n errorMessage = error.message;\n }\n\n console.error('❌ Upload failed:', errorMessage);\n throw new Error(errorMessage);\n }\n};\n\nexport const formatDateForPayload = (date: any) =>\n date && dayjs(date).isValid() ? dayjs(date).format(\"YYYY-MM-DD\") : undefined;\n\nexport const formatTimeForPayload = (date: any) =>\n date && dayjs(date).isValid() ? dayjs(date).format(\"HH:mm:ss\") : undefined;\n\nexport const formatDateTimeForPayload = (date: any) =>\n (date && dayjs(date).isValid()) ? dayjs(date).format(\"YYYY-MM-DD HH:mm:ss\") : undefined;\n\nexport function isJSONString(str: string | undefined) {\n if (!str) return false;\n\n try {\n return JSON.parse(str);\n } catch (e) {\n return false;\n }\n}\n\nexport const getErrorMessage = (error?: any) => {\n if (error instanceof Error) return error.message;\n else if (isJSONString(error)?.message) return isJSONString(error)?.message;\n else if (typeof error === 'string') return error;\n else return \"Something went wrong\";\n};\n\nexport const InvoiceStatus = {\n Approved: \"Approve\",\n Rejected: \"Reject\",\n};\n\n/**\n * Get the default currency symbol from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param currencyData - Optional pre-fetched currency data to avoid localStorage lookup\n */\nexport const defaultCurrencySymbol = (currencyData?: { symbol?: string }) => {\n if (currencyData?.symbol) {\n return currencyData.symbol;\n }\n try {\n const userData = JSON.parse(localStorage.getItem('user') || '{}');\n return userData?.currency_data?.symbol || \"\";\n } catch {\n return \"\";\n }\n};\n\n/**\n * Get the default currency format from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param currencyData - Optional pre-fetched currency data to avoid localStorage lookup\n */\nexport const defaultCurrencyFormat = (currencyData?: { number_format?: string }) => {\n if (currencyData?.number_format) {\n return currencyData.number_format;\n }\n try {\n const userData = JSON.parse(localStorage.getItem('user') || '{}');\n return userData?.currency_data?.number_format || \"\";\n } catch {\n return \"\";\n }\n};\n\n/**\n * Get the default company from localStorage user data.\n * This is a utility function (not a hook) so it can be safely called anywhere.\n * @param userData - Optional pre-fetched user data to avoid localStorage lookup\n */\nexport const defaultCompany = (userData?: { accessCompanies?: number[]; company_id?: number | null }) => {\n let user = userData;\n if (!user) {\n try {\n user = JSON.parse(localStorage.getItem('user') || '{}');\n } catch {\n return null;\n }\n }\n const accessCompanies = user?.accessCompanies || [];\n const defaultCompanyId = user?.company_id || null;\n\n let dcId = defaultCompanyId;\n\n if (Array.isArray(accessCompanies) && accessCompanies?.length > 0) {\n if (!accessCompanies?.includes(defaultCompanyId as number)) {\n dcId = accessCompanies?.[0];\n }\n }\n\n return dcId ? Number(dcId) : null;\n};\n\nexport function omitDataKeys<T>(obj: T, extra?: Array<string>): T {\n // Default keys to omit\n const defaultOmitKeys = [\n \"created_at\",\n \"updated_at\",\n \"created_by\",\n \"created_user\",\n \"updated_by\",\n \"updated_user\",\n \"is_deleted\",\n \"deleted_user\",\n \"deleted_by\",\n \"deleted_at\",\n ...(extra ? extra : []),\n ];\n\n // Handle arrays separately without converting them to objects\n if (Array.isArray(obj)) {\n // Recursively process array elements\n return obj.map((item) => omitDataKeys(item, extra)) as unknown as T;\n }\n\n // Check if obj is an object\n if (_.isObject(obj) && !Array.isArray(obj)) {\n // Recursively apply omit on each property of the object\n return _.mapValues(\n _.omitBy(\n obj,\n (_, key) =>\n defaultOmitKeys.includes(key) ||\n key.endsWith(\"_data\") ||\n key.endsWith(\"_status\")\n ),\n (value) => {\n // Recurse on nested objects, excluding Day.js instances\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return omitDataKeys(value, extra);\n }\n return value;\n }\n ) as T;\n }\n\n // If it's neither an object nor an array, return the value as is (e.g., strings, numbers)\n return obj;\n}\n\n// Define a type for the input objects in the array\nexport interface DataObject {\n [key: string]: any;\n}\n\n// Define a type for the processed object with label and value\nexport interface LabelValueObject extends DataObject {\n label: string;\n value: string | number | null;\n}\n\n/**\n * A global function to process an array of objects and return formatted label-value pairs.\n *\n * @param {Array<T>} dataArray - The array of objects to be processed.\n * @param {Array<T>} fallbackArray - The fallback array if dataArray is empty.\n * @param {Array<keyof T | string>} labelKeys - The keys to be concatenated for the label.\n * @param {keyof T | string} valueKey - The key to be used for the value.\n * @param {Function} [labelFormatter] - Optional custom formatter for label.\n * @returns {Array<LabelValueObject>} - The processed array of label-value objects.\n */\nexport const getLabelValuePairs = <T extends DataObject>(\n dataArray: T[],\n fallbackArray: T[],\n labelKeys: (keyof T | string)[],\n valueKey: keyof T | string,\n labelFormatter?: (item: T) => string\n): LabelValueObject[] => {\n return (\n _.map(dataArray, (item: T) => {\n const label = labelFormatter\n ? labelFormatter(item)\n : _.compact(labelKeys.map((key) => _.get(item, key, \"\"))).filter(v => Boolean(v?.trim())).join(\", \");\n\n return {\n ...item,\n label,\n value: _.get(item, valueKey, null),\n };\n }) || fallbackArray\n );\n};\nexport function formatEmptyDataToNull<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatEmptyDataToNull(item)) as unknown as T;\n }\n\n // If it's an object, iterate through the values and apply transformations\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n // Recursively handle nested objects or arrays\n if (\n Array.isArray(value)\n ) {\n return (value);\n }\n if (\n _.isObject(value) &&\n !dayjs.isDayjs(value) &&\n !(value instanceof File)\n ) {\n return formatEmptyDataToNull(value);\n }\n\n // Replace empty values (except 0) with null\n if (!value && value !== 0 && value !== false) {\n return null;\n }\n\n // Special handling for specific key patterns\n if (\n (key.includes(\"_id\") && !key.includes(\"_ids\")) ||\n key.includes(\"_amount\")\n ) {\n // Convert values for '_id' or '_amount' keys to numbers\n return Array.isArray(value) ? value.map(Number) : Number(value);\n } else if (key.includes(\"date_time\")) {\n // Format date fields\n return formatDateTimeForPayload(value);\n } else if (key.includes(\"date\")) {\n // Format date fields\n return formatDateForPayload(value);\n } else if (key.includes(\"_time\")) {\n // Format time fields\n return formatTimeForPayload(value);\n } else if (Array.isArray(value)) {\n // Ensure arrays are not replaced by null if they're empty\n return value.length ? value : [];\n }\n\n // Return the original value if no other transformation applies\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\nexport function downloadFile(fileUrl: string, fileName = \"\") {\n console.log(fileUrl);\n if (!fileUrl || fileUrl === \"\") return;\n const a = document.createElement(\"a\");\n a.target = \"_blank\";\n a.href = fileUrl;\n a.download = fileName;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n}\n\n//Download Doc\n//eslint-disable-next-line\nexport const downloadDoc = async ({\n api,\n // fileName,\n raw\n}: {\n api: string,\n fileName: string,\n raw: any\n}) => {\n const headers = {\n \"Content-Type\": \"application/json\",\n ...getToken()\n };\n const response = await fetch(`${import.meta.env.VITE_BACKEND_BASE_URL}/${api}`,\n {\n method: \"POST\",\n headers,\n body: raw,\n redirect: \"follow\",\n }\n );\n\n if (!response.ok) {\n throw new Error(await response.text());\n }\n const blob = await response.blob();\n const url = window.URL.createObjectURL(blob);\n window.open(url, '_blank');\n // Revoke the blob URL after some time to avoid memory leaks\n setTimeout(() => window.URL.revokeObjectURL(url), 1000);\n // const a = document.createElement(\"a\");\n // a.href = url;\n // a.download = fileName;\n // document.body.appendChild(a);\n // a.click();\n // a.remove();\n // window.URL.revokeObjectURL(url);\n}\n\nexport function formatResponseDatesToDayJS<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatResponseDatesToDayJS(item)) as unknown as T;\n }\n\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return formatResponseDatesToDayJS(value);\n }\n\n if (key.includes(\"date\") && value) {\n return dayjs.utc(value);\n }\n if (key.includes(\"_time\") && value) {\n return dayjs(`${dayjs().utc().format(\"YYYY-MM-DD\")} ${value}`);\n }\n\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\nexport const toFixedWithNumbers = (num: number) => num > 0 ? Number(num)?.toFixed(2) : num;\n\nexport const findById = (arr: Array<any>, id: any) =>\n arr.find((a) => a.id == id);\n\nexport const getTaxAmountFromMultipleTaxCodes = (\n amount: number,\n taxCodes = [],\n detail = false\n) => {\n if (!amount) return 0;\n\n let totalTaxAmount = 0;\n const taxCodeDetail = taxCodes?.map((code: any) => {\n const taxAmount = amount * (code.rate / 100);\n totalTaxAmount += taxAmount;\n\n return {\n id: code.id,\n name: code.name,\n rate: code.rate,\n tax_amount: taxAmount,\n };\n });\n\n if (detail) {\n return taxCodeDetail;\n }\n return totalTaxAmount;\n};\n\nexport const getTaxAmountDataFromMultipleTaxCodes = (\n grossAmount: number,\n netAmount: number,\n taxCodes = [],\n detail = false\n) => {\n let totalTaxAmount = 0;\n let totalTaxRate = 0;\n const taxCodeDetail = taxCodes.map((code: any) => {\n const taxBaseAmount =\n code.applies_to === \"Gross\" ? netAmount : grossAmount;\n // const taxAmount = grossAmount * (code.rate / 100);\n const taxAmount = taxBaseAmount * (code.rate / 100);\n totalTaxAmount += taxAmount;\n totalTaxRate += code.rate;\n\n return {\n id: code.id,\n name: code.name,\n rate: code.rate,\n tax_amount: taxAmount,\n };\n });\n\n if (detail) {\n return taxCodeDetail;\n }\n return {\n amount: totalTaxAmount,\n rate: totalTaxRate,\n };\n};\n\nexport const calculateAmountData = (quantity: number, rate: number, discount_rate: number | null, discounted_items: any, taxCodes = []) => {\n const amount = quantity * rate;\n let discountAmount = Number(discount_rate);\n if (discounted_items?.discount_category === \"rate\") {\n discountAmount = discount_rate ? amount * (discount_rate / 100) : 0;\n }\n let grossAmount = amount - discountAmount || 0;\n if (grossAmount < 0) {\n grossAmount = 0;\n }\n const taxData = getTaxAmountDataFromMultipleTaxCodes(\n grossAmount,\n amount,\n taxCodes\n );\n\n const taxAmount = taxData?.amount || 0;\n const taxRate = taxData?.rate || 0;\n\n const netAmount = grossAmount + Number(taxAmount) || 0;\n const totalAmount = grossAmount + Number(taxAmount) || 0;\n\n return { grossAmount, taxAmount, taxRate, discountAmount, netAmount, totalAmount }\n}\n\nexport type AnyObject = Record<string, any>;\n\nexport const hasValue = (\n object: AnyObject,\n skipFields: string[] = []\n): boolean => {\n const checkValue = (value: any, skipFields: string[]): boolean => {\n if (_.isArray(value)) {\n // If it's an array, recursively check its elements\n return _.some(value, (item) => checkValue(item, skipFields));\n }\n\n if (_.isPlainObject(value)) {\n // If it's an object, recursively check its keys and values\n return _.some(value, (val, key) => {\n if (skipFields.includes(key)) return false; // Skip specified fields\n return checkValue(val, skipFields);\n });\n }\n\n // Return true for any non-null, non-undefined, and non-empty value\n return !_.isNil(value) && !_.isEmpty(value);\n };\n\n return checkValue(object, skipFields);\n};\nexport const formatAmountWithCurrency = (\n amount: number,\n currencySymbol?: string\n): string => {\n if (!amount) {\n return `${currencySymbol ? currencySymbol : \"\"}`;\n }\n const defaultSymbol = defaultCurrencySymbol();\n const symbol = currencySymbol || defaultSymbol;\n\n return `${symbol} ${Number(amount).toFixed(2)}`;\n};\nexport const formatAmountWithCurrencyData = (\n amount: number,\n currencySymbol?: string\n): string => {\n if (!amount) {\n return \"\";\n }\n const symbol = currencySymbol || '';\n\n return `${symbol} ${Number(amount).toFixed(2)}`;\n};\n\nexport type ManageItemsOptions = {\n key: string;\n action: \"add\" | \"update\" | \"delete\";\n value: any;\n items: any[];\n itemIndex: number\n};\n\nexport const manageItems = ({\n key,\n action,\n value,\n items = [],\n itemIndex\n}: ManageItemsOptions): any[] => {\n switch (action) {\n case \"add\": {\n // const existingItem = items?.find((item) => item[key] === value[key]);\n // if (existingItem) {\n // // Update the existing item\n // return items?.map((item) => (item[key] === value[key] ? value : item));\n // }\n // Add a new item\n return [...items, value];\n }\n\n case \"update\": {\n // Update an existing item\n return items.map((item, index) => ((itemIndex >= 0 ? itemIndex === index : item[key] === value[key]) ? value : item));\n }\n\n case \"delete\": {\n // Delete an item based on\n if (value?.index !== undefined) {\n return items.filter((_, index) => index !== value.index);\n }\n return items.filter((item) => item[key] !== value[key]);\n }\n\n default:\n console.warn(`Unsupported action type: ${action}`);\n return items;\n }\n};\n\nexport function getPartyName(\n party: Record<any, any> | null | undefined\n): string {\n if (!party) return \"\";\n\n const {\n name = \"\",\n first_name = \"\",\n middle_name = \"\",\n last_name = \"\",\n company_name = \"\",\n } = party;\n\n // Trim values and handle potential null values\n const trimmedName = name?.trim() || \"\";\n const trimmedFirstName = first_name?.trim() || \"\";\n const trimmedMiddleName = middle_name?.trim() || \"\";\n const trimmedLastName = last_name?.trim() || \"\";\n const trimmedCompanyName = company_name?.trim() || \"\";\n\n\n if (party?.account_type === 'Individual') {\n return [trimmedFirstName, trimmedMiddleName, trimmedLastName].filter(Boolean).join(' ');\n } else if (party?.account_type === 'Company') {\n return trimmedCompanyName\n } else {\n if (trimmedName) return trimmedName;\n if (trimmedFirstName) {\n return [trimmedFirstName, trimmedMiddleName, trimmedLastName].filter(Boolean).join(' ');\n }\n if (trimmedCompanyName) return trimmedCompanyName;\n }\n\n return \"\";\n}\n\nexport const partyEmailIds = (json: any): string => {\n if (!json) return \"\";\n\n try {\n const parsed = JSON.parse(json);\n return Array.isArray(parsed) ? parsed.join(\", \") : \"\";\n } catch {\n return json;\n }\n};\n\nexport function formatResponseOnlyDatesToDayJS<T>(obj: T): T {\n // Check if the input is an array and process each item recursively\n if (Array.isArray(obj)) {\n return obj.map((item) => formatResponseDatesToDayJS(item)) as unknown as T;\n }\n\n if (_.isObject(obj)) {\n return _.mapValues(obj, (value, key) => {\n if (_.isObject(value) && !dayjs.isDayjs(value)) {\n return formatResponseDatesToDayJS(value);\n }\n\n if (key.includes(\"date\") && value) {\n return dayjs(value);\n }\n\n return value;\n }) as T;\n }\n\n // If it's neither an object nor an array, return the value as is\n return obj;\n}\n\n\n/* fetch exchange & reverse rates */\nexport const fetchExchageRate = async (id: string, type: string = 'Buying') => {\n try {\n const response = await postV1CurrencyInfo({\n currancy_id: id,\n type: type,\n ...getToken()\n });\n\n const { exchange_rate = 1, reverse_rate = 1 } = response?.data || {};\n return { exchange_rate, reverse_rate };\n } catch (error) {\n return { exchange_rate: 1, reverse_rate: 1 };\n }\n};\n\n\nexport const showSnackBar = (error: any) => {\n const message = getErrorMessage(error?.message)\n enqueueSnackbar(message, {\n variant: \"error\",\n });\n}\n\nexport const fetchCompanyLocations = async (companyId: number) => {\n\n const res = await fetchApi(\n {\n apiKey: 'location',\n filters: {\n filters: { '&company_id.in': companyId }\n }\n });\n return res?.data || []\n}\n\nexport const fetchItems = async (itemId: number, attributes?: string) => {\n\n const res = await fetchApi(\n {\n apiKey: 'items',\n filters: {\n filters: { '&id.in': itemId },\n select: attributes\n }\n });\n return res?.data || []\n}\n\n\nexport const getOptionsData = async (key: string, id: number, select?: any, isArray = false) => {\n const res = await fetchApi(\n {\n apiKey: key,\n filters: {\n filters: { '&id.in': id },\n select\n }\n });\n return isArray ? res?.data : Array.isArray(res?.data) ? res?.data[0] : null;\n}\n\n\nexport const fetchOptions = async (key: string, filters: any, select?: any, isArray = false) => {\n const res = await fetchApi(\n {\n apiKey: key,\n filters: {\n filters: filters,\n select\n }\n });\n return isArray ? res?.data : Array.isArray(res?.data) ? res?.data[0] : null;\n}\nexport const createdOnAndBy = (data: any) => {\n const { created_at = '', created_user = {}, created_by_data = {} } = data || {}\n const { first_name = '', last_name = '' } = Object.keys(created_user)?.length ? created_user : created_by_data\n const fName = first_name?.trim() || '';\n const lName = last_name?.trim() || '';\n const cAt = created_at?.trim() || '';\n\n const text = `Created on ${formatDate(cAt, 'DD MMM, YYYY')}`\n\n if (!(fName || lName)) return text;\n\n return `${text} · ${formatText(`${fName} ${lName}`)}`\n}\n\n/**\n * Returns the full name of an object based on the provided keys.\n * The object is expected to have the keys as its properties.\n * If the object is empty, returns a default value.\n * @param {Record<string, any>} obj - The object to process\n * @param {string[]} keys - The keys to use for forming the name\n * @returns {string} The full name of the object\n */\nexport const getName = (obj: Record<string, any>, keys: string[]) => {\n if (_.isEmpty(obj)) {\n // If the object is empty, return a default value\n return \"-\";\n }\n\n // Map over the keys and get the corresponding values from the object\n // Filter out any values that are falsy or have no trimmed value\n // Join the remaining values with a space in between\n return keys\n .map((key) => obj?.[key])\n .filter((n) => Boolean(n && n?.trim()))\n .join(\" \");\n};\n\nexport const getToken = () => {\n const timezone = moment.tz.guess();\n const offsetMinutes = moment.tz.zone(timezone).utcOffset(moment());\n const requestToken = {\n \"x-token\": localStorage.getItem(auth.storageTokenKeyName) || undefined,\n \"x-timezone\": offsetMinutes,\n };\n\n return requestToken;\n};\n\nexport const checkForDuplicate = async (payload: any) => {\n try {\n const response = await postV1PartiesCheck({ ...getToken(), ...payload })\n return response?.data?.party_exists || false\n } catch (error) {\n throw new Error('An error occurred while checking for duplicates.')\n }\n}\n\nexport const partyDuplicateCheck = async (\n activeTab: number | string,\n fValues: Record<string, any>,\n defaultValues?: Record<string, any>\n): Promise<string | null> => {\n\n const values = { ...fValues };\n // Return early if activeTab is not 0 or required fields are not present\n if (activeTab !== 0 || !(values?.contact_no || values?.company_name)) {\n return null;\n }\n\n if (activeTab !== 0 || (!values?.contact_no && values?.company_name && values?.account_type !== 'Company')) {\n return null;\n }\n\n const phoneNumber = parsePhoneNumberFromString(values?.contact_no?.includes('+') ? values?.contact_no : `+${values?.contact_no}`);\n values.contact_no = phoneNumber?.nationalNumber || '';\n values.country_code = phoneNumber?.countryCallingCode || '';\n\n // Determine if contact number or company name values have changed\n const cDefaultValueContactNo = defaultValues?.contact_no || ''\n const cValueContactNo = displayPhone(values)\n\n const isDirtyPhone =\n !defaultValues ||\n cDefaultValueContactNo?.trim() !== cValueContactNo?.trim();\n const isDirtyCompanyName =\n !defaultValues ||\n defaultValues?.company_name?.trim() !== values?.company_name?.trim();\n\n // If neither field has changed, no need to check for duplicates\n if (!isDirtyPhone && !isDirtyCompanyName) {\n return null;\n }\n\n // Parse phone number to extract country code and national number\n const countryCode = phoneNumber?.nationalNumber ? phoneNumber?.countryCallingCode\n ? `+${phoneNumber?.countryCallingCode}` : ''\n : values?.country_code;\n const contactNo = phoneNumber?.nationalNumber || values?.contact_no;\n\n // Construct payload for duplicate check\n const duplicateCheckPayload = {\n party: {\n account_type: values?.account_type, // \"Individual\" or \"Company\"\n ...(isDirtyPhone && countryCode ? { country_code: countryCode } : {}),\n ...(isDirtyPhone && contactNo ? { contact_no: contactNo } : {}),\n ...(values?.account_type === 'Company' && isDirtyCompanyName\n ? { company_name: values?.company_name }\n : {}),\n },\n };\n\n try {\n // Call API to check for duplicates\n const isDuplicate = await checkForDuplicate(duplicateCheckPayload);\n\n if (isDuplicate) {\n // Prepare and return an appropriate error message\n const duplicateType =\n values?.account_type === 'Company' ? phoneNumber?.nationalNumber ? 'company name or phone' : 'company name' : 'phone number';\n return `Added ${duplicateType} already exists. Please add a different ${duplicateType}.`;\n }\n } catch (error: any) {\n // Return error message in case of API failure\n return error.message || 'An error occurred while checking for duplicates.';\n }\n\n // Return null if no duplicates are found\n return null;\n};\n\nexport const displayPhone = (data: Record<string, any>) => {\n const { contact_no = '', country_code = '' } = data || {}\n\n if (!contact_no) return ''\n\n if (country_code) {\n if (country_code?.includes(\"+\")) {\n return `${country_code}${contact_no}`\n }\n return `+${country_code}${contact_no}`\n }\n\n return contact_no?.includes(\"+\") ? contact_no : `+${contact_no}`\n}\n\nexport const getPartyDependentData = async (\n id: number,\n options?: any\n) => {\n let ad: any[] = [],\n co: any[] = [],\n cr = options?.currencies || [],\n cm = options?.companies || [],\n dsa = null,\n dba = null,\n pt = null,\n sp = null;\n\n const res = await getV1PartiesId({ id, ...getToken() });\n const p = res?.data?.parties?.party?.data || null;\n if (p) {\n const {\n payment_term = null,\n party_address_data = [],\n party_contact_data = [],\n currencies_data = [],\n companies_data = [],\n salesperson = null\n } = p;\n\n ad = party_address_data\n co = party_contact_data;\n cr = currencies_data;\n cm = companies_data;\n pt = payment_term;\n dsa = party_address_data?.find((addr: any) => Boolean(addr?.default_shipping_address));\n dba = party_address_data?.find((addr: any) => Boolean(addr?.default_billing_address));\n sp = salesperson\n }\n\n return {\n addresses: ad,\n contacts: co,\n currencies: cr,\n currencyIds: cr.map((c: any) => c.id),\n companies: cm,\n companyIds: cm.map((c: any) => c.id),\n paymentTerm: pt,\n defaultShipping: dsa,\n defaultBilling: dba,\n salesperson: sp\n };\n};\n\nexport interface PayloadMapping {\n [key: string]: string | string[] | ((values: Record<string, any>) => any);\n}\n\n/**\n * Maps API payload by transforming values based on the provided mapping configuration.\n * \n * @param {PayloadMapping} payloadMapping - An object defining the mapping configuration.\n * @param {Record<string, any>} values - The source values to be transformed.\n * @returns {Record<string, any>} The transformed payload object.\n */\nconst isEmptyValue = (value: any): boolean => {\n return _.isNil(value) || value === '' || (_.isObject(value) && _.isEmpty(value));\n};\n\nexport const mapApiPayload = (payloadMapping: PayloadMapping, values: Record<string, any>): Record<string, any> => {\n return _.mapValues(payloadMapping, (val) => {\n // If the mapping value is a function, execute it with the values as the argument\n if (_.isFunction(val)) {\n return (val as (values: Record<string, any>) => any)(values);\n }\n // If the mapping value is an array, map each element to its corresponding value in the source\n if (_.isArray(val)) {\n return (val as string[]).map((key) => _.get(values, key, null));\n }\n // If the mapping value is an object (excluding Day.js), recursively process it\n if (_.isObject(val) && !_.isFunction(val) && !dayjs.isDayjs(val)) {\n return mapApiPayload(val as PayloadMapping, values);\n }\n // Directly map a single key to its value in the source\n const result = _.get(values, val, null)\n return isEmptyValue(result) ? null : result\n });\n};\n\nexport const mapAsyncApiPayload = async (payloadMapping: PayloadMapping, values: Record<string, any>): Promise<Record<string, any>> => {\n const entries = Object.entries(payloadMapping).map(async ([key, val]) => {\n if (_.isFunction(val)) {\n return [key, await val(values)];\n }\n if (_.isArray(val)) {\n const resolvedArray = await Promise.all(val.map(async (key) => _.get(values, key, null)));\n return [key, resolvedArray];\n }\n if (_.isObject(val) && !_.isFunction(val) && !dayjs.isDayjs(val)) {\n return [key, await mapAsyncApiPayload(val as PayloadMapping, values)];\n }\n return [key, _.get(values, val, null)];\n });\n\n return Object.fromEntries(await Promise.all(entries));\n};\n\n\nexport const isBetweenTheDates = (startDate: any, endDate: any) => {\n if (!startDate || !endDate) return false;\n const start = dayjs(startDate).startOf('day');\n const end = dayjs(endDate).endOf('day');\n const currentDate = dayjs();\n return currentDate.isAfter(start) && currentDate.isBefore(end) || currentDate.isSame(start) || currentDate.isSame(end);\n};\n\nexport const setRateBasedOnPriceRules = (salesPrice: any, priceRules: any, addedQuantity: any) => {\n let updatedRate = salesPrice\n if (priceRules?.length) {\n const sortedPriceRules = _.orderBy(\n priceRules,\n ['minimum_quantity'],\n ['desc']\n );\n for (const pRules of sortedPriceRules) {\n if (Number(addedQuantity) >= Number(pRules?.minimum_quantity)) {\n if (isBetweenTheDates(pRules?.start_date, pRules?.end_date)) {\n updatedRate = Number(pRules?.unit_price) || undefined;\n break;\n }\n }\n }\n }\n return updatedRate\n};\n\n\nexport const uploadAttachments = async (files: any) => {\n let existingAttachments =\n files?.filter((i: File | string) => !(i instanceof File)) || [];\n const newFiles = files?.filter((i: File | string) => i instanceof File) || [];\n const bUrl = import.meta.env.VITE_S3_BUCKET_URL;\n existingAttachments = existingAttachments.map((ea: string) =>\n ea.replace(bUrl, \"\")\n );\n\n let uplaodedAttachments: string[] = [];\n\n if (newFiles.length) {\n uplaodedAttachments = await uploadFiles(newFiles, \"sales\");\n }\n\n uplaodedAttachments = [...uplaodedAttachments, ...existingAttachments];\n if (Array.isArray(uplaodedAttachments) && uplaodedAttachments?.length) {\n return uplaodedAttachments.join(\",\");\n }\n return null;\n};\n\nexport const addOrEditArray = (array: any[] = [], data: any) => {\n const { itemIndex, ...updatedData } = data;\n\n const newArray = [...array];\n\n if (newArray[itemIndex]) {\n newArray[itemIndex] = { ...updatedData };\n return newArray;\n }\n\n return [...newArray, updatedData];\n};\nexport const getAccessibleModules = (moduleNames: string[] = []): string[] => {\n const uData = localStorage.getItem(\"_u_data\");\n const userData = uData ? JSON.parse(uData) : {};\n const accessModules = userData?.module_access || [];\n\n const findSubModules = accessModules\n .filter(module => moduleNames.includes(module.module_name))\n .map(module => ({\n ...module,\n sub_modules: [...(module.sub_modules || []), { sub_module_name: \"dashboard\" }],\n }));\n\n const subModuleNamesSet = new Set(\n findSubModules.flatMap(module => module.sub_modules.map(subModule => subModule.sub_module_name))\n );\n\n const permission = JSON.parse(localStorage.getItem(\"role-permission\") || \"{}\");\n return Array.from(subModuleNamesSet).filter(subModule =>\n Object.keys(permission).some(key => key.startsWith(subModule.split(\"/\").pop()))\n ) as string[];\n};\n\nexport const filterAccessibleModules = (menu: any, moduleNames: string[] = []) => {\n const accessibleMenus = new Set(getAccessibleModules(moduleNames))\n\n\n return menu.reduce((filtered, item) => {\n const isSubModuleValid = item.bacSubModuleName && accessibleMenus.has(item.bacSubModuleName);\n const filteredSubmenu = item.submenu?.length ? filterAccessibleModules(item.submenu, moduleNames) : [];\n\n if (isSubModuleValid || filteredSubmenu.length) {\n filtered.push({ ...item, submenu: filteredSubmenu });\n }\n return filtered;\n }, []);\n}\n\n// Usage example:\n// const accessibleModules = getAccessibleModules([\"manufacturing\", \"inventory\", \"sales\"]);\n\n\nexport const checkDuplicateTracking = (data: any, typeOfTrcebility: string, trackRows: any[]) => {\n\n let isDuplicate = false\n let errorMsg = null\n // Check for duplicate tracking numbers\n const isSerialTracking = typeOfTrcebility === 'Serial Number Tracking';\n const trackingField = isSerialTracking ? 'serial_number' : 'lot_number';\n const inputValue = isSerialTracking\n ? data?.add_stock_transfer?.lot_number?.serial_number\n : data?.add_stock_transfer?.lot_number?.lot_number;\n errorMsg = isSerialTracking\n ? \"This serial Number is already available\"\n : \"This lot Number is already available\";\n\n if (trackRows[data?.itemIndex]?.[trackingField] == inputValue) {\n return { isDuplicate: false }\n }\n if (['Serial Number Tracking', 'Lot Tracking'].includes(typeOfTrcebility)) {\n isDuplicate = trackRows.some((o) =>\n o?.[trackingField] === inputValue\n );\n }\n return {\n isDuplicate,\n errorMsg\n }\n}\nexport function getNestedValue(obj: any, path: any) {\n return path.split('.').reduce((acc: any, key: any) => (acc && acc[key] !== undefined ? acc[key] : undefined), obj);\n}\n\n// export const calculatePeriods = (startDateTime: Date, endDateTime: Date) => {\n// const start = dayjs(startDateTime);\n// const end = dayjs(endDateTime);\n\n// if (end.isBefore(start)) {\n// return null;\n// }\n\n// const totalMinutes = end.diff(start, 'minute');\n// if (totalMinutes < 0) {\n// return null;\n// }\n\n// let current = dayjs(start);\n// let years = 0;\n// let months = 0;\n// let days = 0;\n// let hours = 0;\n// // let minutes = 0;\n\n// // Calculate years\n// while (current.add(1, 'year').isBefore(end) || current.add(1, 'year').isSame(end)) {\n// years++;\n// current = current.add(1, 'year');\n// }\n\n// // Calculate months\n// while (current.add(1, 'month').isBefore(end) || current.add(1, 'month').isSame(end)) {\n// months++;\n// current = current.add(1, 'month');\n// }\n\n// // Calculate days \n// while (current.add(1, 'day').isBefore(end) || current.add(1, 'day').isSame(end)) {\n// days++;\n// current = current.add(1, 'day');\n// }\n\n// // Calculate hours\n// while (current.add(1, 'hour').isBefore(end) || current.add(1, 'hour').isSame(end)) {\n// hours++;\n// current = current.add(1, 'hour');\n// }\n\n// // Calculate remaining minutes\n// // minutes = end.diff(current, 'minute');\n\n// const parts = [];\n\n// if (years > 0) {\n// parts.push(`${years} ${years === 1 ? 'Year' : 'Years'}`);\n// }\n// if (months > 0) {\n// parts.push(`${months} ${months === 1 ? 'Month' : 'Months'}`);\n// }\n// if (days > 0) {\n// parts.push(`${days} ${days === 1 ? 'Day' : 'Days'}`);\n// }\n// if (hours > 0) {\n// parts.push(`${hours} ${hours === 1 ? 'Hour' : 'Hours'}`);\n// }\n// // if (minutes > 0) {\n// // parts.push(`${minutes} ${minutes === 1 ? 'Minute' : 'Minutes'}`);\n// // }\n\n// if (parts.length === 0) {\n// return '0 Minutes';\n// }\n\n// return parts.join(' ');\n// };\n//eslint-disable-next-line\nexport const calculatePeriods = (\n startDateTime: Date,\n endDateTime: Date,\n mode: 'Day' | 'Week' | 'Month' | 'Calendar Month' | 'Year' | 'Hour' = 'Month'\n) => {\n const start = dayjs(startDateTime);\n const end = dayjs(endDateTime);\n\n if (end.isBefore(start)) {\n return null;\n }\n\n switch (mode) {\n case 'Year': {\n const years = end.diff(start, 'year');\n const remainingMonths = end.diff(start.add(years, 'year'), 'month');\n return `${years} ${years === 1 ? 'Year' : 'Years'}${remainingMonths > 0 ? `, ${remainingMonths} ${remainingMonths === 1 ? 'Month' : 'Months'}` : ''}`;\n }\n\n case 'Month':\n case 'Calendar Month': {\n const months = end.diff(start, 'month');\n const remainingDays = end.diff(start.add(months, 'month'), 'day');\n return `${months} ${months === 1 ? 'Month' : 'Months'}${remainingDays > 0 ? `, ${remainingDays} ${remainingDays === 1 ? 'Day' : 'Days'}` : ''}`;\n }\n\n case 'Week': {\n const weeks = end.diff(start, 'week');\n const remainingDaysWeekly = end.diff(start.add(weeks, 'week'), 'day');\n return `${weeks} ${weeks === 1 ? 'Week' : 'Weeks'}${remainingDaysWeekly > 0 ? `, ${remainingDaysWeekly} ${remainingDaysWeekly === 1 ? 'Day' : 'Days'}` : ''}`;\n }\n\n case 'Day': {\n const totalHours = end.diff(start, 'hour');\n const days = Math.floor(totalHours / 24);\n const remainingHours = totalHours % 24;\n\n if (remainingHours > 0) {\n return `${days + 1} ${days + 1 === 1 ? 'Day' : 'Days'}`;\n }\n return `${days} ${days === 1 ? 'Day' : 'Days'}`;\n }\n\n case 'Hour': {\n const hours = end.diff(start, 'hour');\n return `${hours} ${hours === 1 ? 'Hour' : 'Hours'}`;\n }\n\n default:\n return 'Invalid mode';\n }\n};\nexport const removeIdFromObject = (array: any) => array?.map(i => ({\n ...i,\n id: undefined\n}))\n\nexport const fetchRentalResponseItems = async (filters: string) => {\n //eslint-disable-next-line\n try {\n const response = await getV1CrossHireRfqResponseItems({\n filters,\n ...getToken(),\n });\n\n return response?.data?.rfq_response_items ?? [];\n } catch (error) {\n throw error;\n }\n};\nexport const fetchRfqItemsByIdForResponse = async (filters: string) => {\n //eslint-disable-next-line\n try {\n const response = await getV1RfqResponseItems({\n filters,\n ...getToken(),\n });\n\n return response?.data?.rfq_response_items ?? [];\n } catch (error) {\n throw error;\n }\n};\n\nexport const appendConditionSafely = (original: string | undefined, newCondition: string): string => {\n const cleanConditionString = (str: string): string => {\n // Remove leading special chars except '('\n return str.trim().replace(/^([^\\w(]+)/, '');\n };\n\n const extractConditions = (str: string): string[] => {\n // Remove outermost brackets if they exist, then split by '&' or ','\n return str\n .trim()\n .replace(/^[(]|[)]$/g, '')\n .split(/[&,]/)\n .map((cond) => cond.trim())\n .filter(Boolean);\n };\n\n // If no original, clean newCondition and wrap in ()\n if (!original || typeof original !== 'string' || original.trim() === '') {\n const cleaned = cleanConditionString(newCondition);\n return `(${cleaned})`;\n }\n\n // Extract existing and new conditions\n const existingConditions = new Set<string>(extractConditions(original));\n const incomingConditions = extractConditions(newCondition);\n\n // Filter out duplicates\n const filteredNew = incomingConditions.filter(\n (cond) => !existingConditions.has(cond)\n );\n\n // Combine both\n const allConditions = [...existingConditions, ...filteredNew];\n return `(${allConditions.join('&')})`;\n};\n\n\nexport const fetchAssemblyItemData = async (itemId: number) => {\n const response = await getV1AssemblyItemsId({\n id: itemId,\n ...getToken()\n });\n return response?.data?.data || null;\n};\nexport const getFileName = (file) => {\n if (!file) return \"\"\n if (file instanceof File) {\n return file.name\n } else if (typeof file === 'string') {\n const parts = file?.split('/');\n return parts?.[parts?.length - 1];\n } else if (Array.isArray(file) && file?.length > 0) {\n return file.map(f => {\n if (f instanceof File) {\n return f.name\n }\n const parts = f?.split('/');\n return parts?.[parts?.length - 1];\n }).join(', ')\n }\n}\n\nexport const getFieldFilters = (fields: any[], fieldNames: string | string[]) => {\n if (!fields?.length) return Array.isArray(fieldNames) ? new Map() : {};\n const filters = new Map()\n if (Array.isArray(fieldNames) && fieldNames?.length) {\n fieldNames.forEach(f => {\n const filt = fields.find(fi => fi.name === f)?.field_properties?.customeFilter || {}\n filters.set(f, filt)\n })\n return filters\n }\n return fields.find(fi => fi.name === fieldNames)?.field_properties?.customeFilter || {}\n};\n\nexport const getNextScheduleDate = (currentDate: any, billingCycle: any) => {\n switch (billingCycle?.duration) {\n case 'Hour':\n return dayjs(currentDate).add(1, 'hour');\n case 'Day':\n return dayjs(currentDate).add(1, 'day');\n case 'Week':\n return dayjs(currentDate).add(1, 'week');\n case '2 Week':\n return dayjs(currentDate).add(2, 'week');\n case 'Month':\n // \"Month\" means actual 1 month (30 days)\n return dayjs(currentDate).add(30, 'day');\n case 'Calendar Month':\n // \"Calendar Month\" means end of the month\n return dayjs(currentDate).endOf('month').add(1, 'day').startOf('day');\n case 'Quarter':\n case '3 Month':\n return dayjs(currentDate).add(3, 'month');\n case '6 Month':\n return dayjs(currentDate).add(6, 'month');\n case 'Year':\n case '1 Year':\n return dayjs(currentDate).add(1, 'year');\n case '3 Year':\n return dayjs(currentDate).add(3, 'year');\n case '5 Year':\n case '5Year':\n return dayjs(currentDate).add(5, 'year');\n default:\n return dayjs(currentDate).add(1, 'month');\n }\n};\n//eslint-disable-next-line\nexport const getCountryIdByName = async (name: string) => {\n const response = await getV1LocationsCountries({\n filters: `(name.like=%${name}%)`,\n ...getToken(),\n });\n return response?.data?.countries?.[0]?.id || null;\n\n}\nexport const getSlicedValue = (value: string, length: number): string => {\n if (!value) return '';\n return value.slice(0, length);\n};\n\nexport const skuGenerator = ({\n name,\n category,\n sequence = '0001'\n}: {\n name: string;\n category: string;\n sequence?: string;\n}): string => {\n const cleanCategory = category.replace(/[^a-zA-Z0-9]/g, '');\n const cleanName = name.replace(/[^a-zA-Z0-9]/g, '');\n\n const categoryPart = getSlicedValue(cleanCategory, 3).toUpperCase();\n const namePart = getSlicedValue(cleanName, 3).toUpperCase();\n\n return `${categoryPart}-${namePart}-${sequence}`;\n};\n\nexport const checkSkuAndItemName = async (payload: any) => {\n const response = await postV1InventoryItemsCheck({\n ...payload,\n ...getToken(),\n });\n return response?.data?.item_exists || null;\n}\n\nexport interface FormValues {\n [key: string]: any;\n}\n\n/**\n * Helper function to process field disabling logic\n */\nconst processFieldDisabling = (\n currentFieldValue: any,\n valueConfig: any,\n fieldsToDisableSet: Set<string>\n): void => {\n if (currentFieldValue !== null && currentFieldValue !== undefined) {\n // Convert current value to string for consistent comparison\n const valueKey = String(currentFieldValue);\n\n // Check for exact match first\n if (valueConfig[valueKey]) {\n valueConfig[valueKey].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n // Check for type-specific matches (boolean, number)\n else if (typeof currentFieldValue === 'boolean' && valueConfig[currentFieldValue]) {\n valueConfig[currentFieldValue].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n else if (typeof currentFieldValue === 'number' && valueConfig[currentFieldValue]) {\n valueConfig[currentFieldValue].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n } else if (valueConfig?.['NO_VALUE']) {\n // Handle NO_VALUE case when field is empty/null/undefined\n valueConfig['NO_VALUE'].forEach((fieldName: string) => {\n fieldsToDisableSet.add(fieldName);\n });\n }\n};\n\n// Types for the configuration object\nexport interface UpdateFieldsDisabledConfig {\n data: any[];\n materialCostingType: string;\n formValues: FormValues;\n fieldsConfig?: FieldDisableConfig;\n isEditMode?: boolean;\n isAddMode?: boolean;\n alwaysDisabledFields?: string[];\n editModeDisabledFields?: string[];\n addModeDisabledFields?: string[];\n}\n\nexport const updateFieldsDisabledState = ({\n data,\n materialCostingType,\n formValues,\n fieldsConfig = INVENTORY_FIELDS_TO_BE_DISABLED,\n isEditMode = false,\n isAddMode = false,\n alwaysDisabledFields = INVENTORY_ALWAYS_DISABLED_FIELDS,\n editModeDisabledFields = INVENTORY_EDIT_MODE_DISABLED_FIELDS,\n addModeDisabledFields = INVENTORY_ADD_MODE_DISABLED_FIELDS\n}: UpdateFieldsDisabledConfig): any[] => {\n // Create a set to track all fields that should be disabled conditionally\n const conditionallyDisabledFields = new Set<string>();\n\n // Get all field names for the current material type (for material-specific fields)\n const materialTypeFieldNames = new Set(\n data\n ?.filter(field => field?.field_properties?.type === materialCostingType)\n ?.map(field => field?.name) || []\n );\n\n // Get all field names in the form (for global fields)\n const allFieldNames = new Set(data?.map(field => field?.name) || []);\n\n // Process each configuration entry for conditional disabling\n Object.entries(fieldsConfig).forEach(([configKey, valueConfig]) => {\n if (configKey === materialCostingType) {\n // Material-specific configuration (like pipe_costing)\n Object.entries(valueConfig).forEach(([dependentFieldName, nestedValueConfig]) => {\n if (materialTypeFieldNames.has(dependentFieldName)) {\n const fieldValue = formValues?.[dependentFieldName];\n processFieldDisabling(fieldValue, nestedValueConfig, conditionallyDisabledFields);\n }\n });\n } else if (allFieldNames.has(configKey)) {\n // Global field configuration (like is_rental)\n const currentFieldValue = formValues?.[configKey];\n processFieldDisabling(currentFieldValue, valueConfig, conditionallyDisabledFields);\n }\n });\n\n // Update form fields with disabled state\n return data.map(field => {\n // Check different types of disabled states\n const isAlwaysDisabled = alwaysDisabledFields.includes(field.name);\n const isEditModeDisabled = isEditMode && editModeDisabledFields.includes(field.name);\n const isAddModeDisabled = isAddMode && addModeDisabledFields.includes(field.name);\n const isConditionallyDisabled = conditionallyDisabledFields.has(field.name);\n // const hasOriginalDisabled = field.disabled === true; // Only respect explicit true values\n\n // Field is disabled if any condition is met\n const isDisabled = isAlwaysDisabled || isEditModeDisabled || isAddModeDisabled || isConditionallyDisabled;\n\n return {\n ...field,\n disabled: isDisabled,\n disableTableAddButton: isDisabled,\n disableDefaultActionColumn: isDisabled || Boolean(field?.disableDefaultActionColumn)\n };\n });\n};\n\nexport const remainingMaterialCostingTypes = (type: string) => {\n return INVENTORY_MATERIAL_COSTING_TYPE_ARR.filter(mct => mct !== type)\n}\nexport const matchedMaterialCostingTypeLabel = (type: string) => {\n return INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS.find(o => o.value === type)?.label || null\n}\n\nexport const fetchDataLocally = (params: any, arr: any) => {\n const { search = '', limit = 25, skip = 0 } = params;\n\n // Filter entityFields based on search term\n let filteredData = arr || [];\n if (search && search.length > 0) {\n const searchLower = search.toLowerCase();\n filteredData = filteredData.filter((item: any) => {\n const label = item?.label || item?.name || '';\n return label.toLowerCase().includes(searchLower);\n });\n }\n\n const totalCount = filteredData.length;\n\n const paginatedData = filteredData.slice(skip, skip + limit).map((item: any) => ({\n ...item,\n label: item?.label || item?.name,\n value: item?.value || item?.id || item?.name\n }));\n\n return {\n data: paginatedData,\n pagination: {\n totalCount\n }\n };\n}"],"names":["token","localStorage","getItem","auth","storageTokenKeyName","spliceUploadedLocation","uploadedlocation","splitLocation","split","length","splice","join","async","fetchWithRetry","url","options","maxRetries","retryDelay","lastError","attempt","response","fetch","status","Error","statusText","error","name","delay","Math","pow","Promise","resolve","setTimeout","handleRegularUpload","files","controller","module","BASE_URL","COMPLETE_BASE_URL","authToken","onProgress","chunkSize","retryAttempts","uploaded","fileIndex","file","signal","aborted","uploadedLocation","uploadSingleFile","push","fileError","message","totalFiles","baseUrl","completeUrl","isMultipart","size","totalParts","ceil","preSignedResponse","encodeURIComponent","type","method","headers","toString","ok","errorData","json","catch","pData","preSignedData","_a","data","uploadId","preSignedUrls","presignedUrl","location","handleMultipartUpload","handleSinglePartUpload","_b","body","fileName","progress","bytesUploaded","totalBytes","totalBytesUploaded","i","partNumber","start","end","min","chunk","slice","partResponse","round","completeResponse","JSON","stringify","completeData","uploadFiles","Array","isArray","filter","uFiles","bUrl","bUrl2","replace","AbortController","iFiles","existingFiles","File","validFiles","_c","map","f","Boolean","errorMessage","formatDateForPayload","date","dayjs","isValid","format","formatTimeForPayload","formatDateTimeForPayload","isJSONString","str","parse","e","getErrorMessage","defaultCurrencySymbol","currencyData","symbol","userData","currency_data","formatResponseDatesToDayJS","obj","item","_","isObject","mapValues","value","key","isDayjs","includes","utc","getTaxAmountDataFromMultipleTaxCodes","grossAmount","netAmount","taxCodes","detail","totalTaxAmount","totalTaxRate","taxCodeDetail","code","taxAmount","applies_to","rate","id","tax_amount","amount","getToken","timezone","moment","tz","guess","offsetMinutes","zone","utcOffset","checkForDuplicate","payload","postV1PartiesCheck","party_exists","displayPhone","contact_no","country_code","mapApiPayload","payloadMapping","values","val","isFunction","get","result","isNil","isEmpty","mapAsyncApiPayload","entries","Object","all","fromEntries","isBetweenTheDates","startDate","endDate","startOf","endOf","currentDate","isAfter","isBefore","isSame","getAccessibleModules","moduleNames","uData","findSubModules","module_access","module_name","sub_modules","sub_module_name","subModuleNamesSet","Set","flatMap","subModule","permission","from","keys","some","startsWith","pop","filterAccessibleModules","menu","accessibleMenus","reduce","filtered","isSubModuleValid","bacSubModuleName","has","filteredSubmenu","submenu","getSlicedValue","processFieldDisabling","currentFieldValue","valueConfig","fieldsToDisableSet","valueKey","String","forEach","fieldName","add","Approved","Rejected","array","itemIndex","updatedData","newArray","original","newCondition","extractConditions","trim","cond","existingConditions","filteredNew","quantity","discount_rate","discounted_items","discountAmount","Number","discount_category","taxData","taxRate","totalAmount","startDateTime","endDateTime","mode","years","diff","remainingMonths","months","remainingDays","weeks","remainingDaysWeekly","totalHours","days","floor","hours","typeOfTrcebility","trackRows","isDuplicate","errorMsg","isSerialTracking","trackingField","inputValue","add_stock_transfer","lot_number","serial_number","_d","_e","o","postV1InventoryItemsCheck","item_exists","created_at","created_user","created_by_data","first_name","last_name","fName","lName","cAt","text","formatDate","formatText","user","accessCompanies","defaultCompanyId","company_id","dcId","number_format","api","raw","redirect","blob","window","URL","createObjectURL","open","revokeObjectURL","fileUrl","a","document","createElement","target","href","download","appendChild","click","removeChild","itemId","getV1AssemblyItemsId","companyId","res","fetchApi","apiKey","filters","params","arr","search","limit","skip","filteredData","searchLower","toLowerCase","label","totalCount","pagination","postV1CurrencyInfo","currancy_id","exchange_rate","reverse_rate","attributes","select","getV1CrossHireRfqResponseItems","rfq_response_items","getV1RfqResponseItems","allCoa","coa","ic","company_ids","c","find","position","parseFloat","isNaN","num","toFixed","formatter","Intl","NumberFormat","minimumFractionDigits","maximumFractionDigits","formattedAmount","currencySymbol","defaultSymbol","formatEmptyDataToNull","keysInOrder","string","fieldsConfig","defaultOperators","textOperators","numberOperators","selectOperators","dropdownOperators","dateOperators","isFilterAllowed","field","is_aggregate","table","fieldType","operators","valueEditorType","inputType","datatype","enum","fieldArr","boolean","comparator","rule","operatorMap","null","notNull","contains","beginsWith","endsWith","doesNotContain","doesNotBeginWith","doesNotEndWith","in","notIn","processRules","rules","ruleValue","rv","combinator","operator","formatValue","concatString","uniqueStringId","Date","now","random","uniqueNumberId","getV1LocationsCountries","countries","request","pathParts","pathname","currentPath","currentModule","moduleName","combinedFilters","specificFilters","title","filterQueryString","cleanedFilterQueryString","subModuleName","subModuleMappings","queryParams","selectedIds","queryString","URLSearchParams","resource","fields","fieldNames","Map","filt","fi","field_properties","customeFilter","set","parts","dataArray","fallbackArray","labelKeys","labelFormatter","compact","v","n","path","acc","billingCycle","duration","filterFields","booleanOperators","rField","ff","operatorLable","to","no","so","dwo","dto","_f","_g","bo","ad","co","cr","currencies","cm","companies","dsa","dba","pt","sp","getV1PartiesId","p","parties","party","payment_term","party_address_data","party_contact_data","currencies_data","companies_data","salesperson","addr","default_shipping_address","default_billing_address","addresses","contacts","currencyIds","companyIds","paymentTerm","defaultShipping","defaultBilling","middle_name","company_name","trimmedName","trimmedFirstName","trimmedMiddleName","trimmedLastName","trimmedCompanyName","account_type","object","skipFields","checkValue","isPlainObject","jsonString","err","action","items","index","INVENTORY_MATERIAL_COSTING_TYPE_OPTIONS","omitDataKeys","extra","defaultOmitKeys","omitBy","activeTab","fValues","defaultValues","phoneNumber","parsePhoneNumberFromString","nationalNumber","countryCallingCode","cDefaultValueContactNo","cValueContactNo","isDirtyPhone","isDirtyCompanyName","countryCode","contactNo","duplicateCheckPayload","duplicateType","parsed","mainModule","INVENTORY_MATERIAL_COSTING_TYPE_ARR","mct","ele","_id","salesPrice","priceRules","addedQuantity","updatedRate","sortedPriceRules","orderBy","pRules","minimum_quantity","start_date","end_date","unit_price","enqueueSnackbar","variant","category","sequence","cleanCategory","cleanName","toUpperCase","materialCostingType","formValues","INVENTORY_FIELDS_TO_BE_DISABLED","isEditMode","isAddMode","alwaysDisabledFields","INVENTORY_ALWAYS_DISABLED_FIELDS","editModeDisabledFields","INVENTORY_EDIT_MODE_DISABLED_FIELDS","addModeDisabledFields","INVENTORY_ADD_MODE_DISABLED_FIELDS","conditionallyDisabledFields","materialTypeFieldNames","allFieldNames","configKey","dependentFieldName","nestedValueConfig","fieldValue","isAlwaysDisabled","isEditModeDisabled","isAddModeDisabled","isConditionallyDisabled","isDisabled","disabled","disableTableAddButton","disableDefaultActionColumn","existingAttachments","newFiles","ea","uplaodedAttachments","discountDueDateBasedOn","discountValidity","dateObj","discountEndDate","setDate","getDate","parseInt","getFullYear","getMonth","setMonth"],"mappings":"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"}