refactor(TServicoPedido): Refatoração da tela, otimizando e separando as responsabilidades
This commit is contained in:
parent
790dbe2df3
commit
32937c9501
16 changed files with 655 additions and 672 deletions
18
README.md
18
README.md
|
|
@ -5,3 +5,21 @@ NEXT_PUBLIC_ORIUS_APP_STATE=GO
|
||||||
NEXT_PUBLIC_ORIUS_APP_API_URL=<http://localhost:8000/>
|
NEXT_PUBLIC_ORIUS_APP_API_URL=<http://localhost:8000/>
|
||||||
NEXT_PUBLIC_ORIUS_APP_API_PREFIX=api/v1/
|
NEXT_PUBLIC_ORIUS_APP_API_PREFIX=api/v1/
|
||||||
NEXT_PUBLIC_ORIUS_APP_API_CONTENT_TYPE=application/json
|
NEXT_PUBLIC_ORIUS_APP_API_CONTENT_TYPE=application/json
|
||||||
|
|
||||||
|
## Modo Debug
|
||||||
|
|
||||||
|
Abra Run → Add Configuration… → Attach to Node.js
|
||||||
|
|
||||||
|
Configure:
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "Attach Next.js (9230)",
|
||||||
|
"type": "node",
|
||||||
|
"request": "attach",
|
||||||
|
"port": 9230,
|
||||||
|
"restart": true,
|
||||||
|
"smartStep": true,
|
||||||
|
"skipFiles": ["<node_internals>/**"]
|
||||||
|
}
|
||||||
|
|
||||||
|
npm run dev:debug
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,6 @@ const nextConfig = {
|
||||||
eslint: { ignoreDuringBuilds: true },
|
eslint: { ignoreDuringBuilds: true },
|
||||||
typescript: { ignoreBuildErrors: true },
|
typescript: { ignoreBuildErrors: true },
|
||||||
|
|
||||||
// Removido o experimental.runtime (incompatível no Next 15)
|
|
||||||
// O runtime agora é definido por rota ou via middleware (Edge/Node.js),
|
|
||||||
// mas por padrão, tudo roda em Node.js quando "output: standalone" está ativo.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = nextConfig;
|
module.exports = nextConfig;
|
||||||
|
|
|
||||||
206
package-lock.json
generated
206
package-lock.json
generated
|
|
@ -63,6 +63,7 @@
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
||||||
"@typescript-eslint/parser": "^8.46.1",
|
"@typescript-eslint/parser": "^8.46.1",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^9.38.0",
|
"eslint": "^9.38.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-import-resolver-typescript": "^4.4.4",
|
"eslint-import-resolver-typescript": "^4.4.4",
|
||||||
|
|
@ -400,6 +401,13 @@
|
||||||
"tslib": "^2.4.0"
|
"tslib": "^2.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@epic-web/invariant": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@epic-web/invariant/-/invariant-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-lrTPqgvfFQtR/eY/qkIzp98OGdNJu0m5ji3q/nJI8v3SXkRKEnWiOxMmbvcSoAIzv/cGiuvRy57k4suKQSAdwA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@eslint-community/eslint-utils": {
|
"node_modules/@eslint-community/eslint-utils": {
|
||||||
"version": "4.9.0",
|
"version": "4.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
|
||||||
|
|
@ -4254,6 +4262,24 @@
|
||||||
"react": ">= 16.8.0"
|
"react": ">= 16.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/cross-env": {
|
||||||
|
"version": "10.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-env/-/cross-env-10.1.0.tgz",
|
||||||
|
"integrity": "sha512-GsYosgnACZTADcmEyJctkJIoqAhHjttw7RsFrVoJNXbsWWqaq6Ym+7kZjq6mS45O0jij6vtiReppKQEtqWy6Dw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@epic-web/invariant": "^1.0.0",
|
||||||
|
"cross-spawn": "^7.0.6"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"cross-env": "dist/bin/cross-env.js",
|
||||||
|
"cross-env-shell": "dist/bin/cross-env-shell.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/cross-spawn": {
|
"node_modules/cross-spawn": {
|
||||||
"version": "7.0.6",
|
"version": "7.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||||
|
|
@ -4273,6 +4299,7 @@
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/d3-array": {
|
"node_modules/d3-array": {
|
||||||
|
|
@ -4396,127 +4423,6 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d3-array": {
|
|
||||||
"version": "3.2.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
|
||||||
"integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"internmap": "1 - 2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-color": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-ease": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-format": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-interpolate": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-path": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-scale": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-array": "2.10.0 - 3",
|
|
||||||
"d3-format": "1 - 3",
|
|
||||||
"d3-interpolate": "1.2.0 - 3",
|
|
||||||
"d3-time": "2.1.1 - 3",
|
|
||||||
"d3-time-format": "2 - 4"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-shape": {
|
|
||||||
"version": "3.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
|
||||||
"integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-path": "^3.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-time": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-array": "2 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-time-format": {
|
|
||||||
"version": "4.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
|
|
||||||
"integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-time": "1 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-timer": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||||
|
|
@ -4612,12 +4518,6 @@
|
||||||
"integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
|
"integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/decimal.js-light": {
|
|
||||||
"version": "2.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
|
|
||||||
"integrity": "sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/deep-is": {
|
"node_modules/deep-is": {
|
||||||
"version": "0.1.4",
|
"version": "0.1.4",
|
||||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||||
|
|
@ -4690,16 +4590,6 @@
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/dom-helpers": {
|
|
||||||
"version": "5.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
|
|
||||||
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@babel/runtime": "^7.8.7",
|
|
||||||
"csstype": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dunder-proto": {
|
"node_modules/dunder-proto": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||||
|
|
@ -5615,15 +5505,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
},
|
},
|
||||||
"node_modules/fast-equals": {
|
|
||||||
"version": "5.3.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.3.2.tgz",
|
|
||||||
"integrity": "sha512-6rxyATwPCkaFIL3JLqw8qXqMpIZ942pTX/tbQFkRsDGblS8tNGtlUauA/+mt6RUfqn/4MoEr+WDkYoIQbibWuQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/fast-glob": {
|
"node_modules/fast-glob": {
|
||||||
"version": "3.3.3",
|
"version": "3.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
|
||||||
|
|
@ -6187,15 +6068,6 @@
|
||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/internmap": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
|
|
||||||
"integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/is-array-buffer": {
|
"node_modules/is-array-buffer": {
|
||||||
"version": "3.0.5",
|
"version": "3.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
|
||||||
|
|
@ -7082,12 +6954,6 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/lodash": {
|
|
||||||
"version": "4.17.21",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
|
||||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/lodash.includes": {
|
"node_modules/lodash.includes": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
|
||||||
|
|
@ -8009,21 +7875,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-smooth": {
|
|
||||||
"version": "4.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
|
|
||||||
"integrity": "sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"fast-equals": "^5.0.1",
|
|
||||||
"prop-types": "^15.8.1",
|
|
||||||
"react-transition-group": "^4.4.5"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
|
|
||||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-style-singleton": {
|
"node_modules/react-style-singleton": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz",
|
||||||
|
|
@ -9000,9 +8851,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "5.9.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
|
||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
|
||||||
"version": "5.9.3",
|
"version": "5.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
|
||||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
"version": "25.9.1",
|
"version": "25.9.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbopack",
|
"dev": "next dev",
|
||||||
|
"dev:debug": "cross-env NEXT_USE_TURBOPACK=0 NODE_OPTIONS=\"--inspect=9230\" next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
|
|
@ -65,6 +66,7 @@
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
"@typescript-eslint/eslint-plugin": "^8.46.1",
|
||||||
"@typescript-eslint/parser": "^8.46.1",
|
"@typescript-eslint/parser": "^8.46.1",
|
||||||
|
"cross-env": "^10.1.0",
|
||||||
"eslint": "^9.38.0",
|
"eslint": "^9.38.0",
|
||||||
"eslint-config-prettier": "^10.1.8",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-import-resolver-typescript": "^4.4.4",
|
"eslint-import-resolver-typescript": "^4.4.4",
|
||||||
|
|
|
||||||
|
|
@ -2,48 +2,15 @@
|
||||||
|
|
||||||
import { GCalculoServico } from '@/packages/administrativo/data/GCalculo/GCalculoServicoData';
|
import { GCalculoServico } from '@/packages/administrativo/data/GCalculo/GCalculoServicoData';
|
||||||
import GCalculoServicoInterface from '@/packages/administrativo/interfaces/GCalculo/GCalculoServicoInterface';
|
import GCalculoServicoInterface from '@/packages/administrativo/interfaces/GCalculo/GCalculoServicoInterface';
|
||||||
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
|
||||||
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
import { withClientErrorHandler } from '@/shared/actions/withClientErrorHandler/withClientErrorHandler';
|
||||||
|
|
||||||
async function executeGCalculoServicoService(
|
async function executeGCalculoServicoService(
|
||||||
payload: GCalculoServicoInterface,
|
payload: GCalculoServicoInterface,
|
||||||
data: TServicoItemPedidoAddInterface,
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
const response = await GCalculoServico(payload);
|
const response = await GCalculoServico(payload);
|
||||||
|
|
||||||
if (response.status == 404 || response.status == 400) {
|
return response;
|
||||||
return {
|
|
||||||
status: response.status,
|
|
||||||
message: 'Erro ao processar dados',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const item = {
|
|
||||||
emolumento_id: response.data.emolumento_id,
|
|
||||||
emolumento_item_id: response.data.emolumento_item_id ?? null,
|
|
||||||
servico_tipo_id: data.servico_tipo.servico_tipo_id ?? 0,
|
|
||||||
tipo_item: data.servico_tipo.tipo_item ?? '',
|
|
||||||
descricao: data.servico_tipo.descricao ?? '',
|
|
||||||
tabela: data.servico_tipo?.descricao ?? '',
|
|
||||||
situacao: 'F',
|
|
||||||
qtd: 1,
|
|
||||||
valor: response.data.valor_total ?? 0,
|
|
||||||
emolumento: response.data.valor_emolumento ?? 0,
|
|
||||||
fundesp: response.data.valor_fundos ?? 0,
|
|
||||||
taxa_judiciaria: response.data.taxa_judiciaria ?? 0,
|
|
||||||
valor_iss: response.data.valor_iss ?? 0,
|
|
||||||
pessoa_id: data?.pessoa?.pessoa_id ?? null,
|
|
||||||
subview: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
if (data?.pessoa?.pessoa_id) {
|
|
||||||
item.subview = {
|
|
||||||
servico: data.servico_tipo,
|
|
||||||
pessoa: data.pessoa,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const GCalculoServicoService = withClientErrorHandler(executeGCalculoServicoService);
|
export const GCalculoServicoService = withClientErrorHandler(executeGCalculoServicoService);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import HandleSelectTServicoTipoInterface from './HandleSelectTServicoTipoInterface';
|
import HandleSelectTServicoTipoInterface from './HandleSelectTServicoTipoInterface';
|
||||||
|
|
||||||
export default function HandleSelectTServicoTipoAction({
|
export default function handleServicoTipoPessoaSelection({
|
||||||
servico,
|
servico,
|
||||||
emolumento,
|
emolumento,
|
||||||
onOpenPessoaForm,
|
onOpenPessoaForm,
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
|
||||||
|
export default function TServicoPedidoItemLocalPrepare(data, response) {
|
||||||
|
|
||||||
|
const item = {
|
||||||
|
emolumento_id: response.data.emolumento_id,
|
||||||
|
emolumento_item_id: response.data.emolumento_item_id ?? null,
|
||||||
|
servico_tipo_id: data.servico_tipo.servico_tipo_id ?? 0,
|
||||||
|
tipo_item: data.servico_tipo.tipo_item ?? '',
|
||||||
|
descricao: data.servico_tipo.descricao ?? '',
|
||||||
|
tabela: data.servico_tipo?.descricao ?? '',
|
||||||
|
situacao: 'F',
|
||||||
|
qtd: 1,
|
||||||
|
valor: response.data.valor_total ?? 0,
|
||||||
|
emolumento: response.data.valor_emolumento ?? 0,
|
||||||
|
fundesp: response.data.valor_fundos ?? 0,
|
||||||
|
taxa_judiciaria: response.data.taxa_judiciaria ?? 0,
|
||||||
|
valor_iss: response.data.valor_iss ?? 0,
|
||||||
|
pessoa_id: data?.pessoa?.pessoa_id ?? null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data?.pessoa?.pessoa_id) {
|
||||||
|
item.subview = {
|
||||||
|
servico: data.servico_tipo,
|
||||||
|
pessoa: data.pessoa,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return item
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
||||||
|
|
||||||
export default function TServicoPedidoItemPreparePayload(data: TServicoItemPedidoAddInterface) {
|
export default function TServicoPedidoItemPreparePayload(data: TServicoItemPedidoAddInterface) {
|
||||||
|
|
||||||
data.qtd = 1;
|
data.qtd = 1;
|
||||||
data.valor_documento = 0;
|
data.valor_documento = 0;
|
||||||
|
|
||||||
|
|
@ -26,4 +27,4 @@ export default function TServicoPedidoItemPreparePayload(data: TServicoItemPedid
|
||||||
quantidade: data.qtd,
|
quantidade: data.qtd,
|
||||||
emolumento_id: data.emolumento.emolumento_id,
|
emolumento_id: data.emolumento.emolumento_id,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
import { Minus, Plus } from 'lucide-react';
|
import { Minus, Plus } from 'lucide-react';
|
||||||
import React, { memo } from 'react';
|
import React, { memo } from 'react';
|
||||||
|
import { useWatch } from 'react-hook-form';
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
|
|
@ -17,12 +18,13 @@ import TPessoaTableFormSubview from '@/packages/administrativo/components/TPesso
|
||||||
import TServicoItemPedidoFormTableInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoFormTableInterface';
|
import TServicoItemPedidoFormTableInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoFormTableInterface';
|
||||||
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
import GetCapitalize from '@/shared/actions/text/GetCapitalize';
|
||||||
|
|
||||||
function TServicoItemPedidoFormTableComponent({
|
function TServicoItemPedidoFormTableComponent({ form, params, handleChangeQtd }: TServicoItemPedidoFormTableInterface) {
|
||||||
data,
|
|
||||||
form,
|
const { control } = form;
|
||||||
params,
|
|
||||||
}: TServicoItemPedidoFormTableInterface) {
|
// Sempre “ouve” o campo itens do formulário
|
||||||
console.log(data);
|
const data = useWatch({ control, name: 'itens' }) || [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded-md border">
|
<div className="rounded-md border">
|
||||||
<Table>
|
<Table>
|
||||||
|
|
@ -37,66 +39,71 @@ function TServicoItemPedidoFormTableComponent({
|
||||||
<TableHead className="text-center">Qtd.</TableHead>
|
<TableHead className="text-center">Qtd.</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
|
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{data?.length ? (
|
{data.length ? (
|
||||||
data.map((item, index) => {
|
data.map((item, index) => (
|
||||||
return (
|
<React.Fragment key={`fragment-${index}`}>
|
||||||
<React.Fragment key={`fragment-${index}`}>
|
<TableRow className="cursor-pointer hover:bg-gray-50">
|
||||||
{/* Linha principal */}
|
<TableCell>
|
||||||
<TableRow key={`row-${index}`} className="cursor-pointer hover:bg-gray-50">
|
<div className="flex items-center gap-3">
|
||||||
<TableCell>
|
<div>
|
||||||
<div className="flex items-center gap-3">
|
<div className="font-semibold text-gray-900 capitalize">
|
||||||
<div>
|
{GetCapitalize(item.descricao)}
|
||||||
<div className="font-semibold text-gray-900 capitalize">
|
|
||||||
{GetCapitalize(item.descricao)}
|
|
||||||
</div>
|
|
||||||
<div className="text-sm text-gray-500">{GetCapitalize(item.tabela)}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div className="text-sm text-gray-500">{GetCapitalize(item.tabela)}</div>
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</div>
|
||||||
<TableCell>R$ {item.emolumento ?? '---'}</TableCell>
|
</TableCell>
|
||||||
<TableCell>R$ {item.taxa_judiciaria ?? '---'}</TableCell>
|
<TableCell>R$ {item.emolumento ?? '---'}</TableCell>
|
||||||
<TableCell>R$ {item.fundesp ?? '---'}</TableCell>
|
<TableCell>R$ {item.taxa_judiciaria ?? '---'}</TableCell>
|
||||||
<TableCell>R$ {item.valor_iss ?? '---'}</TableCell>
|
<TableCell>R$ {item.fundesp ?? '---'}</TableCell>
|
||||||
<TableCell>R$ {item.valor ?? '---'}</TableCell>
|
<TableCell>R$ {item.valor_iss ?? '---'}</TableCell>
|
||||||
<TableCell>
|
<TableCell>R$ {item.valor ?? '---'}</TableCell>
|
||||||
<div className="flex items-center justify-center gap-1">
|
<TableCell>
|
||||||
<Button
|
<div className="flex items-center justify-center gap-1">
|
||||||
type="button"
|
<Button
|
||||||
size="icon"
|
type="button"
|
||||||
variant="outline"
|
size="icon"
|
||||||
className="h-8 w-8 rounded-lg border bg-white"
|
variant="outline"
|
||||||
>
|
className="h-8 w-8 rounded-lg border bg-white"
|
||||||
<Minus className="h-4 w-4" />
|
onClick={() => handleChangeQtd(index, -1)}
|
||||||
</Button>
|
>
|
||||||
<Input type="number" className="h-8 w-12 px-1 text-center" />
|
<Minus className="h-4 w-4" />
|
||||||
<Button
|
</Button>
|
||||||
type="button"
|
<Input
|
||||||
size="icon"
|
type="number"
|
||||||
variant="outline"
|
className="h-8 w-12 px-1 text-center"
|
||||||
className="h-8 w-8 rounded-lg border bg-white"
|
value={item.qtd ?? 1}
|
||||||
>
|
readOnly
|
||||||
<Plus className="h-4 w-4" />
|
/>
|
||||||
</Button>
|
<Button
|
||||||
</div>
|
type="button"
|
||||||
|
size="icon"
|
||||||
|
variant="outline"
|
||||||
|
className="h-8 w-8 rounded-lg border bg-white"
|
||||||
|
onClick={() => handleChangeQtd(index, 1)}
|
||||||
|
>
|
||||||
|
<Plus className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</TableCell>
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
{item.subview && (
|
||||||
|
<TableRow className="bg-gray-50">
|
||||||
|
<TableCell colSpan={7} className="p-4">
|
||||||
|
<TPessoaTableFormSubview
|
||||||
|
item_index={Number(item.index)}
|
||||||
|
data={item.subview}
|
||||||
|
params={params}
|
||||||
|
form={form}
|
||||||
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
{/* SubView */}
|
)}
|
||||||
{item.subview && (
|
</React.Fragment>
|
||||||
<TableRow className="bg-gray-50">
|
))
|
||||||
<TableCell colSpan={7} className="p-4">
|
|
||||||
<TPessoaTableFormSubview
|
|
||||||
item_index={Number(item.index)}
|
|
||||||
data={item.subview}
|
|
||||||
params={params}
|
|
||||||
form={form}
|
|
||||||
/>
|
|
||||||
</TableCell>
|
|
||||||
</TableRow>
|
|
||||||
)}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
) : (
|
) : (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={7} className="py-4 text-center">
|
<TableCell colSpan={7} className="py-4 text-center">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { CreditCard, Package, UserSquare2 } from 'lucide-react';
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { CreditCardIcon, PackageIcon, UserSquare2Icon } from 'lucide-react';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
|
|
@ -21,295 +21,23 @@ import GEmolumentoServicoSelect from '@/packages/administrativo/components/GEmol
|
||||||
import GUsuarioSelect from '@/packages/administrativo/components/GUsuario/GUsuarioSelect';
|
import GUsuarioSelect from '@/packages/administrativo/components/GUsuario/GUsuarioSelect';
|
||||||
import TPessoaTableFormDialog from '@/packages/administrativo/components/TPessoa/TPessoaTableFormDialog';
|
import TPessoaTableFormDialog from '@/packages/administrativo/components/TPessoa/TPessoaTableFormDialog';
|
||||||
import TServicoTipoSelect from '@/packages/administrativo/components/TServicoTipo/TServicoTipoSelect';
|
import TServicoTipoSelect from '@/packages/administrativo/components/TServicoTipo/TServicoTipoSelect';
|
||||||
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaInterface';
|
|
||||||
import HandleSelectTServicoTipoAction from '@/packages/servicos/actions/TServicoPedido/HandleSelectTServicoTipoAction';
|
|
||||||
import { TServicoItemPedidoFormTable } from '@/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoFormTable';
|
import { TServicoItemPedidoFormTable } from '@/packages/servicos/components/TServicoItemPedido/TServicoItemPedidoFormTable';
|
||||||
import { useTServicoItemPedidoCalculoHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCalculoHook';
|
import useTServicoPedidoFormControllerHook from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoFormControllerHook';
|
||||||
import { useTServicoItemPedidoIndexHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoIndexHook';
|
|
||||||
import { useTServicoItemPedidoLocalAddHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoLocalAddHook';
|
|
||||||
import { useTServicoPedidoFormHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoFormHook';
|
|
||||||
import { useTServicoPedidoLoadParamsHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoLoadParamsHook';
|
|
||||||
import { useTServicoPedidoSaveHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoSaveHook';
|
|
||||||
import { useTServicoPedidoShowHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoShowHook';
|
|
||||||
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
|
||||||
import { TServicoPedidoFormInterface } from '@/packages/servicos/interfaces/TServicoPedido/TServicoPedidoFormInterface';
|
import { TServicoPedidoFormInterface } from '@/packages/servicos/interfaces/TServicoPedido/TServicoPedidoFormInterface';
|
||||||
import TServicoPedidoInterface from '@/packages/servicos/interfaces/TServicoPedido/TServicoPedidoInterface';
|
|
||||||
import { TServicoPedidoFormValues } from '@/packages/servicos/schemas/TServicoPedido/TServicoPedidoFormSchema';
|
|
||||||
import { FormatCPFCNPJForm } from '@/shared/actions/CPF/FormatCPFCNPJForm';
|
import { FormatCPFCNPJForm } from '@/shared/actions/CPF/FormatCPFCNPJForm';
|
||||||
import { UnmaskCPFCNPJForm } from '@/shared/actions/CPF/UnmaskCPFCNPJForm';
|
import { UnmaskCPFCNPJForm } from '@/shared/actions/CPF/UnmaskCPFCNPJForm';
|
||||||
import { parseNumberInput } from '@/shared/actions/form/parseNumberInput';
|
|
||||||
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
import ConfirmDialog from '@/shared/components/confirmDialog/ConfirmDialog';
|
||||||
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
import LoadingButton from '@/shared/components/loadingButton/LoadingButton';
|
||||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
|
||||||
import {
|
import {
|
||||||
StepNavigator,
|
StepNavigator,
|
||||||
StepNavigatorRef,
|
StepSection
|
||||||
StepSection,
|
|
||||||
} from '@/shared/components/step/stepNavigator';
|
} from '@/shared/components/step/stepNavigator';
|
||||||
import TipoPagamentoSelect from '@/shared/components/tipoPagamento/TipoPagamentoSelect';
|
import TipoPagamentoSelect from '@/shared/components/tipoPagamento/TipoPagamentoSelect';
|
||||||
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
|
|
||||||
|
|
||||||
export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedidoFormInterface) {
|
export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedidoFormInterface) {
|
||||||
const router = useRouter();
|
|
||||||
const form = useTServicoPedidoFormHook({});
|
|
||||||
const { setValue, reset, watch } = form;
|
|
||||||
|
|
||||||
const [isSaving, setIsSaving] = useState(false);
|
const tServicoPedidoController = useTServicoPedidoFormControllerHook(servico_pedido_id)
|
||||||
const [isAdding, setIsAdding] = useState(false);
|
const { form } = tServicoPedidoController
|
||||||
const [isPessoaFormOpen, setIsPessoaFormOpen] = useState(false);
|
|
||||||
const [isSaveConfirmOpen, setIsSaveConfirmOpen] = useState(false);
|
|
||||||
const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false);
|
|
||||||
const [selectedPessoaTipo, setSelectedPessoaTipo] = useState('');
|
|
||||||
const [shouldKeepFormOpen, setShouldKeepFormOpen] = useState(false);
|
|
||||||
|
|
||||||
const ref = useRef<StepNavigatorRef>(null);
|
|
||||||
|
|
||||||
// Controles de formulário
|
|
||||||
const handleClosePessoaForm = useCallback(() => setIsPessoaFormOpen(false), []);
|
|
||||||
const handleOpenSaveConfirm = useCallback(() => setIsSaveConfirmOpen(true), []);
|
|
||||||
const handleCloseSaveConfirm = useCallback(() => setIsSaveConfirmOpen(false), []);
|
|
||||||
|
|
||||||
// Hooks
|
|
||||||
// const playSuccess = useSoundHook("/sounds/success.mp3");
|
|
||||||
const { setResponse } = useResponse();
|
|
||||||
const { saveTServicoPedido } = useTServicoPedidoSaveHook();
|
|
||||||
const { showTServicoPedido } = useTServicoPedidoShowHook();
|
|
||||||
const { TServicoItemPedidoLocal, localAddTServicoItemPedido, setLocalTServicoItemPedido } =
|
|
||||||
useTServicoItemPedidoLocalAddHook(setValue);
|
|
||||||
const { addTServicoItemPedido } = useTServicoItemPedidoCalculoHook(setValue);
|
|
||||||
const { indexTServicoItemPedido } = useTServicoItemPedidoIndexHook();
|
|
||||||
const { TServicoPedidoParams, loadParamsTServicoPedido } = useTServicoPedidoLoadParamsHook();
|
|
||||||
|
|
||||||
// Acompanha as alterações, nos campos definidos
|
|
||||||
const selectedServicoTipo = watch('servico_tipo');
|
|
||||||
const selectedEmolumento = watch('emolumento');
|
|
||||||
|
|
||||||
const handleFormError = useCallback((errors: any) => {
|
|
||||||
console.group('Erros de validação do formulário');
|
|
||||||
console.log('Campos com erro:', errors);
|
|
||||||
console.groupEnd();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Envia a requisição para a API
|
|
||||||
const handleSavePedido = useCallback(
|
|
||||||
async (data: TServicoPedidoFormValues) => {
|
|
||||||
// Ativa o botão de loading
|
|
||||||
setIsSaving(true);
|
|
||||||
|
|
||||||
// Converte o tipo do formulário (Zod) para o tipo da API (Interface)
|
|
||||||
const payload: TServicoPedidoInterface = {
|
|
||||||
...data,
|
|
||||||
situacao: data.situacao as unknown as SituacoesEnum,
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await saveTServicoPedido(payload);
|
|
||||||
|
|
||||||
setIsSaving(false);
|
|
||||||
|
|
||||||
// Desativa o botão de loading
|
|
||||||
setIsSaving(false);
|
|
||||||
|
|
||||||
// Verifica se devo redirecionar a pagina
|
|
||||||
if (response?.servico_pedido_id > 0) {
|
|
||||||
// Toca o som do sistema
|
|
||||||
// playSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Verifica se devo redirecionar a pagina
|
|
||||||
if (response?.servico_pedido_id > 0 && !shouldKeepFormOpen) {
|
|
||||||
router.replace(`/servicos/balcao/detalhes/${response.servico_pedido_id}`);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[saveTServicoPedido, shouldKeepFormOpen],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Modal de confirmação de serviço
|
|
||||||
const handleSubmitWithConfirmation = useCallback(() => {
|
|
||||||
// Envia o formulário
|
|
||||||
form.handleSubmit(handleSavePedido, handleFormError)();
|
|
||||||
}, [form, handleSavePedido, handleFormError]);
|
|
||||||
|
|
||||||
// Busca os itens do Pedido
|
|
||||||
const fetchPedidoItens = useCallback(
|
|
||||||
async (id: number) => {
|
|
||||||
const pedidoItens = {
|
|
||||||
servico_pedido_id: id,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Busca os itens do pedido
|
|
||||||
const response = await indexTServicoItemPedido(pedidoItens);
|
|
||||||
|
|
||||||
// Verifica se os dados foram localizados
|
|
||||||
if (response?.data?.length) {
|
|
||||||
// Atualiza os dados dos itens locais
|
|
||||||
setLocalTServicoItemPedido(response.data);
|
|
||||||
|
|
||||||
// Atualiza os itens do formulário
|
|
||||||
setValue('itens', response.data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[indexTServicoItemPedido, setValue, setLocalTServicoItemPedido],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Busca o pedido Principal
|
|
||||||
const fetchPedido = useCallback(async () => {
|
|
||||||
// Busca o pedido principal
|
|
||||||
const response = await showTServicoPedido({ servico_pedido_id });
|
|
||||||
|
|
||||||
// Verifica se o pedido foi localizado
|
|
||||||
if (response?.servico_pedido_id) {
|
|
||||||
// Atualiza os dados do formulário
|
|
||||||
reset(response);
|
|
||||||
|
|
||||||
// Carrega os itens do pedido
|
|
||||||
fetchPedidoItens(response.servico_pedido_id);
|
|
||||||
}
|
|
||||||
}, [servico_pedido_id, showTServicoPedido, reset, fetchPedidoItens]);
|
|
||||||
|
|
||||||
const handleAddItemWithPessoa = useCallback(
|
|
||||||
async (selectedTPessoa: TPessoaInterface) => {
|
|
||||||
// Habilita o loading
|
|
||||||
setIsAdding(true);
|
|
||||||
|
|
||||||
// Constroi um novo item
|
|
||||||
const newItem = await addTServicoItemPedido({
|
|
||||||
servico_tipo: selectedServicoTipo,
|
|
||||||
emolumento: selectedEmolumento,
|
|
||||||
pessoa: selectedTPessoa,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verifica se existe um novo item
|
|
||||||
if (!newItem) return;
|
|
||||||
|
|
||||||
// Obtem o indice atual
|
|
||||||
const index = TServicoItemPedidoLocal.length;
|
|
||||||
|
|
||||||
// Define a posição do item
|
|
||||||
newItem.index = index;
|
|
||||||
|
|
||||||
// Atualiza o estado
|
|
||||||
localAddTServicoItemPedido(newItem);
|
|
||||||
|
|
||||||
// Atualiza os itens do formulário
|
|
||||||
form.setValue(`itens.${index}`, newItem);
|
|
||||||
|
|
||||||
// Desabilita o loading
|
|
||||||
setIsAdding(false);
|
|
||||||
},
|
|
||||||
[
|
|
||||||
addTServicoItemPedido,
|
|
||||||
selectedServicoTipo,
|
|
||||||
selectedEmolumento,
|
|
||||||
TServicoItemPedidoLocal.length,
|
|
||||||
localAddTServicoItemPedido,
|
|
||||||
form,
|
|
||||||
],
|
|
||||||
);
|
|
||||||
|
|
||||||
// Controla o formulário de cancelamento de pedido
|
|
||||||
const handleOpenCancelDialog = useCallback(async () => {
|
|
||||||
// Fecha a confirmação
|
|
||||||
setIsCancelDialogOpen(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Controle de redirecionamento
|
|
||||||
const handleConfirmCancel = useCallback(async () => {
|
|
||||||
// Redireciona o usuário
|
|
||||||
router.replace(`/servicos/balcao/`);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Controle do formulário de cancelamento do Pedido
|
|
||||||
const handleCloseCancelDialog = useCallback(async () => {
|
|
||||||
// Fecha o formulário
|
|
||||||
setIsCancelDialogOpen(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Controle de itens
|
|
||||||
const handleAddItemBasic = useCallback(async () => {
|
|
||||||
setIsAdding(true);
|
|
||||||
|
|
||||||
// Prepara e valida os dados de item do pedido
|
|
||||||
const payload: TServicoItemPedidoAddInterface = {
|
|
||||||
servico_tipo: selectedServicoTipo,
|
|
||||||
emolumento: selectedEmolumento,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Verifica se os dados foram criados corretamente
|
|
||||||
if (!payload) return;
|
|
||||||
|
|
||||||
// Obtem o resultado da adição do item
|
|
||||||
const newItem = await addTServicoItemPedido(payload);
|
|
||||||
|
|
||||||
// Se tiver um novo item, adiciona o mesmo na tela
|
|
||||||
if (newItem) localAddTServicoItemPedido(newItem);
|
|
||||||
|
|
||||||
setIsAdding(false);
|
|
||||||
}, [addTServicoItemPedido, selectedServicoTipo, selectedEmolumento, localAddTServicoItemPedido]);
|
|
||||||
|
|
||||||
// Habilita o formulário de pessoas
|
|
||||||
const handleOpenPessoaForm = useCallback((tipoPessoa: string) => {
|
|
||||||
setSelectedPessoaTipo(tipoPessoa);
|
|
||||||
setIsPessoaFormOpen(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Adiciona o item a tabela e verifica se deve ou não montar a subview da linha da tabela
|
|
||||||
const handleSelectServicoTipo = useCallback(() => {
|
|
||||||
const response = HandleSelectTServicoTipoAction({
|
|
||||||
servico: selectedServicoTipo,
|
|
||||||
emolumento: selectedEmolumento,
|
|
||||||
onOpenPessoaForm: handleOpenPessoaForm,
|
|
||||||
onAddItem: handleAddItemBasic,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Verifica se existem erros
|
|
||||||
if (response?.status) {
|
|
||||||
setResponse(response);
|
|
||||||
}
|
|
||||||
}, [selectedServicoTipo, selectedEmolumento, handleOpenPessoaForm, handleAddItemBasic]);
|
|
||||||
|
|
||||||
// Cálculo automático dos totais
|
|
||||||
const calcularTotais = useCallback(() => {
|
|
||||||
if (!TServicoItemPedidoLocal || !TServicoItemPedidoLocal.length) {
|
|
||||||
setValue('valor_pedido', 0);
|
|
||||||
setValue('valor_pago', 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const total = TServicoItemPedidoLocal.reduce((acc, item) => {
|
|
||||||
const valor = Number(item.valor ?? 0);
|
|
||||||
return acc + valor;
|
|
||||||
}, 0);
|
|
||||||
|
|
||||||
setValue('valor_pedido', total, { shouldDirty: true });
|
|
||||||
|
|
||||||
// opcional: manter valor pago igual ao pedido
|
|
||||||
const valorPagoAtual = watch('valor_pago');
|
|
||||||
if (!valorPagoAtual || valorPagoAtual === 0) {
|
|
||||||
setValue('valor_pago', total, { shouldDirty: true });
|
|
||||||
}
|
|
||||||
}, [TServicoItemPedidoLocal, setValue, watch]);
|
|
||||||
|
|
||||||
// Dispara a busca do pedido
|
|
||||||
useEffect(() => {
|
|
||||||
// Se existir pedido_id, busca o pedido
|
|
||||||
if (servico_pedido_id) fetchPedido();
|
|
||||||
}, [servico_pedido_id, fetchPedido]);
|
|
||||||
|
|
||||||
// Dispara a busca de itens
|
|
||||||
useEffect(() => {
|
|
||||||
// Dispara a busca dos itens
|
|
||||||
setValue('itens', TServicoItemPedidoLocal, { shouldDirty: true });
|
|
||||||
}, [TServicoItemPedidoLocal, setValue]);
|
|
||||||
|
|
||||||
// Dispara a busca de parâmetros
|
|
||||||
useEffect(() => {
|
|
||||||
loadParamsTServicoPedido();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
// Monitora mudanças na lista de itens
|
|
||||||
useEffect(() => {
|
|
||||||
calcularTotais();
|
|
||||||
}, [TServicoItemPedidoLocal, calcularTotais]);
|
|
||||||
|
|
||||||
// Memoriza os dados para não renderizar novamente
|
// Memoriza os dados para não renderizar novamente
|
||||||
const sections: StepSection[] = useMemo(
|
const sections: StepSection[] = useMemo(
|
||||||
|
|
@ -317,21 +45,21 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
{
|
{
|
||||||
key: 'pedido',
|
key: 'pedido',
|
||||||
id: 'selectPedido',
|
id: 'selectPedido',
|
||||||
icon: <Package className="h-4 w-4" />,
|
icon: <PackageIcon className="h-4 w-4" />,
|
||||||
title: 'Pedido',
|
title: 'Pedido',
|
||||||
description: 'Dados gerais do pedido.',
|
description: 'Dados gerais do pedido.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'servicoPedidoItem',
|
key: 'servicoPedidoItem',
|
||||||
id: 'selectServicoPedidoItem',
|
id: 'selectServicoPedidoItem',
|
||||||
icon: <UserSquare2 className="h-4 w-4" />,
|
icon: <UserSquare2Icon className="h-4 w-4" />,
|
||||||
title: 'Itens',
|
title: 'Itens',
|
||||||
description: 'Itens/serviços do pedido.',
|
description: 'Itens/serviços do pedido.',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: 'payment',
|
key: 'payment',
|
||||||
id: 'selectPayment',
|
id: 'selectPayment',
|
||||||
icon: <CreditCard className="h-4 w-4" />,
|
icon: <CreditCardIcon className="h-4 w-4" />,
|
||||||
title: 'Pagamento',
|
title: 'Pagamento',
|
||||||
description: 'Forma e dados de pagamento.',
|
description: 'Forma e dados de pagamento.',
|
||||||
},
|
},
|
||||||
|
|
@ -496,15 +224,16 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
text={`+ Adicionar`}
|
text={`+ Adicionar`}
|
||||||
textLoading="Adicionando..."
|
textLoading="Adicionando..."
|
||||||
onClick={handleSelectServicoTipo}
|
onClick={tServicoPedidoController.handleSelectServicoTipo}
|
||||||
loading={isAdding}
|
loading={tServicoPedidoController.isAdding}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-12">
|
<div className="col-span-12">
|
||||||
<TServicoItemPedidoFormTable
|
<TServicoItemPedidoFormTable
|
||||||
form={form}
|
form={form}
|
||||||
params={TServicoPedidoParams}
|
params={tServicoPedidoController.TServicoPedidoParams}
|
||||||
data={TServicoItemPedidoLocal}
|
data={tServicoPedidoController.TServicoItemPedidoLocal}
|
||||||
|
handleChangeQtd={tServicoPedidoController.handleChangeQtd}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -563,20 +292,23 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
<FormField
|
<FormField
|
||||||
control={form.control}
|
control={form.control}
|
||||||
name="valor_pedido"
|
name="valor_pedido"
|
||||||
render={({ field }) => (
|
render={({ field }) => {
|
||||||
<FormItem>
|
const valorPedido = form.watch('valor_pedido');
|
||||||
<FormLabel>Valor do Pedido</FormLabel>
|
return (
|
||||||
<FormControl>
|
<FormItem>
|
||||||
<Input
|
<FormLabel>Valor do Pedido</FormLabel>
|
||||||
{...field}
|
<FormControl>
|
||||||
type="number"
|
<Input
|
||||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
{...field}
|
||||||
readOnly={true}
|
type="number"
|
||||||
/>
|
value={valorPedido ?? 0}
|
||||||
</FormControl>
|
readOnly
|
||||||
<FormMessage />
|
/>
|
||||||
</FormItem>
|
</FormControl>
|
||||||
)}
|
<FormMessage />
|
||||||
|
</FormItem>
|
||||||
|
);
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-span-12 md:col-span-4">
|
<div className="col-span-12 md:col-span-4">
|
||||||
|
|
@ -590,7 +322,7 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
type="number"
|
type="number"
|
||||||
onChange={(e) => field.onChange(parseNumberInput(e))}
|
onChange={(e) => field.onChange(Number(e.target.value))}
|
||||||
/>
|
/>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
<FormMessage />
|
<FormMessage />
|
||||||
|
|
@ -623,7 +355,7 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
<Card className="card-border">
|
<Card className="card-border">
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<StepNavigator
|
<StepNavigator
|
||||||
ref={ref}
|
ref={tServicoPedidoController.ref}
|
||||||
sections={sections}
|
sections={sections}
|
||||||
defaultActive="pedido"
|
defaultActive="pedido"
|
||||||
scrollOffset={16}
|
scrollOffset={16}
|
||||||
|
|
@ -639,9 +371,9 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<Switch
|
<Switch
|
||||||
id="permanecer_formulario"
|
id="permanecer_formulario"
|
||||||
checked={shouldKeepFormOpen}
|
checked={tServicoPedidoController.shouldKeepFormOpen}
|
||||||
onCheckedChange={(checked) => {
|
onCheckedChange={(checked) => {
|
||||||
setShouldKeepFormOpen(checked);
|
tServicoPedidoController.setShouldKeepFormOpen(checked);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Label htmlFor="permanecer_formulario">Permanecer no formulário</Label>
|
<Label htmlFor="permanecer_formulario">Permanecer no formulário</Label>
|
||||||
|
|
@ -650,15 +382,15 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
className="w-full"
|
className="w-full"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleOpenCancelDialog}
|
onClick={tServicoPedidoController.handleOpenCancelDialog}
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
</Button>
|
</Button>
|
||||||
<LoadingButton
|
<LoadingButton
|
||||||
text="Salvar"
|
text="Salvar"
|
||||||
textLoading="Salvando..."
|
textLoading="Salvando..."
|
||||||
onClick={handleOpenSaveConfirm}
|
onClick={tServicoPedidoController.handleOpenSaveConfirm}
|
||||||
loading={isSaving}
|
loading={tServicoPedidoController.isSaving}
|
||||||
/>
|
/>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -668,41 +400,41 @@ export default function TServicoPedidoForm({ servico_pedido_id }: TServicoPedido
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
{/* Cofirmação de envio de dados */}
|
{/* Cofirmação de envio de dados */}
|
||||||
{isSaveConfirmOpen && (
|
{tServicoPedidoController.isSaveConfirmOpen && (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
isOpen={isSaveConfirmOpen}
|
isOpen={tServicoPedidoController.isSaveConfirmOpen}
|
||||||
title="Confirmar pedido"
|
title="Confirmar pedido"
|
||||||
description="Atenção"
|
description="Atenção"
|
||||||
message="Deseja confirmar o pedido?"
|
message="Deseja confirmar o pedido?"
|
||||||
confirmText="Sim, confirmar"
|
confirmText="Sim, confirmar"
|
||||||
cancelText="Cancelar"
|
cancelText="Cancelar"
|
||||||
onConfirm={handleSubmitWithConfirmation}
|
onConfirm={tServicoPedidoController.handleSubmitWithConfirmation}
|
||||||
onCancel={handleCloseSaveConfirm}
|
onCancel={tServicoPedidoController.handleCloseSaveConfirm}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Confirma o cancelamento do pedido */}
|
{/* Confirma o cancelamento do pedido */}
|
||||||
{isCancelDialogOpen && (
|
{tServicoPedidoController.isCancelDialogOpen && (
|
||||||
<ConfirmDialog
|
<ConfirmDialog
|
||||||
isOpen={isCancelDialogOpen}
|
isOpen={tServicoPedidoController.isCancelDialogOpen}
|
||||||
title="Cancelamento de pedido"
|
title="Cancelamento de pedido"
|
||||||
description="Atenção"
|
description="Atenção"
|
||||||
message="Deseja cancelar o pedido? Os dados não serão salvos!"
|
message="Deseja cancelar o pedido? Os dados não serão salvos!"
|
||||||
confirmText="Sim, cancelar"
|
confirmText="Sim, cancelar"
|
||||||
cancelText="Fechar"
|
cancelText="Fechar"
|
||||||
onConfirm={handleConfirmCancel}
|
onConfirm={tServicoPedidoController.handleConfirmCancel}
|
||||||
onCancel={handleCloseCancelDialog}
|
onCancel={tServicoPedidoController.handleCloseCancelDialog}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Modal TPessoa */}
|
{/* Modal TPessoa */}
|
||||||
{isPessoaFormOpen && (
|
{tServicoPedidoController.isPessoaFormOpen && (
|
||||||
<TPessoaTableFormDialog
|
<TPessoaTableFormDialog
|
||||||
isOpen={isPessoaFormOpen}
|
isOpen={tServicoPedidoController.isPessoaFormOpen}
|
||||||
tipoPessoa={selectedPessoaTipo}
|
tipoPessoa={tServicoPedidoController.selectedPessoaTipo}
|
||||||
onClose={handleClosePessoaForm}
|
onClose={tServicoPedidoController.handleClosePessoaForm}
|
||||||
onSave={handleAddItemWithPessoa}
|
onSave={tServicoPedidoController.handleAddItemWithPessoa}
|
||||||
buttonIsLoading={isSaving}
|
buttonIsLoading={tServicoPedidoController.isSaving}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { FieldValues, Path, PathValue, UseFormSetValue } from 'react-hook-form';
|
import { FieldValues, Path, PathValue, UseFormSetValue } from 'react-hook-form';
|
||||||
|
|
||||||
import { GCalculoServicoService } from '@/packages/administrativo/services/GCalculo/GCalculoServicoService';
|
import { GCalculoServicoService } from '@/packages/administrativo/services/GCalculo/GCalculoServicoService';
|
||||||
|
import TServicoPedidoItemLocalPrepare from '@/packages/servicos/actions/TServicoPedidoItem/TServicoPedidoItemLocalPrepare';
|
||||||
import TServicoPedidoItemPreparePayload from '@/packages/servicos/actions/TServicoPedidoItem/TServicoPedidoItemPreparePayload';
|
import TServicoPedidoItemPreparePayload from '@/packages/servicos/actions/TServicoPedidoItem/TServicoPedidoItemPreparePayload';
|
||||||
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
import TServicoItemPedidoAddInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoAddInterface';
|
||||||
import TServicoItemPedidoCalculoResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
import TServicoItemPedidoCalculoResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
||||||
import { useResponse } from '@/shared/components/response/ResponseContext';
|
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||||
|
|
||||||
|
|
||||||
export function useTServicoItemPedidoCalculoHook<TFormValues extends FieldValues>(
|
export function useTServicoItemPedidoCalculoHook<TFormValues extends FieldValues>(
|
||||||
setValue?: UseFormSetValue<TFormValues>,
|
setValue?: UseFormSetValue<TFormValues>,
|
||||||
) {
|
) {
|
||||||
|
|
@ -17,8 +19,9 @@ export function useTServicoItemPedidoCalculoHook<TFormValues extends FieldValues
|
||||||
const [TServicoItemPedido, setTServicoItemPedido] = useState<
|
const [TServicoItemPedido, setTServicoItemPedido] = useState<
|
||||||
TServicoItemPedidoCalculoResponseInterface[]
|
TServicoItemPedidoCalculoResponseInterface[]
|
||||||
>([]);
|
>([]);
|
||||||
|
const [shouldSync, setShouldSync] = useState(false);
|
||||||
|
|
||||||
const addTServicoItemPedido = async (data: TServicoItemPedidoAddInterface) => {
|
const calculoTServicoItemPedido = async (data: TServicoItemPedidoAddInterface) => {
|
||||||
const payload = TServicoPedidoItemPreparePayload(data);
|
const payload = TServicoPedidoItemPreparePayload(data);
|
||||||
|
|
||||||
if (payload.status) {
|
if (payload.status) {
|
||||||
|
|
@ -26,39 +29,41 @@ export function useTServicoItemPedidoCalculoHook<TFormValues extends FieldValues
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await GCalculoServicoService(payload, data);
|
const response = await GCalculoServicoService(payload);
|
||||||
|
|
||||||
if (response.status) {
|
if (response.status != 200) {
|
||||||
setResponse(response);
|
setResponse(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTServicoItemPedido((prev) => {
|
const itemLocal = TServicoPedidoItemLocalPrepare(data, response);
|
||||||
const safePrev = Array.isArray(prev) ? prev : [];
|
|
||||||
|
|
||||||
const novoItem = response;
|
if (!itemLocal) return;
|
||||||
|
|
||||||
if (!novoItem) return safePrev;
|
// Atualiza apenas o estado local
|
||||||
|
setTServicoItemPedido((prev) => [...prev, itemLocal]);
|
||||||
|
|
||||||
const novoArray = [...safePrev, novoItem];
|
// Marca para sincronizar com o formulário
|
||||||
|
setShouldSync(true);
|
||||||
|
|
||||||
if (setValue) {
|
return itemLocal;
|
||||||
setValue(
|
|
||||||
'itens' as Path<TFormValues>,
|
|
||||||
novoArray as unknown as PathValue<TFormValues, Path<TFormValues>>,
|
|
||||||
{ shouldDirty: true },
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return novoArray;
|
|
||||||
});
|
|
||||||
|
|
||||||
return response;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Efeito seguro para sincronizar com o react-hook-form após o render
|
||||||
|
useEffect(() => {
|
||||||
|
if (setValue && shouldSync) {
|
||||||
|
setValue(
|
||||||
|
'itens' as Path<TFormValues>,
|
||||||
|
TServicoItemPedido as unknown as PathValue<TFormValues, Path<TFormValues>>,
|
||||||
|
{ shouldDirty: true },
|
||||||
|
);
|
||||||
|
setShouldSync(false);
|
||||||
|
}
|
||||||
|
}, [setValue, shouldSync, TServicoItemPedido]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
TServicoItemPedido,
|
TServicoItemPedido,
|
||||||
setTServicoItemPedido,
|
setTServicoItemPedido,
|
||||||
addTServicoItemPedido,
|
calculoTServicoItemPedido,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
'use client';
|
|
||||||
|
|
||||||
import { useState } from 'react';
|
|
||||||
import { FieldValues, Path, PathValue, UseFormSetValue } from 'react-hook-form';
|
|
||||||
|
|
||||||
import TServicoItemPedidoCalculoResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
|
||||||
|
|
||||||
export function useTServicoItemPedidoLocalAddHook<TFormValues extends FieldValues>(
|
|
||||||
setValue?: UseFormSetValue<TFormValues>,
|
|
||||||
) {
|
|
||||||
const [TServicoItemPedidoLocal, setLocalTServicoItemPedido] = useState<
|
|
||||||
TServicoItemPedidoCalculoResponseInterface[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
const localAddTServicoItemPedido = (item: TServicoItemPedidoCalculoResponseInterface) => {
|
|
||||||
setLocalTServicoItemPedido((prev) => {
|
|
||||||
const updated = [...prev, item];
|
|
||||||
|
|
||||||
if (setValue) {
|
|
||||||
setValue(
|
|
||||||
'itens' as Path<TFormValues>,
|
|
||||||
updated as unknown as PathValue<TFormValues, Path<TFormValues>>,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return updated;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const localClearTServicoItemPedido = () => {
|
|
||||||
setLocalTServicoItemPedido([]);
|
|
||||||
|
|
||||||
if (setValue) {
|
|
||||||
setValue(
|
|
||||||
'itens' as Path<TFormValues>,
|
|
||||||
[] as unknown as PathValue<TFormValues, Path<TFormValues>>,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
TServicoItemPedidoLocal,
|
|
||||||
localAddTServicoItemPedido,
|
|
||||||
setLocalTServicoItemPedido,
|
|
||||||
localClearTServicoItemPedido,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { FieldValues, Path, PathValue, UseFormSetValue } from 'react-hook-form';
|
||||||
|
|
||||||
|
import TServicoItemPedidoCalculoResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
||||||
|
|
||||||
|
export function useTServicoItemPedidoLocalHandleHook<TFormValues extends FieldValues>(
|
||||||
|
setValue?: UseFormSetValue<TFormValues>,
|
||||||
|
) {
|
||||||
|
const [TServicoItemPedidoLocal, setLocalTServicoItemPedido] = useState<
|
||||||
|
TServicoItemPedidoCalculoResponseInterface[]
|
||||||
|
>([]);
|
||||||
|
|
||||||
|
// Estado auxiliar para indicar que o form deve ser atualizado
|
||||||
|
const [shouldSync, setShouldSync] = useState(false);
|
||||||
|
|
||||||
|
// Adiciona item localmente (apenas atualiza o state)
|
||||||
|
const localAddTServicoItemPedido = (item: TServicoItemPedidoCalculoResponseInterface) => {
|
||||||
|
setLocalTServicoItemPedido((prev) => [...prev, item]);
|
||||||
|
setShouldSync(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Remove item por índice
|
||||||
|
const localRemoveTServicoItemPedido = useCallback((index: number) => {
|
||||||
|
setLocalTServicoItemPedido((prev) => prev.filter((_, i) => i !== index));
|
||||||
|
setShouldSync(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Limpa os itens
|
||||||
|
const localClearTServicoItemPedido = () => {
|
||||||
|
setLocalTServicoItemPedido([]);
|
||||||
|
setShouldSync(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Efeito responsável por sincronizar o formulário depois da atualização
|
||||||
|
useEffect(() => {
|
||||||
|
if (setValue && shouldSync) {
|
||||||
|
setValue(
|
||||||
|
'itens' as Path<TFormValues>,
|
||||||
|
TServicoItemPedidoLocal as unknown as PathValue<TFormValues, Path<TFormValues>>,
|
||||||
|
{ shouldDirty: true },
|
||||||
|
);
|
||||||
|
setShouldSync(false);
|
||||||
|
}
|
||||||
|
}, [setValue, shouldSync, TServicoItemPedidoLocal]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
TServicoItemPedidoLocal,
|
||||||
|
localAddTServicoItemPedido,
|
||||||
|
localRemoveTServicoItemPedido,
|
||||||
|
setLocalTServicoItemPedido,
|
||||||
|
localClearTServicoItemPedido,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,363 @@
|
||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useRouter } from 'next/navigation';
|
||||||
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
|
||||||
|
import TPessoaInterface from '@/packages/administrativo/interfaces/TPessoa/TPessoaInterface';
|
||||||
|
import { useTServicoItemPedidoCalculoHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoCalculoHook';
|
||||||
|
import { useTServicoItemPedidoIndexHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoIndexHook';
|
||||||
|
import { useTServicoItemPedidoLocalHandleHook } from '@/packages/servicos/hooks/TServicoItemPedido/useTServicoItemPedidoLocalHandleHook';
|
||||||
|
import { useTServicoPedidoFormHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoFormHook';
|
||||||
|
import { useTServicoPedidoLoadParamsHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoLoadParamsHook';
|
||||||
|
import { useTServicoPedidoSaveHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoSaveHook';
|
||||||
|
import { useTServicoPedidoShowHook } from '@/packages/servicos/hooks/TServicoPedido/useTServicoPedidoShowHook';
|
||||||
|
import TServicoPedidoInterface from '@/packages/servicos/interfaces/TServicoPedido/TServicoPedidoInterface';
|
||||||
|
import { TServicoPedidoFormValues } from '@/packages/servicos/schemas/TServicoPedido/TServicoPedidoFormSchema';
|
||||||
|
import { useResponse } from '@/shared/components/response/ResponseContext';
|
||||||
|
import { StepNavigatorRef } from '@/shared/components/step/stepNavigator';
|
||||||
|
import { SituacoesEnum } from '@/shared/enums/SituacoesEnum';
|
||||||
|
import { TipoPessoaEnum } from '@/shared/enums/TipoPessoaEnum';
|
||||||
|
|
||||||
|
export default function useTServicoPedidoFormControllerHook(servico_pedido_id?: number) {
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const form = useTServicoPedidoFormHook({});
|
||||||
|
const { setValue, reset, watch } = form;
|
||||||
|
|
||||||
|
const [isSaving, setIsSaving] = useState(false);
|
||||||
|
const [isAdding, setIsAdding] = useState(false);
|
||||||
|
const [isPessoaFormOpen, setIsPessoaFormOpen] = useState(false);
|
||||||
|
const [isSaveConfirmOpen, setIsSaveConfirmOpen] = useState(false);
|
||||||
|
const [isCancelDialogOpen, setIsCancelDialogOpen] = useState(false);
|
||||||
|
const [selectedPessoaTipo, setSelectedPessoaTipo] = useState('');
|
||||||
|
const [shouldKeepFormOpen, setShouldKeepFormOpen] = useState(false);
|
||||||
|
|
||||||
|
const ref = useRef<StepNavigatorRef>(null);
|
||||||
|
|
||||||
|
// Controles de formulário
|
||||||
|
const handleClosePessoaForm = useCallback(() => setIsPessoaFormOpen(false), []);
|
||||||
|
const handleOpenSaveConfirm = useCallback(() => setIsSaveConfirmOpen(true), []);
|
||||||
|
const handleCloseSaveConfirm = useCallback(() => setIsSaveConfirmOpen(false), []);
|
||||||
|
|
||||||
|
// Hooks
|
||||||
|
// const playSuccess = useSoundHook("/sounds/success.mp3");
|
||||||
|
const { setResponse } = useResponse();
|
||||||
|
const { saveTServicoPedido } = useTServicoPedidoSaveHook();
|
||||||
|
const { showTServicoPedido } = useTServicoPedidoShowHook();
|
||||||
|
const { TServicoItemPedidoLocal, localAddTServicoItemPedido, localRemoveTServicoItemPedido, setLocalTServicoItemPedido } = useTServicoItemPedidoLocalHandleHook(setValue);
|
||||||
|
const { calculoTServicoItemPedido } = useTServicoItemPedidoCalculoHook(setValue);
|
||||||
|
const { indexTServicoItemPedido } = useTServicoItemPedidoIndexHook();
|
||||||
|
const { TServicoPedidoParams, loadParamsTServicoPedido } = useTServicoPedidoLoadParamsHook();
|
||||||
|
|
||||||
|
// Acompanha as alterações, nos campos definidos
|
||||||
|
const selectedServicoTipo = watch('servico_tipo');
|
||||||
|
const selectedEmolumento = watch('emolumento');
|
||||||
|
|
||||||
|
const handleFormError = useCallback((errors: any) => {
|
||||||
|
console.group('Erros de validação do formulário');
|
||||||
|
console.log('Campos com erro:', errors);
|
||||||
|
console.groupEnd();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Envia a requisição para a API
|
||||||
|
const handleSavePedido = useCallback(
|
||||||
|
async (data: TServicoPedidoFormValues) => {
|
||||||
|
// Ativa o botão de loading
|
||||||
|
setIsSaving(true);
|
||||||
|
|
||||||
|
// Converte o tipo do formulário (Zod) para o tipo da API (Interface)
|
||||||
|
const payload: TServicoPedidoInterface = {
|
||||||
|
...data,
|
||||||
|
situacao: data.situacao as unknown as SituacoesEnum,
|
||||||
|
};
|
||||||
|
|
||||||
|
const response = await saveTServicoPedido(payload);
|
||||||
|
|
||||||
|
// Desativa o botão de loading
|
||||||
|
setIsSaving(false);
|
||||||
|
|
||||||
|
// Verifica se devo redirecionar a pagina
|
||||||
|
if (response?.servico_pedido_id > 0) {
|
||||||
|
// Toca o som do sistema
|
||||||
|
// playSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica se devo redirecionar a pagina
|
||||||
|
if (response?.servico_pedido_id > 0 && !shouldKeepFormOpen) {
|
||||||
|
router.replace(`/servicos/balcao/detalhes/${response.servico_pedido_id}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[saveTServicoPedido, shouldKeepFormOpen],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Modal de confirmação de serviço
|
||||||
|
const handleSubmitWithConfirmation = useCallback(() => {
|
||||||
|
// Envia o formulário
|
||||||
|
form.handleSubmit(handleSavePedido, handleFormError)();
|
||||||
|
}, [form, handleSavePedido, handleFormError]);
|
||||||
|
|
||||||
|
// Busca os itens do Pedido
|
||||||
|
const fetchPedidoItens = useCallback(
|
||||||
|
async (id: number) => {
|
||||||
|
const pedidoItens = {
|
||||||
|
servico_pedido_id: id,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Busca os itens do pedido
|
||||||
|
const response = await indexTServicoItemPedido(pedidoItens);
|
||||||
|
|
||||||
|
// Verifica se os dados foram localizados
|
||||||
|
if (response?.data?.length) {
|
||||||
|
// Atualiza os dados dos itens locais
|
||||||
|
setLocalTServicoItemPedido(response.data);
|
||||||
|
|
||||||
|
// Atualiza os itens do formulário
|
||||||
|
setValue('itens', response.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[indexTServicoItemPedido, setValue, setLocalTServicoItemPedido],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Busca o pedido Principal
|
||||||
|
const fetchPedido = useCallback(async () => {
|
||||||
|
// Busca o pedido principal
|
||||||
|
const response = await showTServicoPedido({ servico_pedido_id });
|
||||||
|
|
||||||
|
// Verifica se o pedido foi localizado
|
||||||
|
if (response?.servico_pedido_id) {
|
||||||
|
// Atualiza os dados do formulário
|
||||||
|
reset(response);
|
||||||
|
|
||||||
|
// Carrega os itens do pedido
|
||||||
|
fetchPedidoItens(response.servico_pedido_id);
|
||||||
|
}
|
||||||
|
}, [servico_pedido_id, showTServicoPedido, reset, fetchPedidoItens]);
|
||||||
|
|
||||||
|
const handleAddItemWithPessoa = useCallback(
|
||||||
|
async (selectedTPessoa: TPessoaInterface) => {
|
||||||
|
handleAddItem(selectedTPessoa)
|
||||||
|
}, [selectedEmolumento, selectedServicoTipo]);
|
||||||
|
|
||||||
|
// Controla o formulário de cancelamento de pedido
|
||||||
|
const handleOpenCancelDialog = useCallback(async () => {
|
||||||
|
// Fecha a confirmação
|
||||||
|
setIsCancelDialogOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Controle de redirecionamento
|
||||||
|
const handleConfirmCancel = useCallback(async () => {
|
||||||
|
// Redireciona o usuário
|
||||||
|
router.replace(`/servicos/balcao/`);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Controle do formulário de cancelamento do Pedido
|
||||||
|
const handleCloseCancelDialog = useCallback(async () => {
|
||||||
|
// Fecha o formulário
|
||||||
|
setIsCancelDialogOpen(false);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleRemoveLocalItem = useCallback(async (index: number) => {
|
||||||
|
|
||||||
|
localRemoveTServicoItemPedido(index)
|
||||||
|
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Controle de itens
|
||||||
|
const handleAddItem = useCallback(async (selectedTPessoa?: TPessoaInterface) => {
|
||||||
|
|
||||||
|
setIsAdding(true);
|
||||||
|
|
||||||
|
// Prepara e valida os dados de item do pedido
|
||||||
|
const payload = {
|
||||||
|
servico_tipo: selectedServicoTipo,
|
||||||
|
emolumento: selectedEmolumento,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Se existir pessoa, adiciona ao payload
|
||||||
|
if (selectedTPessoa) {
|
||||||
|
payload.pessoa = selectedTPessoa;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtem o resultado da adição do item
|
||||||
|
const item = await calculoTServicoItemPedido(payload);
|
||||||
|
|
||||||
|
// Verifica se foi realizado o calculo
|
||||||
|
if (!item) {
|
||||||
|
setResponse({
|
||||||
|
status: 422,
|
||||||
|
detail: 'Não foi localizado item para o serviço',
|
||||||
|
})
|
||||||
|
setIsAdding(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define índice e adiciona localmente
|
||||||
|
const index = TServicoItemPedidoLocal.length;
|
||||||
|
|
||||||
|
// Guarda o indice
|
||||||
|
item.index = index
|
||||||
|
|
||||||
|
// Adiciona o item calculo localmente
|
||||||
|
localAddTServicoItemPedido(item)
|
||||||
|
|
||||||
|
// Define os itens
|
||||||
|
form.setValue(`itens.${index}`, item);
|
||||||
|
|
||||||
|
setIsAdding(false);
|
||||||
|
|
||||||
|
}, [calculoTServicoItemPedido, selectedServicoTipo, selectedEmolumento, localAddTServicoItemPedido]);
|
||||||
|
|
||||||
|
// Habilita o formulário de pessoas
|
||||||
|
const handleOpenPessoaForm = useCallback((tipoPessoa: string) => {
|
||||||
|
setSelectedPessoaTipo(tipoPessoa);
|
||||||
|
setIsPessoaFormOpen(true);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Adiciona o item a tabela e verifica se deve ou não montar a subview da linha da tabela
|
||||||
|
const handleSelectServicoTipo = useCallback(() => {
|
||||||
|
|
||||||
|
const tipoPessoa = [TipoPessoaEnum.FISICA, TipoPessoaEnum.JURIDICA]
|
||||||
|
|
||||||
|
// Verifica se o emolumento e o tipo de serviço foram selecionados
|
||||||
|
if (!selectedServicoTipo || !selectedEmolumento) {
|
||||||
|
setResponse({
|
||||||
|
status: 422,
|
||||||
|
detail: 'Serviço e emolumento devem ser selecionados',
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verifica se deve selecionar pessoas
|
||||||
|
switch (tipoPessoa.includes(selectedServicoTipo.tipo_pessoa)) {
|
||||||
|
|
||||||
|
// Habilita o formulário
|
||||||
|
case true:
|
||||||
|
|
||||||
|
handleOpenPessoaForm(selectedServicoTipo.tipo_pessoa);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Adiciona direto
|
||||||
|
default:
|
||||||
|
|
||||||
|
handleAddItem();
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [selectedServicoTipo, selectedEmolumento, handleOpenPessoaForm, handleAddItem]);
|
||||||
|
|
||||||
|
const calcularTotais = useCallback(() => {
|
||||||
|
const itens = form.getValues('itens') || [];
|
||||||
|
|
||||||
|
if (!itens.length) {
|
||||||
|
setValue('valor_pedido', 0, { shouldDirty: true });
|
||||||
|
setValue('valor_pago', 0, { shouldDirty: true });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const total = itens.reduce((acc, item) => acc + Number(item.valor ?? 0), 0);
|
||||||
|
|
||||||
|
// Atualiza sempre o valor do pedido
|
||||||
|
setValue('valor_pedido', total, { shouldDirty: true });
|
||||||
|
|
||||||
|
// Atualiza o valor pago apenas se estiver vazio, null, undefined ou 0
|
||||||
|
const valorPagoAtual = Number(form.getValues('valor_pago')) || 0;
|
||||||
|
if (!valorPagoAtual) {
|
||||||
|
setValue('valor_pago', total, { shouldDirty: true });
|
||||||
|
}
|
||||||
|
}, [form, setValue]);
|
||||||
|
|
||||||
|
// Incremente ou decrementa a quantidade
|
||||||
|
const handleChangeQtd = useCallback(
|
||||||
|
(index: number, delta: number) => {
|
||||||
|
const currentItens = form.getValues('itens') || [];
|
||||||
|
const currentItem = currentItens[index];
|
||||||
|
if (!currentItem) return;
|
||||||
|
|
||||||
|
const currentQtd = Number(currentItem.qtd ?? 1);
|
||||||
|
const newQtd = currentQtd + delta;
|
||||||
|
|
||||||
|
// Se quantidade for 0 ou menor, remove o item
|
||||||
|
if (newQtd <= 0) {
|
||||||
|
const filteredItens = currentItens.filter((_, i) => i !== index);
|
||||||
|
form.setValue('itens', filteredItens, { shouldDirty: true });
|
||||||
|
localRemoveTServicoItemPedido(index);
|
||||||
|
calcularTotais();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const multiplier = newQtd / currentQtd;
|
||||||
|
|
||||||
|
const updatedItem = {
|
||||||
|
...currentItem,
|
||||||
|
qtd: newQtd,
|
||||||
|
emolumento: (Number(currentItem.emolumento) * multiplier).toFixed(2),
|
||||||
|
taxa_judiciaria: (Number(currentItem.taxa_judiciaria) * multiplier).toFixed(2),
|
||||||
|
fundesp: (Number(currentItem.fundesp) * multiplier).toFixed(2),
|
||||||
|
valor_iss: (Number(currentItem.valor_iss) * multiplier).toFixed(2),
|
||||||
|
valor: (Number(currentItem.valor) * multiplier).toFixed(2),
|
||||||
|
};
|
||||||
|
|
||||||
|
const updatedItens = [...currentItens];
|
||||||
|
updatedItens[index] = updatedItem;
|
||||||
|
|
||||||
|
form.setValue('itens', updatedItens, { shouldDirty: true });
|
||||||
|
calcularTotais();
|
||||||
|
},
|
||||||
|
[form, localRemoveTServicoItemPedido, calcularTotais],
|
||||||
|
);
|
||||||
|
|
||||||
|
// Dispara a busca do pedido
|
||||||
|
useEffect(() => {
|
||||||
|
// Se existir pedido_id, busca o pedido
|
||||||
|
if (servico_pedido_id) fetchPedido();
|
||||||
|
}, [servico_pedido_id, fetchPedido]);
|
||||||
|
|
||||||
|
// Dispara a busca de itens
|
||||||
|
useEffect(() => {
|
||||||
|
// Dispara a busca dos itens
|
||||||
|
setValue('itens', TServicoItemPedidoLocal, { shouldDirty: true });
|
||||||
|
}, [TServicoItemPedidoLocal, setValue]);
|
||||||
|
|
||||||
|
// Dispara a busca de parâmetros
|
||||||
|
useEffect(() => {
|
||||||
|
loadParamsTServicoPedido();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// Monitora mudanças na lista de itens
|
||||||
|
useEffect(() => {
|
||||||
|
calcularTotais();
|
||||||
|
}, [TServicoItemPedidoLocal, calcularTotais]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
form,
|
||||||
|
ref,
|
||||||
|
isSaving,
|
||||||
|
isAdding,
|
||||||
|
isPessoaFormOpen,
|
||||||
|
isSaveConfirmOpen,
|
||||||
|
isCancelDialogOpen,
|
||||||
|
shouldKeepFormOpen,
|
||||||
|
selectedPessoaTipo,
|
||||||
|
TServicoItemPedidoLocal,
|
||||||
|
TServicoPedidoParams,
|
||||||
|
|
||||||
|
// setters diretos
|
||||||
|
setIsSaveConfirmOpen,
|
||||||
|
setIsCancelDialogOpen,
|
||||||
|
setShouldKeepFormOpen,
|
||||||
|
|
||||||
|
// handlers principais
|
||||||
|
handleSavePedido,
|
||||||
|
handleSelectServicoTipo,
|
||||||
|
handleSubmitWithConfirmation,
|
||||||
|
handleCloseSaveConfirm,
|
||||||
|
handleOpenCancelDialog,
|
||||||
|
handleConfirmCancel,
|
||||||
|
handleCloseCancelDialog,
|
||||||
|
handleClosePessoaForm,
|
||||||
|
handleAddItemWithPessoa,
|
||||||
|
handleOpenSaveConfirm,
|
||||||
|
handleChangeQtd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
import { UseFormReturn } from 'react-hook-form';
|
import { UseFormReturn } from 'react-hook-form';
|
||||||
|
|
||||||
import TServicoItemPedidoAddResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
import TServicoItemPedidoAddResponseInterface from '@/packages/servicos/interfaces/TServicoItemPedido/TServicoItemPedidoCalculoResponseInterface';
|
||||||
|
import { TServicoPedidoFormValues } from '@/packages/servicos/schemas/TServicoPedido/TServicoPedidoFormSchema';
|
||||||
import GConfigInterface from '@/shared/interfaces/GConfigInterface';
|
import GConfigInterface from '@/shared/interfaces/GConfigInterface';
|
||||||
|
|
||||||
import { TServicoPedidoFormValues } from '../../schemas/TServicoPedido/TServicoPedidoFormSchema';
|
|
||||||
|
|
||||||
export default interface TServicoItemPedidoFormTableInterface {
|
export default interface TServicoItemPedidoFormTableInterface {
|
||||||
data: TServicoItemPedidoAddResponseInterface[];
|
data: TServicoItemPedidoAddResponseInterface[];
|
||||||
form: UseFormReturn<TServicoPedidoFormValues>;
|
form: UseFormReturn<TServicoPedidoFormValues>;
|
||||||
params: GConfigInterface[];
|
params: GConfigInterface[];
|
||||||
|
handleChangeQtd: any;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
4
src/shared/enums/TipoPessoaEnum.ts
Normal file
4
src/shared/enums/TipoPessoaEnum.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
export const TipoPessoaEnum = {
|
||||||
|
FISICA: "F",
|
||||||
|
JURIDICA: "J"
|
||||||
|
} as const
|
||||||
Loading…
Add table
Reference in a new issue