utils.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. import { useI18n } from "vue-i18n";
  2. /**
  3. * @description Corta uma string em um determinado tamanho.
  4. * @param {string} string string a ser cortada.
  5. * @param {string} size tamanho da string.
  6. * @returns {string} string cortada.
  7. */
  8. const excerpt = (string, size = 30) => {
  9. if (size == null) return string;
  10. if (string.length > size) {
  11. string = string.substring(0, size) + "...";
  12. }
  13. return string;
  14. };
  15. /**
  16. * @description Formata uma data de DD/MM/YYYY para YYYY-MM-DD
  17. * @param {string} date data.
  18. * @param {string} time tempo.
  19. * @throws {Error} Caso a data seja nula ou invalida.
  20. * @returns {string} data formatada.
  21. */
  22. const formatDateDMYtoYMD = (date, time) => {
  23. if (!date) throw new Error(useI18n().t("validation.rules.required"));
  24. const testDate =
  25. /^([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{4}$/;
  26. if (testDate.test(date) === false)
  27. throw new Error(useI18n().t("validation.rules.date"));
  28. const [day, month, year] = date.split("/");
  29. return `${year}-${month}-${day} ${time ? time : ""}`;
  30. };
  31. /**
  32. * @description Converte uma data e hora para o formato brasileiro.
  33. * @param {string} dateTimeString data e hora.
  34. * @returns {string} data e hora no formato brasileiro.
  35. * @throws {Error} Caso a data seja nula ou invalida.
  36. * @returns {string} data formatada.
  37. * @example
  38. * // convertDateTime("2023-05-23T13:07:27.000000Z");
  39. * // Output: 23/05/2023 10:07:27
  40. */
  41. const convertDateTime = (dateTimeString) => {
  42. const dateTime = new Date(dateTimeString);
  43. const options = {
  44. timeZone: "America/Sao_Paulo",
  45. day: "2-digit",
  46. month: "2-digit",
  47. year: "numeric",
  48. hour: "2-digit",
  49. minute: "2-digit",
  50. second: "2-digit",
  51. };
  52. const formattedDateTime = dateTime
  53. .toLocaleString("pt-BR", options)
  54. .replace(",", "");
  55. return formattedDateTime;
  56. };
  57. /**
  58. * @description Formata uma data de YYYY-MM-DD para DD/MM/YYYY
  59. * @param {string} dateTime data e hora.
  60. * @returns {string} data e hora no formato brasileiro.
  61. * @example
  62. * // formatDateYMDtoDMY("2023-05-23T13:07:27.000000Z");
  63. * // Output: 23/05/2023 10:07:27
  64. */
  65. const formatDateYMDtoDMY = (dateTime) => {
  66. const [datePart, timePart] = dateTime.split(" ");
  67. const [year, month, day] = datePart.split("-");
  68. const formattedDate = `${day}/${month}/${year}`;
  69. if (timePart) {
  70. const [hours, minutes, seconds] = timePart.split(":");
  71. const formattedTime = `${hours}:${minutes}:${seconds}`;
  72. return `${formattedDate} ${formattedTime}`;
  73. }
  74. return formattedDate;
  75. };
  76. /**
  77. * @description Checa a moeda selecionada.
  78. * @param {number} moeda moeda selecionada.
  79. * @returns {object} opções de moeda.
  80. */
  81. const checaMoeda = (moeda) => {
  82. let currencyOptions = {};
  83. if (moeda == 1) {
  84. currencyOptions = {
  85. locale: "pt-BR",
  86. currency: "BRL",
  87. currencyDisplay: "symbol",
  88. hideCurrencySymbolOnFocus: false,
  89. hideGroupingSeparatorOnFocus: false,
  90. hideNegligibleDecimalDigitsOnFocus: false,
  91. autoDecimalDigits: true,
  92. useGrouping: true,
  93. accountingSign: false,
  94. };
  95. } else if (moeda == 2) {
  96. currencyOptions = {
  97. currency: "PYG",
  98. locale: "es-PY",
  99. valueAsInteger: true,
  100. distractionFree: true,
  101. precision: 0,
  102. autoDecimalMode: true,
  103. valueRange: { min: 0 },
  104. allowNegative: true,
  105. };
  106. } else if (moeda == 3) {
  107. currencyOptions = {
  108. locale: "en-US",
  109. currency: "USD",
  110. currencyDisplay: "symbol",
  111. hideCurrencySymbolOnFocus: true,
  112. hideGroupingSeparatorOnFocus: true,
  113. hideNegligibleDecimalDigitsOnFocus: false,
  114. autoDecimalDigits: true,
  115. useGrouping: true,
  116. accountingSign: false,
  117. };
  118. }
  119. return currencyOptions;
  120. };
  121. /**
  122. * @description Filtra a moeda.
  123. * @param {number} value valor.
  124. * @returns {string} valor formatado.
  125. */
  126. const filterCurrency = (value) => {
  127. if (value) {
  128. value = parseFloat(value);
  129. return value.toLocaleString("pt-BR", {
  130. style: "currency",
  131. currency: "BRL",
  132. });
  133. }
  134. return value;
  135. };
  136. /**
  137. * @description Filtra a unidade de medida.
  138. * @param {number} value valor.
  139. * @returns {string} valor formatado.
  140. */
  141. const filterUnidadeMedida = (value) => {
  142. return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
  143. };
  144. /**
  145. * @description Valida se a data é válida.
  146. * @param {string} date data.
  147. * @returns {boolean} true se a data é válida, false caso contrário.
  148. */
  149. const validaData = (date) => {
  150. const regex = /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}$/;
  151. return regex.test(date);
  152. };
  153. /**
  154. * @description Valida se a hora é válida.
  155. * @param {string} time hora.
  156. * @returns {boolean} true se a hora é válida, false caso contrário.
  157. */
  158. const validaHora = (time) => {
  159. const regex = /^([0-1][0-9]|2[0-3]):[0-5][0-9]$/;
  160. return regex.test(time);
  161. };
  162. /**
  163. * @description Valida se a data e hora são válidas.
  164. * @param {string} dataHora data e hora.
  165. * @returns {boolean} true se a data e hora são válidas, false caso contrário.
  166. */
  167. const validaDataHora = (dataHora) => {
  168. const regex =
  169. /^(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[0-2])\/\d{4}\s([0-1][0-9]|2[0-3]):[0-5][0-9]$/;
  170. return regex.test(dataHora);
  171. };
  172. /**
  173. * @description Formata a quantidade.
  174. * @param {number} value valor.
  175. * @returns {string} valor formatado.
  176. */
  177. const formatQuantity = (value) => {
  178. if (value) {
  179. return value
  180. .toString()
  181. .replace(/[^0-9]/g, "")
  182. .replace(/\B(?=(\d{3})+(?!\d))/g, ".");
  183. }
  184. return value;
  185. };
  186. /**
  187. * @description Formata a moeda.
  188. * @param {number} value valor.
  189. * @returns {string} valor formatado.
  190. */
  191. const formatCurrency = (value) => {
  192. if (value != null) {
  193. value = parseFloat(value);
  194. return value.toLocaleString("pt-BR", {
  195. minimumFractionDigits: 2,
  196. style: "currency",
  197. currency: "BRL",
  198. });
  199. }
  200. return value;
  201. };
  202. // algoritmo de luhn que valida se o cartao tem numero valido (nao garante que ele existe, só garante que poderia ser um numero de cartao realmente valido)
  203. const validateCardNumberLuhn = (cardNumber) => {
  204. const digits = cardNumber.replace(/\D/g, '');
  205. if (digits.length < 13 || digits.length > 19) return false;
  206. let sum = 0;
  207. let isEven = false;
  208. for (let i = digits.length - 1; i >= 0; i--) {
  209. let digit = parseInt(digits[i], 10);
  210. if (isEven) {
  211. digit *= 2;
  212. if (digit > 9) digit -= 9;
  213. }
  214. sum += digit;
  215. isEven = !isEven;
  216. }
  217. return sum % 10 === 0;
  218. };
  219. const detectCardBrand = (cardNumber) => {
  220. const digits = (cardNumber || '').replace(/\D/g, '');
  221. if (!digits) return null;
  222. // Visa
  223. if (/^4/.test(digits)) return 'visa';
  224. // Mastercard (inclui range novo 2221–2720)
  225. if (/^(5[1-5]|2[2-7][0-9]{2})/.test(digits)) return 'mastercard';
  226. // Elo (principais BINs conhecidos)
  227. if (/^(4011|4312|4389|4514|4576|5041|5066|5067|5090|6277|6362|6363|6504|6505|6516|6550)/.test(digits)) return 'elo';
  228. // Hipercard
  229. if (/^(3841|60)/.test(digits)) return 'hipercard';
  230. // American Express
  231. if (/^3[47]/.test(digits)) return 'amex';
  232. // Diners Club
  233. if (/^(30[0-5]|36|38|39)/.test(digits)) return 'diners';
  234. // Discover
  235. if (/^(6011|65|64[4-9])/.test(digits)) return 'discover';
  236. // JCB
  237. if (/^35/.test(digits)) return 'jcb';
  238. // Aura (Banco do Brasil)
  239. if (/^50/.test(digits)) return 'aura';
  240. return null;
  241. };
  242. const validateCardExpiration = (expiration) => {
  243. if (!expiration || !/^\d{2}\/\d{4}$/.test(expiration)) return false;
  244. const [month, year] = expiration.split('/').map(Number);
  245. if (month < 1 || month > 12) return false;
  246. const now = new Date();
  247. const currentYear = now.getFullYear();
  248. const currentMonth = now.getMonth() + 1;
  249. if (year < currentYear) return false;
  250. if (year === currentYear && month < currentMonth) return false;
  251. return true;
  252. };
  253. const formatAddress = (address) => {
  254. if (!address) return '';
  255. const { address: street, number, district, city, state } = address;
  256. let parts = [];
  257. if(street && street !== null && street != 'null') parts.push(street);
  258. if(number && number !== null && number != 'null') parts.push(number);
  259. if(district && district !== null && district != 'null') parts.push(district);
  260. if(city?.name && city.name !== null && city.name != 'null') parts.push(city.name);
  261. if(state?.code && state.code !== null && state.code != 'null') parts.push(state.code);
  262. return parts.join(', ');
  263. };
  264. const calculateDailyPrices = (dailyPrice8h) => {
  265. if (!dailyPrice8h || dailyPrice8h <= 0) {
  266. return {
  267. daily_price_8h: null,
  268. daily_price_6h: null,
  269. daily_price_4h: null,
  270. daily_price_2h: null,
  271. };
  272. }
  273. return {
  274. daily_price_8h: dailyPrice8h,
  275. daily_price_6h: dailyPrice8h * 0.85,
  276. daily_price_4h: dailyPrice8h * 0.55,
  277. daily_price_2h: dailyPrice8h * 0.30,
  278. };
  279. };
  280. const chooseprice = (periodType, daily_price_8h) => {
  281. let alldaily_prices = calculateDailyPrices(daily_price_8h);
  282. switch (periodType) {
  283. case "8":
  284. return daily_price_8h
  285. case "6":
  286. return alldaily_prices.daily_price_6h
  287. case "4":
  288. return alldaily_prices.daily_price_4h
  289. case "2":
  290. return alldaily_prices.daily_price_2h
  291. default:
  292. return 0
  293. }
  294. }
  295. export {
  296. formatDateDMYtoYMD,
  297. formatDateYMDtoDMY,
  298. excerpt,
  299. convertDateTime,
  300. checaMoeda,
  301. filterCurrency,
  302. filterUnidadeMedida,
  303. validaData,
  304. validaHora,
  305. validaDataHora,
  306. formatQuantity,
  307. formatCurrency,
  308. validateCardNumberLuhn,
  309. detectCardBrand,
  310. validateCardExpiration,
  311. formatAddress,
  312. calculateDailyPrices,
  313. chooseprice
  314. };